Having three classes. Class Table QTableWidget and a signal and a function to get row numbers with click event. which transmit and send to two other classes. This part of script works as promising.
class Table(QtWidgets.QWidget):
rownumber = QtCore.pyqtSignal(int)
def __init__(self, parent=None):
super(Table, self).__init__(parent)
self.tableWidget = QtWidgets.QTableWidget(0, 3)
self.tableWidget.cellClicked.connect(self.cellClick)
def cellClick(self, row, column):
self.rownumber.emit(row)
def currentrow(self):
return self.tableWidget.currentRow()
Second Combo class with QComboBox and a signal and two functions to send and transfer information to third class, that value in QComboBox is changed. To check if the signal is emitting, printing Signal emitted . This part of script seems also working fine, since print code is executed.
class Combo(QtWidgets.QWidget):
Toupdatedata = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(Combo, self).__init__(parent)
self.combo = QtWidgets.QComboBox()
self.combo.addItems(["1","2","3","4"])
self.combo.activated.connect(self.setdatastrength)
#QtCore.pyqtSlot(int)
def setdatastrength(self, index):
value = self.combo[index]
self.dataupdate()
def dataupdate(self):
self.Toupdatedata.emit()
print('Signal emitted')
def get_data(self):
return tuple([self.combo.currentText()])
Third class Tab with QTabWidget and two functions and a connection, first function recieves numbers of row from first class Table, second function should and supposed to run and execute, when index of combobox from second class Combo changes. Checking to see if it works printing a string text I am executing. But it does not work as expected?! When values of QComboBox changes, function updatedata() never runs!
class Tab(QtWidgets.QWidget):
def __init__(self, parent=None):
super( Tab, self).__init__()
self.tab = QtWidgets.QTabWidget()
self.Table = Table()
self.combo = [Combo(), Combo()]
self.datacombo = []
self.Row = 0
self.tab.addTab( self.Table, 'Tables')
self.Table.rownumber.connect(self.rowselected_tables)
self.combo[self.Row].Toupdatedata.connect(self.updatedata)
# Alternative calling function currentrow.
# self.combo[self.Table.currentrow()].Toupdatedata.connect(self.updatedata)
#QtCore.pyqtSlot(int)
def rowselected_tables(self, row):
self.Row = row
if row > 0:
self.Tab.addTab(self.combo[row], 'Combo')
a1 = self.combo[row].get_data()
self.datacombo[row] = a1
#QtCore.pyqtSlot()
def updatedata(self):
self.datacombo[self.Table.currentrow()] = self.combo[self.Table.currentrow()].get_data()
print('I am executing', self.datagroup)
I wonder, what's it I'm doing wrong?
UPDATE:
import sys
from PyQt5 import QtCore, QtWidgets, QtGui
class Table(QtWidgets.QWidget):
rownumber = QtCore.pyqtSignal(int)
rowCount = QtCore.pyqtSignal(int)
def __init__(self, parent=None):
super(Table, self).__init__(parent)
self.tableWidget = QtWidgets.QTableWidget(3, 3)
self.lay = QtWidgets.QHBoxLayout(self)
self.lay.addWidget(self.tableWidget)
self.tableWidget.cellClicked.connect(self.cellClick)
def cellClick(self, row, column):
self.rownumber.emit(row)
def currentrow(self):
return self.tableWidget.currentRow()
def getrow(self):
count = self.tableWidget.rowCount()
self.rowCount.emit(count)
class Combo(QtWidgets.QWidget):
Toupdatedata = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(Combo, self).__init__(parent)
self.combo = QtWidgets.QComboBox()
self.combo.addItems(["1","2","3","4"])
self.hbox = QtWidgets.QHBoxLayout()
self.con = QtWidgets.QLabel("Number: ")
self.hbox.addWidget(self.con)
self.hbox.addWidget(self.combo)
self.setLayout(self.hbox)
self.combo.activated.connect(self.setdatastrength)
#QtCore.pyqtSlot(int)
def setdatastrength(self, index):
self.dataupdate()
def dataupdate(self):
self.Toupdatedata.emit()
print('Signal emitted')
def get_data(self):
return tuple([self.combo.currentText()])
class Tab(QtWidgets.QWidget):
def __init__(self, parent=None):
super( Tab, self).__init__()
self.tab = QtWidgets.QTabWidget()
self.Table = Table()
self.combo = []
self.datacombo = []
self.Row = 0
self.tab.addTab( self.Table, 'Tables')
self.Table.rowCount.connect(self.addrow)
self.Table.getrow()
self.Table.rownumber.connect(self.rowselected_tables)
self.combo[self.Row].Toupdatedata.connect(self.updatedata)
self.lay = QtWidgets.QHBoxLayout(self)
self.lay.addWidget(self.tab)
# Alternative calling function currentrow.
# self.combo[self.Table.currentrow()].Toupdatedata.connect(self.updatedata)
#QtCore.pyqtSlot(int)
def addrow(self, count):
for row in range(count):
self.combo.append(Combo())
self.datacombo.append(Combo().get_data())
#QtCore.pyqtSlot(int)
def rowselected_tables(self, row):
self.Row = row
if row > 0:
while self.tab.count() > 1:
self.tab.removeTab( self.tab.count()-1 )
self.tab.addTab(self.combo[row], 'Combo')
a1 = self.combo[row].get_data()
self.datacombo[row] = a1
else:
for n in [1]:
self.tab.removeTab( n )
#QtCore.pyqtSlot()
def updatedata(self):
self.datacombo[self.Table.currentrow()] = self.combo[self.Table.currentrow()].get_data()
print('I am executing', self.datagroup)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Tab()
w.show()
sys.exit(app.exec_())
In my opinion, you are connecting the signal self.combo[self.Row].Toupdatedata.connect (self.updatedata) in the wrong place.
I noted the text where the changes were made. Try it:
import sys
from PyQt5 import QtCore, QtWidgets, QtGui
class Table(QtWidgets.QWidget):
rownumber = QtCore.pyqtSignal(int)
rowCount = QtCore.pyqtSignal(int)
def __init__(self, parent=None):
super(Table, self).__init__(parent)
self.tableWidget = QtWidgets.QTableWidget(3, 3)
self.lay = QtWidgets.QHBoxLayout(self)
self.lay.addWidget(self.tableWidget)
self.tableWidget.cellClicked.connect(self.cellClick)
def cellClick(self, row, column):
self.rownumber.emit(row)
def currentrow(self):
return self.tableWidget.currentRow()
def getrow(self):
count = self.tableWidget.rowCount()
self.rowCount.emit(count)
class Combo(QtWidgets.QWidget):
Toupdatedata = QtCore.pyqtSignal(int) # + int
def __init__(self, rowTable, parent=None): # + rowTable
super(Combo, self).__init__(parent)
self.rowTable = rowTable # +
## print(rowTable, '------')
self.combo = QtWidgets.QComboBox()
self.combo.addItems(["item1", "item2", "item3", "item4"])
self.hbox = QtWidgets.QHBoxLayout()
self.con = QtWidgets.QLabel("Number: ")
self.hbox.addWidget(self.con)
self.hbox.addWidget(self.combo)
self.setLayout(self.hbox)
self.combo.activated.connect(self.setdatastrength)
#QtCore.pyqtSlot(int)
def setdatastrength(self, index):
self.dataupdate()
def dataupdate(self):
print('+ Signal emitted ->', self.rowTable)
self.Toupdatedata.emit(self.rowTable) # + self.rowTable
def get_data(self):
return tuple([self.combo.currentText()])
class Tab(QtWidgets.QWidget):
def __init__(self, parent=None):
super( Tab, self).__init__()
self.tab = QtWidgets.QTabWidget()
self.Table = Table()
self.combo = []
self.datacombo = []
self.Row = 0
self.tab.addTab( self.Table, 'Tables')
self.Table.rowCount.connect(self.addrow)
self.Table.getrow()
self.Table.rownumber.connect(self.rowselected_tables)
#- self.combo[self.Row].Toupdatedata.connect(self.updatedata)
self.lay = QtWidgets.QHBoxLayout(self)
self.lay.addWidget(self.tab)
# Alternative calling function currentrow.
# ? self.combo[self.Table.currentrow()].Toupdatedata.connect(self.updatedata)
#QtCore.pyqtSlot(int)
def addrow(self, count):
for row in range(count):
cb = Combo(row) # + row
self.combo.append(cb)
self.datacombo.append(cb.get_data()[0]) # get_data()[0]
self.combo[row].Toupdatedata.connect(lambda rowTable=row: self.updatedata(rowTable)) # <===== !!!
#QtCore.pyqtSlot(int)
def rowselected_tables(self, row):
self.Row = row
if row > 0:
while self.tab.count() > 1:
self.tab.removeTab( self.tab.count()-1 )
self.tab.addTab(self.combo[row], 'Combo')
a1 = self.combo[row].get_data()[0] # + [0]
self.datacombo[row] = a1
else:
for n in [1]:
self.tab.removeTab( n )
#QtCore.pyqtSlot()
def updatedata(self, rowTable): # + rowTable
# self.datacombo[self.Table.currentrow()] = self.combo[self.Table.currentrow()].get_data()
self.datacombo[rowTable] = self.combo[rowTable].get_data()[0] # [0]
print('I am executing', self.datacombo ) # ? self.datagroup
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Tab()
w.show()
sys.exit(app.exec_())
I need to add pixmap to my rectangles. When I press the click button then my pixmap will be added to one by one in my rectangles but I got this attribute error. Can any one please guide me how to solve this error? I tried so many ways but I didn't get the proper output.
Thank you in advance.
Given below is my code:
from pyface.qt import QtGui, QtCore
import sys
global X,Y
class ScanView(QtGui.QGraphicsView):
def __init__(self,X=5, Y=5, parent=None):
super(ScanView, self).__init__(parent)
self.row = X
self.cols = Y
self.squareLB = 50
self.width = Y*self.squareLB+2*self.squareLB
self.height = X*self.squareLB+2*self.squareLB
self.List = []
if self.width>708:
self.scene = QtGui.QGraphicsScene(0,0,self.width,self.height)
for i in range(self.row):
for j in range(self.cols):
item = self.scene.addRect(QtCore.QRectF(0,0,self.squareLB,self.squareLB))
item.setPos(self.squareLB+j*self.squareLB, X*self.squareLB-(i*self.squareLB))
self.List.append(item)
else:
self.scene = QtGui.QGraphicsScene(0,0,708,self.height)
self.marginLR = (708.0-Y*self.squareLB)/2.0
for i in range(self.row):
for j in range(self.cols):
item = self.scene.addRect(QtCore.QRectF(0,0,self.squareLB,self.squareLB))
item.setPos(self.marginLR+j*self.squareLB, X*self.squareLB-(i*self.squareLB))
self.List.append(item)
self.setScene(self.scene)
class Settings(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Settings, self).__init__(parent)
spacer = QtGui.QWidget(self)
spacer.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
self.vbox = QtGui.QVBoxLayout()
self.save = QtGui.QPushButton("save")
self.open= QtGui.QPushButton("open")
self.folder= QtGui.QPushButton("Folder")
self.folder.clicked.connect(self.showSettings)
self.vbox.addWidget(self.save)
self.vbox.addWidget(self.open)
self.vbox.addWidget(self.folder)
self.grid = QtGui.QGridLayout()
self.grid.addLayout(self.vbox,0,0)
self.scrollArea = QtGui.QScrollArea()
self.scrollArea.setBackgroundRole(QtGui.QPalette.Light)
self.scrollArea.setWidgetResizable(True)
self.grid.addWidget(self.scrollArea,0,1)
self.setCentralWidget(QtGui.QWidget(self))
self.centralWidget().setLayout(self.grid)
self.setGeometry(200,100,300,300)
self.show()
def showSettings(self):
self.MyView = ScanView(5,5)
self.vbox2 = QtGui.QVBoxLayout()
self.Scanbtn1 = QtGui.QPushButton(("click"))
self.Scanbtn1.clicked.connect(self.on_clicked)
self.vbox2.addWidget(self.Scanbtn1)
self.newwidget = QtGui.QWidget()
self.glayout = QtGui.QGridLayout(self.newwidget)
self.glayout.addWidget(self.MyView,0,0)
self.Sw = QtGui.QWidget()
self.Sw.setLayout(self.vbox2)
# self.Sw.setFixedWidth(width - self.scrollArea.viewport().width())
self.glayout.addWidget(self.Sw,0,1)
self.scrollArea.setWidget(self.newwidget)
def on_clicked(self):
print "hellloooooo"
filename1 = "./img/tick.png"
pixmap = QtGui.QPixmap(filename1)
if not pixmap.isNull():
self.MyView.add_pixmap(pixmap)
# pic = QtGui.QPixmap("./img/tick.png")
# scene.addItem(QtGui.QGraphicsPixmapItem(pic))
# # view = self.gv
# self.MyView.setScene(scene)
# self.MyView.setRenderHint(QtGui.QPainter.Antialiasing)
# self.MyView.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Settings()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
You have that error because scene does not exist in the Settings class, self.scene is a member of the ScanView class plus self.scene is different from scene.
Going to the problem, you must add as a child of the rectangles and you must also change the size of the pixmap is necessary. To obtain the first rectangle you must store it in a list and then create an iterator.
import sys
from pyface.qt import QtGui, QtCore
class ScanView(QtGui.QGraphicsView):
def __init__(self,X=5, Y=5, parent=None):
super(ScanView, self).__init__(parent)
self._squares = []
n_rows, n_cols = X, Y
squareLB = 50
width, height = (Y + 2)*squareLB, (X + 2)*squareLB
self._scene = QtGui.QGraphicsScene(0, 0, max(708, width), height)
p = squareLB if width > 708 else (708.0-Y*squareLB)/2.0
for i in range(n_rows):
for j in range(n_cols):
it = self._scene.addRect(0, 0, squareLB, squareLB)
it.setPos(p + j*squareLB, i*squareLB)
self._squares.append(it)
self.setScene(self._scene)
class Settings(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Settings, self).__init__(parent)
self.save = QtGui.QPushButton("save")
self.open = QtGui.QPushButton("open")
self.folder = QtGui.QPushButton("Folder", clicked=self.showSettings)
central_widget = QtGui.QWidget()
self.setCentralWidget(central_widget)
vbox = QtGui.QVBoxLayout()
vbox.addWidget(self.save)
vbox.addWidget(self.open)
vbox.addWidget(self.folder)
self.scrollArea = QtGui.QScrollArea(widgetResizable=True)
self.scrollArea.setBackgroundRole(QtGui.QPalette.Light)
hlay = QtGui.QHBoxLayout(central_widget)
hlay.addLayout(vbox)
hlay.addWidget(self.scrollArea)
self.setGeometry(200, 100, 300, 300)
def showSettings(self):
self.view = ScanView(5, 5)
self.scanbtn = QtGui.QPushButton("click", clicked=self.on_clicked)
self.newwidget = QtGui.QWidget()
hlay = QtGui.QHBoxLayout(self.newwidget)
hlay.addWidget(self.view)
hlay.addWidget(self.scanbtn)
self.scrollArea.setWidget(self.newwidget)
self._iter_squares = iter(self.view._squares)
def on_clicked(self):
filename = "./img/tick.png"
pixmap = QtGui.QPixmap(filename)
if pixmap.isNull():
return
try:
it = next(self._iter_squares)
except StopIteration:
pass
else:
pixmap = pixmap.scaled(it.rect().size().toSize())
pixmap_it = QtGui.QGraphicsPixmapItem(pixmap, it)
def main():
app = QtGui.QApplication(sys.argv)
ex = Settings()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I've created a widget with contents of 3 QGroupbox, I am trying to place and align them respectively with QGridLayout. Strange behaviour of QGroupboxsmakes this question.
What looks like currently.
As shown above figure when Qwidget screen stretchs in and out, Every group overlap each other and by outstretching replaces strangely and unwanted.
What I want to be....
By stretching in want all groups keeping its own position Fixed and scrollbar would appear instead.
The code is:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class ClassWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ClassWidget, self).__init__(parent)
self.setGeometry(QtCore.QRect(200, 100, 670, 360))
self.A = ClassA()
self.B = ClassB()
self.C = ClassC()
grid = QtWidgets.QGridLayout(self)
grid.addWidget(self.A, 0, 0)
grid.addWidget(self.B, 0, 1, 1, 2)
grid.addWidget(self.C, 1, 0, 1, 2)
class ClassA(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ClassA, self).__init__(parent)
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
self.c_lay = QtWidgets.QHBoxLayout()
fctd = "One\n\nTwo\n\nThree"
con_strength = QtWidgets.QLabel(fctd)
self.value = QtWidgets.QLineEdit('Test')
self.c_lay.addWidget(con_strength)
self.c_lay.addWidget(self.value, alignment=QtCore.Qt.AlignRight)
self.combo = QtWidgets.QComboBox()
self.combo.addItems(["10","12","14","16"])
self.hbox = QtWidgets.QHBoxLayout()
self.con = QtWidgets.QLabel("Number: ")
self.hbox.addWidget(self.con)
self.hbox.addWidget(self.combo)
self.vlay = QtWidgets.QVBoxLayout()
self.vlay.addLayout(self.hbox)
self.vlay.addLayout(self.c_lay)
self.vlay.addStretch()
Concrete_Group = QtWidgets.QGroupBox(self)
Concrete_Group.setTitle("&GroupA")
Concrete_Group.setLayout(self.vlay)
self.comth = ["10","12","14","16"]
self.combo.activated.connect(self.setdatastrength)
#QtCore.pyqtSlot(int)
def setdatastrength(self, index):
value = self.comth[index]
self.display_data(value)
def display_data(self, value):
try:
f = value
f_value = "{}"
self.value.setText(f_value.format(f))
except ValueError:
print("Error")
class ClassB(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ClassB, self).__init__(parent)
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
self.combo_exclass = QtWidgets.QComboBox()
self.combo_exclass.addItems([" Very dry area"," Dry or permanently
wet"," Wet, rarely dry"," Moderate humidity"," Tidal splash & spray
zones"])
self.combo_lclass = QtWidgets.QComboBox()
self.combo_lclass.addItems(["L2","L4","L6","L8"])
self.combo_vct = QtWidgets.QComboBox()
self.combo_vct.addItems(["0.10","0.20","0.30","0.40",
"0.50","0.60","0.70"])
self.combo_in = QtWidgets.QComboBox()
self.combo_in.addItems(["Class1","Class2","Class3"])
self.tbox = QtWidgets.QHBoxLayout()
self.exclass = QtWidgets.QLabel("Class1: ")
self.tbox.addWidget(self.exclass)
self.tbox.addWidget(self.combo_exclass)
self.mtbox = QtWidgets.QHBoxLayout()
self.lclass = QtWidgets.QLabel("Class2: ")
self.mtbox.addWidget(self.lclass)
self.mtbox.addWidget(self.combo_lclass)
self.mbbox = QtWidgets.QHBoxLayout()
self.vct = QtWidgets.QLabel("Class3: ")
self.mbbox.addWidget(self.vct)
self.mbbox.addWidget(self.combo_vct)
self.bbox = QtWidgets.QHBoxLayout()
self.inl = QtWidgets.QLabel("Class4: ")
self.bbox.addWidget(self.inl)
self.bbox.addWidget(self.combo_in)
self.grid = QtWidgets.QGridLayout()
self.grid.addLayout(self.tbox, 0, 0, 1, 2)
self.grid.addLayout(self.mtbox, 1, 0)
self.grid.addLayout(self.mbbox, 2, 0)
self.grid.addLayout(self.bbox, 3, 0)
Environment_Group = QtWidgets.QGroupBox(self)
Environment_Group.setTitle("&Group2")
Environment_Group.setLayout(self.grid)
class ClassC(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ClassC, self).__init__(parent)
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
self.topone = QtWidgets.QComboBox()
self.topone.addItems(["One","Two","Three","four"])
self.longitudinalone = QtWidgets.QComboBox()
self.longitudinalone.addItems(["One","Two","Three","four"])
self.bottomone = QtWidgets.QComboBox()
self.bottomone.addItems(["One","Two","Three","four"])
self.stirrupone = QtWidgets.QComboBox()
self.stirrupone.addItems(["One","Two","Three","four"])
self.toprebar = QtWidgets.QComboBox()
self.toprebar.addItems(["1","2","3","4","5","6","7","8","9"])
self.longitudinalrebar = QtWidgets.QComboBox()
self.longitudinalrebar.addItems(["1","2","3","4","5","6",
"7","8","9"])
self.bottomrebar = QtWidgets.QComboBox()
self.bottomrebar.addItems(["1","2","3","4","5","6","7","8","9"])
self.stirruprebar = QtWidgets.QComboBox()
self.stirruprebar.addItems(["1","2","3","4","5","6","7","8","9"])
self.rebarbox = QtWidgets.QVBoxLayout()
self.topvoid = QtWidgets.QLabel(" ")
self.top = QtWidgets.QLabel("One: ")
self.longitudinal = QtWidgets.QLabel("Two: ")
self.bottom = QtWidgets.QLabel("Three: ")
self.stirrup = QtWidgets.QLabel("Four: ")
self.rebarbox.addWidget(self.topvoid)
self.rebarbox.addWidget(self.top)
self.rebarbox.addWidget(self.longitudinal)
self.rebarbox.addWidget(self.bottom)
self.rebarbox.addWidget(self.stirrup)
self.typebox = QtWidgets.QVBoxLayout()
self.type = QtWidgets.QLabel("Type ")
self.typebox.addWidget(self.type, alignment=QtCore.Qt.AlignCenter)
self.typebox.addWidget(self.topone)
self.typebox.addWidget(self.longitudinalone)
self.typebox.addWidget(self.bottomone)
self.typebox.addWidget(self.stirrupone)
self.Reinforcebox = QtWidgets.QVBoxLayout()
self.Reinforcement = QtWidgets.QLabel("One, One")
self.Reinforcebox.addWidget(self.Reinforcement)
self.Reinforcebox.addWidget(self.toprebar)
self.Reinforcebox.addWidget(self.longitudinalrebar)
self.Reinforcebox.addWidget(self.bottomrebar)
self.Reinforcebox.addWidget(self.stirruprebar)
self.designstrengthbox = QtWidgets.QVBoxLayout()
self.designsteelstrength = QtWidgets.QLabel("Four")
self.topsteelstrength = QtWidgets.QLabel("")
self.longsteelstrength = QtWidgets.QLabel("")
self.bottompsteelstrength = QtWidgets.QLabel("")
self.stirrupsteelstrength = QtWidgets.QLabel("")
self.designstrengthbox.addWidget(self.designsteelstrength)
self.designstrengthbox.addWidget(self.topsteelstrength, alignment=QtCore.Qt.AlignCenter)
self.designstrengthbox.addWidget(self.longsteelstrength, alignment=QtCore.Qt.AlignCenter)
self.designstrengthbox.addWidget(self.bottompsteelstrength, alignment=QtCore.Qt.AlignCenter)
self.designstrengthbox.addWidget(self.stirrupsteelstrength, alignment=QtCore.Qt.AlignCenter)
self.sbox = QtWidgets.QVBoxLayout()
self.anytext = QtWidgets.QLabel("Any text")
self.value = QtWidgets.QLabel("Any")
self.value1 = QtWidgets.QLabel("Any")
self.value2 = QtWidgets.QLabel("Any")
self.value3 = QtWidgets.QLabel("Any")
self.sbox.addWidget(self.anytext)
self.sbox.addWidget(self.value)
self.sbox.addWidget(self.value1)
self.sbox.addWidget(self.value2)
self.sbox.addWidget(self.value3)
self.hlay = QtWidgets.QHBoxLayout()
self.hlay.addStretch()
self.hlay.addLayout(self.rebarbox)
self.hlay.addLayout(self.typebox)
self.hlay.addLayout(self.Reinforcebox)
self.hlay.addLayout(self.designstrengthbox)
self.hlay.addLayout(self.sbox)
self.hlay.addStretch()
Concrete_Group = QtWidgets.QGroupBox(self)
Concrete_Group.setTitle("&GroupC")
Concrete_Group.setLayout(self.hlay)
self.rebarstrength = ["1","2","3","4"]
self.topone.activated.connect(self.setdatatopstrength)
#QtCore.pyqtSlot(int)
def setdatatopstrength(self, index):
value = self.rebarstrength[index]
self.display_topsteeldata(value)
#QtCore.pyqtSlot(int)
def display_topsteeldata(self, value):
try:
gammas = 1.15
fyd = int(float(value)/gammas)
fmt = "{}"
self.topsteelstrength.setText(fmt.format(str(fyd)))
except ValueError:
print("Error")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = ClassWidget()
w.show()
sys.exit(app.exec_())
The problem is simple, the groupboxes that are inside ClassA, ClassB and ClassC are just children and therefore the minimunSizeHint() of ClassA, ClassB and ClassC is (0, 0). For example, we show classA:
So there are 2 solutions:
1. The first is to establish a layout for ClassA, ClassB and ClassC classes, for example:
...
Concrete_Group = QtWidgets.QGroupBox()
Concrete_Group.setTitle("&GroupA")
Concrete_Group.setLayout(self.vlay)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(Concrete_Group)
...
Complete code:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class ClassWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ClassWidget, self).__init__(parent)
self.setGeometry(QtCore.QRect(200, 100, 670, 360))
self.A = ClassA()
self.B = ClassB()
self.C = ClassC()
grid = QtWidgets.QGridLayout(self)
grid.addWidget(self.A, 0, 0)
grid.addWidget(self.B, 0, 1, 1, 2)
grid.addWidget(self.C, 1, 0, 1, 2)
class ClassA(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ClassA, self).__init__(parent)
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
self.c_lay = QtWidgets.QHBoxLayout()
fctd = "One\n\nTwo\n\nThree"
con_strength = QtWidgets.QLabel(fctd)
self.value = QtWidgets.QLineEdit('Test')
self.c_lay.addWidget(con_strength)
self.c_lay.addWidget(self.value, alignment=QtCore.Qt.AlignRight)
self.combo = QtWidgets.QComboBox()
self.combo.addItems(["10","12","14","16"])
self.hbox = QtWidgets.QHBoxLayout()
self.con = QtWidgets.QLabel("Number: ")
self.hbox.addWidget(self.con)
self.hbox.addWidget(self.combo)
self.vlay = QtWidgets.QVBoxLayout()
self.vlay.addLayout(self.hbox)
self.vlay.addLayout(self.c_lay)
self.vlay.addStretch()
Concrete_Group = QtWidgets.QGroupBox()
Concrete_Group.setTitle("&GroupA")
Concrete_Group.setLayout(self.vlay)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(Concrete_Group)
self.comth = ["10","12","14","16"]
self.combo.activated.connect(self.setdatastrength)
#QtCore.pyqtSlot(int)
def setdatastrength(self, index):
value = self.comth[index]
self.display_data(value)
def display_data(self, value):
try:
f = value
f_value = "{}"
self.value.setText(f_value.format(f))
except ValueError:
print("Error")
class ClassB(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ClassB, self).__init__(parent)
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
self.combo_exclass = QtWidgets.QComboBox()
self.combo_exclass.addItems([" Very dry area"," Dry or permanently wet"," Wet, rarely dry"," Moderate humidity"," Tidal splash & spray zones"])
self.combo_lclass = QtWidgets.QComboBox()
self.combo_lclass.addItems(["L2","L4","L6","L8"])
self.combo_vct = QtWidgets.QComboBox()
self.combo_vct.addItems(["0.10","0.20","0.30","0.40",
"0.50","0.60","0.70"])
self.combo_in = QtWidgets.QComboBox()
self.combo_in.addItems(["Class1","Class2","Class3"])
self.tbox = QtWidgets.QHBoxLayout()
self.exclass = QtWidgets.QLabel("Class1: ")
self.tbox.addWidget(self.exclass)
self.tbox.addWidget(self.combo_exclass)
self.mtbox = QtWidgets.QHBoxLayout()
self.lclass = QtWidgets.QLabel("Class2: ")
self.mtbox.addWidget(self.lclass)
self.mtbox.addWidget(self.combo_lclass)
self.mbbox = QtWidgets.QHBoxLayout()
self.vct = QtWidgets.QLabel("Class3: ")
self.mbbox.addWidget(self.vct)
self.mbbox.addWidget(self.combo_vct)
self.bbox = QtWidgets.QHBoxLayout()
self.inl = QtWidgets.QLabel("Class4: ")
self.bbox.addWidget(self.inl)
self.bbox.addWidget(self.combo_in)
self.grid = QtWidgets.QGridLayout()
self.grid.addLayout(self.tbox, 0, 0, 1, 2)
self.grid.addLayout(self.mtbox, 1, 0)
self.grid.addLayout(self.mbbox, 2, 0)
self.grid.addLayout(self.bbox, 3, 0)
Environment_Group = QtWidgets.QGroupBox()
Environment_Group.setTitle("&Group2")
Environment_Group.setLayout(self.grid)
vlay = QtWidgets.QVBoxLayout(self)
vlay.addWidget(Environment_Group)
class ClassC(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ClassC, self).__init__(parent)
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
self.topone = QtWidgets.QComboBox()
self.topone.addItems(["One","Two","Three","four"])
self.longitudinalone = QtWidgets.QComboBox()
self.longitudinalone.addItems(["One","Two","Three","four"])
self.bottomone = QtWidgets.QComboBox()
self.bottomone.addItems(["One","Two","Three","four"])
self.stirrupone = QtWidgets.QComboBox()
self.stirrupone.addItems(["One","Two","Three","four"])
self.toprebar = QtWidgets.QComboBox()
self.toprebar.addItems(["1","2","3","4","5","6","7","8","9"])
self.longitudinalrebar = QtWidgets.QComboBox()
self.longitudinalrebar.addItems(["1","2","3","4","5","6",
"7","8","9"])
self.bottomrebar = QtWidgets.QComboBox()
self.bottomrebar.addItems(["1","2","3","4","5","6","7","8","9"])
self.stirruprebar = QtWidgets.QComboBox()
self.stirruprebar.addItems(["1","2","3","4","5","6","7","8","9"])
self.rebarbox = QtWidgets.QVBoxLayout()
self.topvoid = QtWidgets.QLabel(" ")
self.top = QtWidgets.QLabel("One: ")
self.longitudinal = QtWidgets.QLabel("Two: ")
self.bottom = QtWidgets.QLabel("Three: ")
self.stirrup = QtWidgets.QLabel("Four: ")
self.rebarbox.addWidget(self.topvoid)
self.rebarbox.addWidget(self.top)
self.rebarbox.addWidget(self.longitudinal)
self.rebarbox.addWidget(self.bottom)
self.rebarbox.addWidget(self.stirrup)
self.typebox = QtWidgets.QVBoxLayout()
self.type = QtWidgets.QLabel("Type ")
self.typebox.addWidget(self.type, alignment=QtCore.Qt.AlignCenter)
self.typebox.addWidget(self.topone)
self.typebox.addWidget(self.longitudinalone)
self.typebox.addWidget(self.bottomone)
self.typebox.addWidget(self.stirrupone)
self.Reinforcebox = QtWidgets.QVBoxLayout()
self.Reinforcement = QtWidgets.QLabel("One, One")
self.Reinforcebox.addWidget(self.Reinforcement)
self.Reinforcebox.addWidget(self.toprebar)
self.Reinforcebox.addWidget(self.longitudinalrebar)
self.Reinforcebox.addWidget(self.bottomrebar)
self.Reinforcebox.addWidget(self.stirruprebar)
self.designstrengthbox = QtWidgets.QVBoxLayout()
self.designsteelstrength = QtWidgets.QLabel("Four")
self.topsteelstrength = QtWidgets.QLabel()
self.longsteelstrength = QtWidgets.QLabel()
self.bottompsteelstrength = QtWidgets.QLabel()
self.stirrupsteelstrength = QtWidgets.QLabel()
self.designstrengthbox.addWidget(self.designsteelstrength)
self.designstrengthbox.addWidget(self.topsteelstrength, alignment=QtCore.Qt.AlignCenter)
self.designstrengthbox.addWidget(self.longsteelstrength, alignment=QtCore.Qt.AlignCenter)
self.designstrengthbox.addWidget(self.bottompsteelstrength, alignment=QtCore.Qt.AlignCenter)
self.designstrengthbox.addWidget(self.stirrupsteelstrength, alignment=QtCore.Qt.AlignCenter)
self.sbox = QtWidgets.QVBoxLayout()
self.anytext = QtWidgets.QLabel("Any text")
self.value = QtWidgets.QLabel("Any")
self.value1 = QtWidgets.QLabel("Any")
self.value2 = QtWidgets.QLabel("Any")
self.value3 = QtWidgets.QLabel("Any")
self.sbox.addWidget(self.anytext)
self.sbox.addWidget(self.value)
self.sbox.addWidget(self.value1)
self.sbox.addWidget(self.value2)
self.sbox.addWidget(self.value3)
self.hlay = QtWidgets.QHBoxLayout()
self.hlay.addStretch()
self.hlay.addLayout(self.rebarbox)
self.hlay.addLayout(self.typebox)
self.hlay.addLayout(self.Reinforcebox)
self.hlay.addLayout(self.designstrengthbox)
self.hlay.addLayout(self.sbox)
self.hlay.addStretch()
Concrete_Group = QtWidgets.QGroupBox()
Concrete_Group.setTitle("&GroupC")
Concrete_Group.setLayout(self.hlay)
self.rebarstrength = ["1","2","3","4"]
self.topone.activated.connect(self.setdatatopstrength)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(Concrete_Group)
#QtCore.pyqtSlot(int)
def setdatatopstrength(self, index):
value = self.rebarstrength[index]
self.display_topsteeldata(value)
#QtCore.pyqtSlot(int)
def display_topsteeldata(self, value):
try:
gammas = 1.15
fyd = int(float(value)/gammas)
fmt = "{}"
self.topsteelstrength.setText(fmt.format(str(fyd)))
except ValueError:
print("Error")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = ClassWidget()
w.show()
sys.exit(app.exec_())
2. Or classA, class and class are inherited from QGroubBox, for this you can, for example, do the following:
class ClassA(QtWidgets.QGroupBox):
def __init__(self, parent=None):
super(ClassA, self).__init__(parent)
...
self.setTitle("&GroupA")
self.setLayout(self.vlay)
...
Complete code:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class ClassWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ClassWidget, self).__init__(parent)
self.setGeometry(QtCore.QRect(200, 100, 670, 360))
self.A = ClassA()
self.B = ClassB()
self.C = ClassC()
grid = QtWidgets.QGridLayout(self)
grid.addWidget(self.A, 0, 0)
grid.addWidget(self.B, 0, 1, 1, 2)
grid.addWidget(self.C, 1, 0, 1, 2)
class ClassA(QtWidgets.QGroupBox):
def __init__(self, parent=None):
super(ClassA, self).__init__(parent)
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
self.c_lay = QtWidgets.QHBoxLayout()
fctd = "One\n\nTwo\n\nThree"
con_strength = QtWidgets.QLabel(fctd)
self.value = QtWidgets.QLineEdit('Test')
self.c_lay.addWidget(con_strength)
self.c_lay.addWidget(self.value, alignment=QtCore.Qt.AlignRight)
self.combo = QtWidgets.QComboBox()
self.combo.addItems(["10","12","14","16"])
self.hbox = QtWidgets.QHBoxLayout()
self.con = QtWidgets.QLabel("Number: ")
self.hbox.addWidget(self.con)
self.hbox.addWidget(self.combo)
self.vlay = QtWidgets.QVBoxLayout()
self.vlay.addLayout(self.hbox)
self.vlay.addLayout(self.c_lay)
self.vlay.addStretch()
self.setTitle("&GroupA")
self.setLayout(self.vlay)
self.comth = ["10","12","14","16"]
self.combo.activated.connect(self.setdatastrength)
#QtCore.pyqtSlot(int)
def setdatastrength(self, index):
value = self.comth[index]
self.display_data(value)
def display_data(self, value):
try:
f = value
f_value = "{}"
self.value.setText(f_value.format(f))
except ValueError:
print("Error")
class ClassB(QtWidgets.QGroupBox):
def __init__(self, parent=None):
super(ClassB, self).__init__(parent)
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
self.combo_exclass = QtWidgets.QComboBox()
self.combo_exclass.addItems([" Very dry area"," Dry or permanently wet"," Wet, rarely dry"," Moderate humidity"," Tidal splash & spray zones"])
self.combo_lclass = QtWidgets.QComboBox()
self.combo_lclass.addItems(["L2","L4","L6","L8"])
self.combo_vct = QtWidgets.QComboBox()
self.combo_vct.addItems(["0.10","0.20","0.30","0.40",
"0.50","0.60","0.70"])
self.combo_in = QtWidgets.QComboBox()
self.combo_in.addItems(["Class1","Class2","Class3"])
self.tbox = QtWidgets.QHBoxLayout()
self.exclass = QtWidgets.QLabel("Class1: ")
self.tbox.addWidget(self.exclass)
self.tbox.addWidget(self.combo_exclass)
self.mtbox = QtWidgets.QHBoxLayout()
self.lclass = QtWidgets.QLabel("Class2: ")
self.mtbox.addWidget(self.lclass)
self.mtbox.addWidget(self.combo_lclass)
self.mbbox = QtWidgets.QHBoxLayout()
self.vct = QtWidgets.QLabel("Class3: ")
self.mbbox.addWidget(self.vct)
self.mbbox.addWidget(self.combo_vct)
self.bbox = QtWidgets.QHBoxLayout()
self.inl = QtWidgets.QLabel("Class4: ")
self.bbox.addWidget(self.inl)
self.bbox.addWidget(self.combo_in)
self.grid = QtWidgets.QGridLayout()
self.grid.addLayout(self.tbox, 0, 0, 1, 2)
self.grid.addLayout(self.mtbox, 1, 0)
self.grid.addLayout(self.mbbox, 2, 0)
self.grid.addLayout(self.bbox, 3, 0)
self.setTitle("&Group2")
self.setLayout(self.grid)
class ClassC(QtWidgets.QGroupBox):
def __init__(self, parent=None):
super(ClassC, self).__init__(parent)
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
self.topone = QtWidgets.QComboBox()
self.topone.addItems(["One","Two","Three","four"])
self.longitudinalone = QtWidgets.QComboBox()
self.longitudinalone.addItems(["One","Two","Three","four"])
self.bottomone = QtWidgets.QComboBox()
self.bottomone.addItems(["One","Two","Three","four"])
self.stirrupone = QtWidgets.QComboBox()
self.stirrupone.addItems(["One","Two","Three","four"])
self.toprebar = QtWidgets.QComboBox()
self.toprebar.addItems(["1","2","3","4","5","6","7","8","9"])
self.longitudinalrebar = QtWidgets.QComboBox()
self.longitudinalrebar.addItems(["1","2","3","4","5","6",
"7","8","9"])
self.bottomrebar = QtWidgets.QComboBox()
self.bottomrebar.addItems(["1","2","3","4","5","6","7","8","9"])
self.stirruprebar = QtWidgets.QComboBox()
self.stirruprebar.addItems(["1","2","3","4","5","6","7","8","9"])
self.rebarbox = QtWidgets.QVBoxLayout()
self.topvoid = QtWidgets.QLabel(" ")
self.top = QtWidgets.QLabel("One: ")
self.longitudinal = QtWidgets.QLabel("Two: ")
self.bottom = QtWidgets.QLabel("Three: ")
self.stirrup = QtWidgets.QLabel("Four: ")
self.rebarbox.addWidget(self.topvoid)
self.rebarbox.addWidget(self.top)
self.rebarbox.addWidget(self.longitudinal)
self.rebarbox.addWidget(self.bottom)
self.rebarbox.addWidget(self.stirrup)
self.typebox = QtWidgets.QVBoxLayout()
self.type = QtWidgets.QLabel("Type ")
self.typebox.addWidget(self.type, alignment=QtCore.Qt.AlignCenter)
self.typebox.addWidget(self.topone)
self.typebox.addWidget(self.longitudinalone)
self.typebox.addWidget(self.bottomone)
self.typebox.addWidget(self.stirrupone)
self.Reinforcebox = QtWidgets.QVBoxLayout()
self.Reinforcement = QtWidgets.QLabel("One, One")
self.Reinforcebox.addWidget(self.Reinforcement)
self.Reinforcebox.addWidget(self.toprebar)
self.Reinforcebox.addWidget(self.longitudinalrebar)
self.Reinforcebox.addWidget(self.bottomrebar)
self.Reinforcebox.addWidget(self.stirruprebar)
self.designstrengthbox = QtWidgets.QVBoxLayout()
self.designsteelstrength = QtWidgets.QLabel("Four")
self.topsteelstrength = QtWidgets.QLabel()
self.longsteelstrength = QtWidgets.QLabel()
self.bottompsteelstrength = QtWidgets.QLabel()
self.stirrupsteelstrength = QtWidgets.QLabel()
self.designstrengthbox.addWidget(self.designsteelstrength)
self.designstrengthbox.addWidget(self.topsteelstrength, alignment=QtCore.Qt.AlignCenter)
self.designstrengthbox.addWidget(self.longsteelstrength, alignment=QtCore.Qt.AlignCenter)
self.designstrengthbox.addWidget(self.bottompsteelstrength, alignment=QtCore.Qt.AlignCenter)
self.designstrengthbox.addWidget(self.stirrupsteelstrength, alignment=QtCore.Qt.AlignCenter)
self.sbox = QtWidgets.QVBoxLayout()
self.anytext = QtWidgets.QLabel("Any text")
self.value = QtWidgets.QLabel("Any")
self.value1 = QtWidgets.QLabel("Any")
self.value2 = QtWidgets.QLabel("Any")
self.value3 = QtWidgets.QLabel("Any")
self.sbox.addWidget(self.anytext)
self.sbox.addWidget(self.value)
self.sbox.addWidget(self.value1)
self.sbox.addWidget(self.value2)
self.sbox.addWidget(self.value3)
self.hlay = QtWidgets.QHBoxLayout()
self.hlay.addStretch()
self.hlay.addLayout(self.rebarbox)
self.hlay.addLayout(self.typebox)
self.hlay.addLayout(self.Reinforcebox)
self.hlay.addLayout(self.designstrengthbox)
self.hlay.addLayout(self.sbox)
self.hlay.addStretch()
self.setTitle("&GroupC")
self.setLayout(self.hlay)
self.rebarstrength = ["1","2","3","4"]
self.topone.activated.connect(self.setdatatopstrength)
#QtCore.pyqtSlot(int)
def setdatatopstrength(self, index):
value = self.rebarstrength[index]
self.display_topsteeldata(value)
#QtCore.pyqtSlot(int)
def display_topsteeldata(self, value):
try:
gammas = 1.15
fyd = int(float(value)/gammas)
fmt = "{}"
self.topsteelstrength.setText(fmt.format(str(fyd)))
except ValueError:
print("Error")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = ClassWidget()
w.show()
sys.exit(app.exec_())
user can draw rectangles by this application by giving clicking twice on grey picture. But this application dont saves last rectangles, instead of saving its drawing(updateing) a new rectangle by 2 next points. how i can solve this problem? how can i save previouse rectangles too?
class myQLabel(QLabel):
def __init__(self,parent):
super(myQLabel, self).__init__(parent)
self.x = 0
self.y = 0
self.trafficlines = []
def mousePressEvent(self, QMouseEvent):
#print mode
self.x = QMouseEvent.x()
self.y = QMouseEvent.y()
if self.x != 0 and self.y != 0:
self.trafficlines.append(copy.deepcopy([self.x,self.y]))
print "______"
print self.x
print self.y
print "("+str(mode)+")"
print "______"
def paintEvent(self, QPaintEvent):
super(myQLabel, self).paintEvent(QPaintEvent)
painter = QPainter(self)
if mode == 0:
painter.setPen(QPen(Qt.red,3))
elif mode == 1:
painter.setPen(QPen(Qt.blue,3))
elif mode == 2:
painter.setPen(QPen(Qt.green,3))
elif mode == 3:
painter.setPen(QPen(Qt.magenta,3))
if len(self.trafficlines)%2==1 and len(self.trafficlines)>0:
painter.drawPoint(self.trafficlines[-1][0],self.trafficlines[-1][1])
if len(self.trafficlines)%2==0 and len(self.trafficlines)>0 and mode!=0:
painter.drawLine( self.trafficlines[-2][0],self.trafficlines[-2][1],self.trafficlines[-1][0],self.trafficlines[-1][1] )
if len(self.trafficlines)%2==0 and len(self.trafficlines)>0 and mode==0:
x1=self.trafficlines[-2][0]
y1=self.trafficlines[-2][1]
x2=self.trafficlines[-1][0]
y2=self.trafficlines[-1][1]
painter.drawLine( x1,y1,x1,y2)
painter.drawLine( x1,y2,x2,y2)
painter.drawLine( x2,y2,x2,y1)
painter.drawLine( x2,y1,x1,y1)
self.update()
This is all the code:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys, os
import copy
mode = 5
class Example(QWidget):
def __init__(self,parent):
super(Example, self).__init__()
self.main_image_name="C:\Python27\project\main_image.png"
self.initUI()
def initUI(self):
File_name = QLabel('Setup file name')
File_name_edit = QLineEdit()
QToolTip.setFont(QFont('SansSerif', 10))
#QMainWindow.statusBar().showMessage('Ready')
self.setGeometry(300, 300, 250, 150)
self.resize(640, 360)
#self.setFixedSize(640, 360)
self.center()
self.main_image = myQLabel(self)
self.main_image.setPixmap(QPixmap(self.main_image_name))
btn = QPushButton("Make setup file")
btn.setToolTip('Press <b>Detect</b> button for detecting objects by your settings')
btn.resize(btn.sizeHint())
btn.clicked.connect(QCoreApplication.instance().quit)
btn_browse = QPushButton("Browse")
btn_browse.clicked.connect(self.browse)
btn_set = QPushButton("Set name")
#fullscreen
#self.main_image.setScaledContents(True)
#just centered
self.main_image.setAlignment(Qt.AlignCenter)
#Layout
box_File_name = QHBoxLayout()
box_File_name.addWidget(File_name)
box_File_name.addWidget(File_name_edit)
box_File_name.addWidget(btn_set)
grid = QGridLayout()
grid.setSpacing(10)
grid.addLayout(box_File_name, 1, 0)
#grid.addWidget(File_name_edit, 1, 1)
grid.addWidget(self.main_image, 2, 0)
grid.addWidget(btn_browse, 3 , 0)
grid.addWidget(btn, 4, 0)
box_number = QVBoxLayout()
number_group=QButtonGroup() # Number group
r0=QRadioButton("Traffic Lights")
number_group.addButton(r0)
r1=QRadioButton("Direction")
number_group.addButton(r1)
r2=QRadioButton("Traffic Lines H")
number_group.addButton(r2)
r3=QRadioButton("Traffic Lines V")
number_group.addButton(r3)
box_number.addWidget(r0)
box_number.addWidget(r1)
box_number.addWidget(r2)
box_number.addWidget(r3)
r0.toggled.connect(self.radio0_clicked)
r1.toggled.connect(self.radio1_clicked)
r2.toggled.connect(self.radio2_clicked)
r3.toggled.connect(self.radio3_clicked)
box_road_sign = QHBoxLayout()
road_sign_label = QLabel('Road signs', self)
road_sign = QComboBox()
road_sign.addItem("None")
road_sign.addItem("ex1")
road_sign.addItem("ex2")
road_sign.addItem("ex3")
road_sign.addItem("ex4")
road_sign.addItem("ex5")
box_road_sign.addWidget(road_sign_label)
box_road_sign.addWidget(road_sign)
grid.addLayout(box_road_sign, 1, 1)
grid.addLayout(box_number, 2, 1)
self.setLayout(grid)
self.show()
def browse(self):
w = QWidget()
w.resize(320, 240)
w.setWindowTitle("Select Picture")
filename = QFileDialog.getOpenFileName(w, 'Open File', '/')
self.main_image_name = filename
self.main_image.setPixmap(QPixmap(self.main_image_name))
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def radio0_clicked(self, enabled):
if enabled:
print("0")
global mode
mode=0
def radio1_clicked(self, enabled):
if enabled:
print("1")
global mode
mode=1
def radio2_clicked(self, enabled):
if enabled:
print("2")
global mode
mode=2
def radio3_clicked(self, enabled):
if enabled:
print("3")
global mode
mode=3
class myQLabel(QLabel):
def __init__(self,parent):
super(myQLabel, self).__init__(parent)
self.x = 0
self.y = 0
self.trafficlines = []
def mousePressEvent(self, QMouseEvent):
#print mode
self.x = QMouseEvent.x()
self.y = QMouseEvent.y()
if self.x != 0 and self.y != 0:
self.trafficlines.append(copy.deepcopy([self.x,self.y]))
print "______"
print self.x
print self.y
print "("+str(mode)+")"
print "______"
def paintEvent(self, QPaintEvent):
super(myQLabel, self).paintEvent(QPaintEvent)
painter = QPainter(self)
if mode == 0:
painter.setPen(QPen(Qt.red,3))
elif mode == 1:
painter.setPen(QPen(Qt.blue,3))
elif mode == 2:
painter.setPen(QPen(Qt.green,3))
elif mode == 3:
painter.setPen(QPen(Qt.magenta,3))
if len(self.trafficlines)%2==1 and len(self.trafficlines)>0:
painter.drawPoint(self.trafficlines[-1][0],self.trafficlines[-1][1])
if len(self.trafficlines)%2==0 and len(self.trafficlines)>0 and mode!=0:
painter.drawLine( self.trafficlines[-2][0],self.trafficlines[-2][1],self.trafficlines[-1][0],self.trafficlines[-1][1] )
if len(self.trafficlines)%2==0 and len(self.trafficlines)>0 and mode==0:
x1=self.trafficlines[-2][0]
y1=self.trafficlines[-2][1]
x2=self.trafficlines[-1][0]
y2=self.trafficlines[-1][1]
painter.drawLine( x1,y1,x1,y2)
painter.drawLine( x1,y2,x2,y2)
painter.drawLine( x2,y2,x2,y1)
painter.drawLine( x2,y1,x1,y1)
self.update()
class menubarex(QMainWindow):
def __init__(self, parent=None):
super(menubarex, self).__init__(parent)
self.form_widget = Example(self)
self.setCentralWidget(self.form_widget)
self.initUI()
def initUI(self):
exitAction = QAction(QIcon('exit.png'), '&Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit application')
exitAction.triggered.connect(qApp.quit)
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAction)
#self.toolbar = self.addToolBar('Exit')
#self.toolbar.addAction(exitAction)
self.statusBar().showMessage('Ready')
self.setWindowTitle('mi ban')
self.setWindowIcon(QIcon('C:\Python27\project\icon.png'))
def closeEvent(self, event):
reply = QMessageBox.question(self, 'Message',
"Are you sure to quit?", QMessageBox.Yes |
QMessageBox.No)
if reply == QMessageBox.Yes:
event.accept()
else:
event.ignore()
def main():
app = QApplication(sys.argv)
#ex = Example()
menubar = menubarex()
menubar.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
paintEvent() redraws the entire widget, so it does not save memory from the previous drawing, so the rectangles or previous lines are not saved. The solution is to store those states and redraw everything again, for this we can store the mode and points in trafficlines as shown below:
class myQLabel(QLabel):
def __init__(self,parent):
super(myQLabel, self).__init__(parent)
self.trafficlines = []
self.mode = 0
self.start_point = QPoint()
def setMode(self, mode):
self.mode = mode
def mousePressEvent(self, event):
if self.start_point.isNull():
self.start_point = event.pos()
else:
self.trafficlines.append((self.mode,[self.start_point, event.pos()]))
self.start_point = QPoint()
self.update()
def paintEvent(self, event):
super(myQLabel, self).paintEvent(event)
painter = QPainter(self)
colors = [Qt.red, Qt.blue, Qt.green, Qt.magenta]
for mode, points in self.trafficlines:
painter.setPen(QPen(colors[mode],3))
if mode != 0:
painter.drawLine(*points)
else:
rect = QRect(*points)
painter.drawRect(rect)
if not self.start_point.isNull():
painter.setPen(QPen(colors[self.mode],3))
painter.drawPoint(self.start_point)
Note: do not use global variables, they are difficult to debug, in addition to unnecessary many times.
Also I take the liberty to improve your code by making it more readable with fewer lines. The complete code is in the following part:
import sys
import os
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class Example(QWidget):
def __init__(self,parent):
super(Example, self).__init__()
self.main_image_name="C:\Python27\project\main_image.png"
self.initUI()
def initUI(self):
File_name = QLabel('Setup file name')
File_name_edit = QLineEdit()
self.resize(640, 360)
self.center()
self.main_image = myQLabel(self)
self.main_image.setPixmap(QPixmap(self.main_image_name))
btn = QPushButton("Make setup file")
btn.setToolTip('Press <b>Detect</b> button for detecting objects by your settings')
btn.resize(btn.sizeHint())
btn.clicked.connect(QCoreApplication.instance().quit)
btn_browse = QPushButton("Browse")
btn_browse.clicked.connect(self.browse)
btn_set = QPushButton("Set name")
self.main_image.setAlignment(Qt.AlignCenter)
#Layout
box_File_name = QHBoxLayout()
box_File_name.addWidget(File_name)
box_File_name.addWidget(File_name_edit)
box_File_name.addWidget(btn_set)
grid = QGridLayout(self)
grid.setSpacing(10)
grid.addLayout(box_File_name, 1, 0)
#grid.addWidget(File_name_edit, 1, 1)
grid.addWidget(self.main_image, 2, 0)
grid.addWidget(btn_browse, 3 , 0)
grid.addWidget(btn, 4, 0)
box_number = QVBoxLayout()
number_group = QButtonGroup(self) # Number group
for i, text in enumerate(["Traffic Lights", "Direction", "Traffic Lines H", "Traffic Lines V"]):
rb = QRadioButton(text)
box_number.addWidget(rb)
number_group.addButton(rb, i)
number_group.buttonClicked[int].connect(self.main_image.setMode)
number_group.button(0).setChecked(True)
box_road_sign = QHBoxLayout()
road_sign_label = QLabel('Road signs', self)
road_sign = QComboBox()
road_sign.addItems(["None", "ex1", "ex2","ex3", "ex4", "ex5"])
box_road_sign.addWidget(road_sign_label)
box_road_sign.addWidget(road_sign)
grid.addLayout(box_road_sign, 1, 1)
grid.addLayout(box_number, 2, 1)
def browse(self):
filename = QFileDialog.getOpenFileName(self, 'Open File', '/')
self.main_image_name = filename
self.main_image.setPixmap(QPixmap(self.main_image_name))
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
class myQLabel(QLabel):
def __init__(self,parent):
super(myQLabel, self).__init__(parent)
self.trafficlines = []
self.mode = 0
self.start_point = QPoint()
def setMode(self, mode):
self.mode = mode
def mousePressEvent(self, event):
if self.start_point.isNull():
self.start_point = event.pos()
else:
self.trafficlines.append((self.mode,[self.start_point, event.pos()]))
self.start_point = QPoint()
self.update()
def paintEvent(self, event):
super(myQLabel, self).paintEvent(event)
painter = QPainter(self)
colors = [Qt.red, Qt.blue, Qt.green, Qt.magenta]
for mode, points in self.trafficlines:
painter.setPen(QPen(colors[mode],3))
if mode != 0:
painter.drawLine(*points)
else:
rect = QRect(*points)
painter.drawRect(rect)
if not self.start_point.isNull():
painter.setPen(QPen(colors[self.mode],3))
painter.drawPoint(self.start_point)
class menubarex(QMainWindow):
def __init__(self, parent=None):
super(menubarex, self).__init__(parent)
self.form_widget = Example(self)
self.setCentralWidget(self.form_widget)
self.initUI()
def initUI(self):
exitAction = QAction(QIcon('exit.png'), '&Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit application')
exitAction.triggered.connect(qApp.quit)
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAction)
self.statusBar().showMessage('Ready')
self.setWindowTitle('mi ban')
self.setWindowIcon(QIcon('C:\Python27\project\icon.png'))
def closeEvent(self, event):
reply = QMessageBox.question(self, 'Message',
"Are you sure to quit?", QMessageBox.Yes |
QMessageBox.No)
if reply == QMessageBox.Yes:
event.accept()
else:
event.ignore()
def main():
app = QApplication(sys.argv)
#ex = Example()
menubar = menubarex()
menubar.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()