Related
There is a QWidget, which is called with the button "Start" in the main widget.
It shows some text, which should be updated every minute during the work of the QWidget.
How can I make this infinity updating within this code?
class ExampleWidget(QWidget):
def __init__(self, parent=None):
super().__init__()
self.setWindowTitle('Example Widget ScrollArea')
self.initUi()
def initUi(self):
area = QScrollArea(self)
area.setWidgetResizable(True)
self.scrollAreaWidgetContents = QLabel(some_text, self)
area.setWidget(self.scrollAreaWidgetContents)
button = QPushButton("Close")
button.clicked.connect(self.goMainWindow)
layoutV = QVBoxLayout()
layoutV.addWidget(area)
layoutV.addWidget(button)
self.setLayout(layoutV)
def goMainWindow(self):
self.hide()
def sizeHint(self):
return QSize(400, 200)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
start_main_button = QPushButton('Start', self)
start_main_button.move(40, 40)
start_main_button.clicked.connect(self.start)
self.setGeometry(300, 300, 290, 150)
self.setWindowTitle('Test')
def start(self):
global some_text
some_text = 'some text'
self.result_widget = ExampleWidget()
self.result_widget.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
One of my tries:
def start(self):
global some_text
some_text = 'some text'
self.result_widget = ExampleWidget()
self.result_widget.show()
i = 0
while True:
i+=1
some_text+=str(i)
self.result_widget = ExampleWidget()
self.result_widget.show()
Forget the global variables because they are considered bad practice, on the other hand in a GUI you should avoid having loops that consume a lot of time, and in your case a while True blocks the GUI. In Qt if you want to do periodic tasks you must use a QTimer:
from PyQt5 import QtCore, QtWidgets
class ExampleWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__()
self.setWindowTitle('Example Widget ScrollArea')
self.initUi()
def initUi(self):
area = QtWidgets.QScrollArea()
area.setWidgetResizable(True)
self.scrollAreaWidgetContents = QtWidgets.QLabel("some_text")
area.setWidget(self.scrollAreaWidgetContents)
button = QtWidgets.QPushButton("Close")
button.clicked.connect(self.hide)
layoutV = QtWidgets.QVBoxLayout(self)
layoutV.addWidget(area)
layoutV.addWidget(button)
def update_text(self, text):
# update the text
self.scrollAreaWidgetContents.setText(text)
def sizeHint(self):
return QtCore.QSize(400, 200)
class MainWindow(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
start_main_button = QtWidgets.QPushButton('Start', self)
start_main_button.move(40, 40)
start_main_button.clicked.connect(self.start)
self.setGeometry(300, 300, 290, 150)
self.setWindowTitle('Test')
self.result_widget = ExampleWidget()
self.timer = QtCore.QTimer(self, interval=60*1000)
self.timer.timeout.connect(self.on_timeout)
self.counter = 0
self.initial_text = "some_text"
def on_timeout(self):
# this method will be called every 60 * 1000 ms
self.initial_text += str(self.counter)
self.result_widget.update_text(self.initial_text)
self.counter += 1
#QtCore.pyqtSlot()
def start(self):
self.result_widget.show()
# start timer
self.timer.start()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
I have QButtons arranged as first row has four buttons and second row has five buttons.
My code is developed using PyQt5 in Python2.7.
from PyQt5 import QtCore, QtGui, QtWidgets
import cv2
import time
import face_recognition.api as face_recognition
class Thread(QtCore.QThread):
changePixmap = QtCore.pyqtSignal(QtGui.QImage)
scaled_size = QtCore.QSize(640, 480)
def run(self):
cap = cv2.VideoCapture(1)
cap.set(3,1280);
cap.set(4,1024);
time.sleep(2)
while True:
ret, frame = cap.read()
if ret:
r=1
face_locations=[]
rescaleSize=480
if(frame.shape[0] > 480 and frame.shape[1] > 640):
r = rescaleSize / float(frame.shape[0])
dim = (int(frame.shape[1] * r), rescaleSize)
face_locations = face_recognition.face_locations(cv2.resize(frame, dim, fx=0.0, fy=0.0))
else:
face_locations = face_recognition.face_locations(frame)
for face_location in face_locations:
top, right, bottom, left = face_location
cv2.rectangle(frame,(int(right/r),int(top/r)),(int(left/r),int(bottom/r)),(0,255,0),2)
rgbImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
convertToQtFormat = QtGui.QImage(rgbImage.data, rgbImage.shape[1], rgbImage.shape[0], QtGui.QImage.Format_RGB888)
p = convertToQtFormat.scaled(self.scaled_size, QtCore.Qt.KeepAspectRatio)
self.changePixmap.emit(p)
def scaled(self, scaled_size):
self.scaled_size = scaled_size
class PlayStreaming(QtWidgets.QLabel):
reSize = QtCore.pyqtSignal(QtCore.QSize)
def __init__(self):
super(PlayStreaming, self).__init__()
self.initUI()
#QtCore.pyqtSlot(QtGui.QImage)
def setImage(self, image):
self.label.setPixmap(QtGui.QPixmap.fromImage(image))
def initUI(self):
self.setWindowTitle("Image")
# create a label
self.label = QtWidgets.QLabel(self)
th = Thread(self)
th.changePixmap.connect(self.setImage)
self.reSize.connect(th.scaled)
th.start()
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.label, alignment=QtCore.Qt.AlignCenter)
def resizeEvent(self, event):
self.reSize.emit(self.size())
class UIWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(UIWidget, self).__init__(parent)
# Initialize tab screen
self.tabs = QtWidgets.QTabWidget()
self.tab1 = QtWidgets.QWidget()
self.tab2 = QtWidgets.QWidget()
self.tab3 = QtWidgets.QWidget()
# Add tabs
self.tabs.addTab(self.tab1, "Face")
self.tabs.addTab(self.tab2, "Human")
self.tabs.addTab(self.tab3, "Vehicle")
# Create first tab
self.createGridLayout()
self.tab1.layout = QtWidgets.QVBoxLayout()
self.display = PlayStreaming()
self.tab1.layout.addWidget(self.display, stretch=1)
self.tab1.layout.addWidget(self.horizontalGroupBox)
self.tab1.setLayout(self.tab1.layout)
# Add tabs to widget
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.tabs)
def createGridLayout(self):
self.horizontalGroupBox = QtWidgets.QGroupBox("")
self.horizontalGroupBox.setStyleSheet("QGroupBox{ background-color: red; border: none;}")
layout = QtWidgets.QGridLayout()
layout.addWidget(QtWidgets.QPushButton('Test'),0,0)
layout.addWidget(QtWidgets.QPushButton('Run'),0,1)
layout.addWidget(QtWidgets.QPushButton('RescaleUp'),0,2)
layout.addWidget(QtWidgets.QPushButton('RescaleDown'),0,3)
layout.addWidget(QtWidgets.QPushButton('Set Faces'),1,0)
layout.addWidget(QtWidgets.QPushButton('FacePose'),1,1)
layout.addWidget(QtWidgets.QPushButton('Gender'),1,2)
layout.addWidget(QtWidgets.QPushButton('Age'),1,3)
layout.addWidget(QtWidgets.QPushButton('Recognize'),1,4)
self.horizontalGroupBox.setLayout(layout)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = UIWidget()
w.resize(1000, 800)
w.show()
sys.exit(app.exec_())
I like to make the first four buttons are equally spaced and the second fuve buttons are also equally spaced.
For that, changes are made as
class UIWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(UIWidget, self).__init__(parent)
# Initialize tab screen
self.tabs = QtWidgets.QTabWidget()
self.tab1 = QtWidgets.QWidget()
self.tab2 = QtWidgets.QWidget()
self.tab3 = QtWidgets.QWidget()
# Add tabs
self.tabs.addTab(self.tab1, "Face")
self.tabs.addTab(self.tab2, "Human")
self.tabs.addTab(self.tab3, "Vehicle")
# Create first tab
self.createGridLayout()
self.tab1.layout = QtWidgets.QVBoxLayout()
self.display = PlayStreaming()
self.tab1.layout.addWidget(self.display, stretch=1)
self.tab1.layout.addWidget(self.horizontalGroupBox)
self.tab1.layout.addWidget(self.horizontalGroupBox2)
self.tab1.setLayout(self.tab1.layout)
# Add tabs to widget
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.tabs)
def createGridLayout(self):
self.horizontalGroupBox = QtWidgets.QGroupBox("")
self.horizontalGroupBox.setStyleSheet("QGroupBox{ background-color: red; border: none;}")
layout = QtWidgets.QGridLayout()
layout.addWidget(QtWidgets.QPushButton('Test'),0,0)
layout.addWidget(QtWidgets.QPushButton('Run'),0,1)
layout.addWidget(QtWidgets.QPushButton('RescaleUp'),0,2)
layout.addWidget(QtWidgets.QPushButton('RescaleDown'),0,3)
self.horizontalGroupBox.setLayout(layout)
self.horizontalGroupBox2 = QtWidgets.QGroupBox("")
self.horizontalGroupBox2.setStyleSheet("QGroupBox{ background-color: red; border: none;}")
layout = QtWidgets.QGridLayout()
layout.addWidget(QtWidgets.QPushButton('Set Faces'),0,0)
layout.addWidget(QtWidgets.QPushButton('FacePose'),0,1)
layout.addWidget(QtWidgets.QPushButton('Gender'),0,2)
layout.addWidget(QtWidgets.QPushButton('Age'),0,3)
layout.addWidget(QtWidgets.QPushButton('Recognize'),0,4)
self.horizontalGroupBox2.setLayout(layout)
Then there is a gap in between two QGroupBoxes.
How can I make so that there is no gap and first row and second row have equally spaced buttons?
You must use 1 QVBoxLayout next to 2 QHBoxLayouts:
def createGridLayout(self):
self.horizontalGroupBox = QtWidgets.QGroupBox("")
self.horizontalGroupBox.setStyleSheet("QGroupBox{ background-color: red; border: none;}")
hlay1 = QtWidgets.QHBoxLayout()
hlay1.addWidget(QtWidgets.QPushButton('Test'))
hlay1.addWidget(QtWidgets.QPushButton('Run'))
hlay1.addWidget(QtWidgets.QPushButton('RescaleUp'))
hlay1.addWidget(QtWidgets.QPushButton('RescaleDown'))
hlay2 = QtWidgets.QHBoxLayout()
hlay2.addWidget(QtWidgets.QPushButton('Set Faces'))
hlay2.addWidget(QtWidgets.QPushButton('FacePose'))
hlay2.addWidget(QtWidgets.QPushButton('Gender'))
hlay2.addWidget(QtWidgets.QPushButton('Age'))
hlay2.addWidget(QtWidgets.QPushButton('Recognize'))
layout = QtWidgets.QVBoxLayout()
layout.addLayout(hlay1)
layout.addLayout(hlay2)
self.horizontalGroupBox.setLayout(layout)
I've a Widget, which wants to display Images with QLabel and QCheckBox. 4 classes are created each contains some information to be put on the final screen.
Class Grid align and grid images, text and checkboxes.
After script running get current screen. No images appear in present widget.
Where are images?
Desired screen
The code
import sys, os
from PyQt5 import QtCore, QtGui, QtWidgets
iconroot = os.path.dirname(__file__)
class ImageWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ImageWidget, self).__init__(parent)
self.hlay = QtWidgets.QHBoxLayout(self)
buckling_ilabel = QtWidgets.QLabel(self)
pixmap = QtGui.QPixmap(os.path.join(iconroot, "images/fixed-fixed.png"))
buckling_ilabel.resize(150, 150)
buckling_ilabel.setPixmap(pixmap.scaled(buckling_ilabel.size(), QtCore.Qt.KeepAspectRatio))
self.hlay.addWidget(buckling_ilabel)
buckling_blabel = QtWidgets.QLabel(self)
pixmap = QtGui.QPixmap(os.path.join(iconroot, "images/pinned-pinned.png"))
buckling_blabel.resize(150, 150)
buckling_blabel.setPixmap(pixmap.scaled(buckling_blabel.size(), QtCore.Qt.KeepAspectRatio))
self.hlay.addWidget(buckling_blabel)
buckling_clabel = QtWidgets.QLabel(self)
pixmap = QtGui.QPixmap(os.path.join(iconroot, "images/fixed-free.png"))
buckling_clabel.resize(150, 150)
buckling_clabel.setPixmap(pixmap.scaled(buckling_clabel.size(), QtCore.Qt.KeepAspectRatio))
self.hlay.addWidget(buckling_clabel)
buckling_dlabel = QtWidgets.QLabel(self)
pixmap = QtGui.QPixmap(os.path.join(iconroot, "images/fixed-pinned.png"))
buckling_dlabel.resize(150, 150)
buckling_dlabel.setPixmap(pixmap.scaled(buckling_dlabel.size(), QtCore.Qt.KeepAspectRatio))
self.hlay.addWidget(buckling_dlabel)
self.setLayout(self.hlay)
class EffLengthInfo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(EffLengthInfo, self).__init__(parent)
ilabel = QtWidgets.QLabel('Ley = 1.0 L\nLec = 1.0 L')
blabel = QtWidgets.QLabel('Ley = 0.699 L\nLec = 0.699 L')
clabel = QtWidgets.QLabel('Ley = 2.0 L\nLec = 2.0 L')
dlabel = QtWidgets.QLabel('Ley = 0.5 L\nLec = 0.5 L')
self.ilay = QtWidgets.QHBoxLayout()
self.ilay.addWidget(ilabel)
self.ilay.addWidget(blabel)
self.ilay.addWidget(clabel)
self.ilay.addWidget(dlabel)
class CheckInfo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(CheckInfo, self).__init__(parent)
icheck = QtWidgets.QCheckBox()
bcheck = QtWidgets.QCheckBox()
ccheck = QtWidgets.QCheckBox()
dcheck = QtWidgets.QCheckBox()
self.checklay = QtWidgets.QHBoxLayout()
self.checklay.addWidget(icheck, alignment=QtCore.Qt.AlignCenter)
self.checklay.addWidget(bcheck, alignment=QtCore.Qt.AlignCenter)
self.checklay.addWidget(ccheck, alignment=QtCore.Qt.AlignCenter)
self.checklay.addWidget(dcheck, alignment=QtCore.Qt.AlignCenter)
class Grid(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Grid, self).__init__(parent)
self.imagewidget = ImageWidget()
self.efflengthinfo = EffLengthInfo()
self.checkinfo = CheckInfo()
vlay = QtWidgets.QVBoxLayout(self)
vlay.addLayout(self.imagewidget.hlay)
vlay.addLayout(self.efflengthinfo.ilay)
vlay.addLayout(self.checkinfo.checklay)
self.setLayout(vlay)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
im = Grid()
im.show()
sys.exit(app.exec_())
The #S.Nick's solution works but it is not the correct one, besides that it does not explain the problem and it only indicates the error message that you should have provided.
The first mistake you have is that you do not have a consistent design, for example, even though a widget is a visual element, it does not only mean that it is only, it also has associated data, so I ask myself: Why did you create the ImageWidget class, the same thing? for EffLengthInfo and CheckInfo? Well it seems that just to create a layout, is it necessary to create a widget to just create a layout? No, because the widget is an unnecessary resource, that is, wasted memory. Therefore, I point out that S.Nick's solution is incorrect since he is inviting others to overlap a design error.
If your goal is just to create layouts then better use a function:
import sys, os
from PyQt5 import QtCore, QtGui, QtWidgets
iconroot = os.path.dirname(__file__)
def create_image_layout():
hlay = QtWidgets.QHBoxLayout()
for icon_name in ("images/fixed-fixed.png",
"images/pinned-pinned.png",
"images/fixed-free.png",
"images/fixed-pinned.png"):
label = QtWidgets.QLabel()
pixmap = QtGui.QPixmap(os.path.join(iconroot, icon_name))
label.resize(150, 150)
label.setPixmap(pixmap.scaled(label.size(), QtCore.Qt.KeepAspectRatio))
hlay.addWidget(label)
return hlay
def create_EffLengthInfo_layout():
hlay = QtWidgets.QHBoxLayout()
for text in ('Ley = 1.0 L\nLec = 1.0 L',
'Ley = 0.699 L\nLec = 0.699 L',
'Ley = 2.0 L\nLec = 2.0 L',
'Ley = 0.5 L\nLec = 0.5 L'):
label = QtWidgets.QLabel(text)
hlay.addWidget(label)
return hlay
def create_checkInfo_layout():
hlay = QtWidgets.QHBoxLayout()
for _ in range(3):
checkbox = QtWidgets.QCheckBox()
hlay.addWidget(checkbox, alignment=QtCore.Qt.AlignCenter)
return hlay
class Grid(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Grid, self).__init__(parent)
image_lay = create_image_layout()
efflengthinfo_lay = create_EffLengthInfo_layout()
checkinfo_lay = create_checkInfo_layout()
vlay = QtWidgets.QVBoxLayout(self)
vlay.addLayout(image_lay)
vlay.addLayout(efflengthinfo_lay)
vlay.addLayout(checkinfo_lay)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
im = Grid()
im.show()
sys.exit(app.exec_())
Why was it shown in the case of EffLengthInfo and CheckInfo "works"?
I point out that it works in quotes because it works but it is not the solution, going to the point, a layout is established in a layout and it is part of the widget and after that it can not be placed in another widget, and if we check ImageWidget we see that you have established two times the layout to the widget:
class ImageWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ImageWidget, self).__init__(parent)
self.hlay = QtWidgets.QHBoxLayout(self) # 1.
...
self.setLayout(self.hlay) # 2.
When you set a widget when building the layout, it is set in that widget.
When the widget sets the layout using the setLayout() method
Therefore you should throw the following error in the line vlay.addLayout(self.imagewidget.hlay):
QLayout::addChildLayout: layout "" already has a parent
Another solution is to set the widgets instead of the layouts:
class ImageWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ImageWidget, self).__init__(parent)
self.hlay = QtWidgets.QHBoxLayout(self)
...
# self.setLayout(self.hlay) # comment this line
class EffLengthInfo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(EffLengthInfo, self).__init__(parent)
...
self.ilay = QtWidgets.QHBoxLayout(self) # <-- add self
class CheckInfo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(CheckInfo, self).__init__(parent)
...
self.checklay = QtWidgets.QHBoxLayout(self) # <-- add self
class Grid(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Grid, self).__init__(parent)
self.imagewidget = ImageWidget()
self.efflengthinfo = EffLengthInfo()
self.checkinfo = CheckInfo()
vlay = QtWidgets.QVBoxLayout(self)
vlay.addWidget(self.imagewidget) # <-- change addLayout() to addWidget()
vlay.addWidget(self.efflengthinfo) # <-- change addLayout() to addWidget()
vlay.addWidget(self.checkinfo) # <-- change addLayout() to addWidget()
...
Another perspective that you might think, and this depends on the use you want to give the widget, is that you want an information unit to be an image, a text and a checkbox, so if it is correct to create a widget:
import sys, os
from PyQt5 import QtCore, QtGui, QtWidgets
iconroot = os.path.dirname(__file__)
class FooWidget(QtWidgets.QWidget):
def __init__(self, path_icon, text, checked=False, parent=None):
super(FooWidget, self).__init__(parent)
lay = QtWidgets.QVBoxLayout(self)
pixmap = QtGui.QPixmap(os.path.join(iconroot, path_icon))
pixmap_label = QtWidgets.QLabel()
pixmap_label.resize(150, 150)
pixmap_label.setPixmap(pixmap.scaled(pixmap_label.size(), QtCore.Qt.KeepAspectRatio))
text_label = QtWidgets.QLabel(text)
checkbox = QtWidgets.QCheckBox(checked=checked)
lay.addWidget(pixmap_label)
lay.addWidget(text_label)
lay.addWidget(checkbox)
class Grid(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Grid, self).__init__(parent)
lay = QtWidgets.QHBoxLayout(self)
icons = ["images/fixed-fixed.png",
"images/pinned-pinned.png",
"images/fixed-free.png",
"images/fixed-pinned.png"]
texts = ["Ley = 1.0 L\nLec = 1.0 L",
"Ley = 0.699 L\nLec = 0.699 L",
"Ley = 2.0 L\nLec = 2.0 L",
"Ley = 0.5 L\nLec = 0.5 L"]
for path_icon, text in zip(icons, texts):
w = FooWidget(os.path.join(iconroot, path_icon), text)
lay.addWidget(w)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
im = Grid()
im.show()
sys.exit(app.exec_())
Line: vlay.addLayout (self.imagewidget.hlay)
error is: QLayout :: addChildLayout: layout "" already has a parent
Try it:
import sys, os
from PyQt5 import QtCore, QtGui, QtWidgets
iconroot = os.path.dirname(__file__)
class ImageWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ImageWidget, self).__init__(parent)
# self.hlay = QtWidgets.QHBoxLayout(self)
self.hlay = QtWidgets.QHBoxLayout() # < --- -self
buckling_ilabel = QtWidgets.QLabel(self)
pixmap = QtGui.QPixmap(os.path.join(iconroot, "images/logo.png"))
buckling_ilabel.resize(150, 150)
buckling_ilabel.setPixmap(pixmap.scaled(buckling_ilabel.size(), QtCore.Qt.KeepAspectRatio))
self.hlay.addWidget(buckling_ilabel)
buckling_blabel = QtWidgets.QLabel(self)
pixmap = QtGui.QPixmap(os.path.join(iconroot, "images/logo.png"))
buckling_blabel.resize(150, 150)
buckling_blabel.setPixmap(pixmap.scaled(buckling_blabel.size(), QtCore.Qt.KeepAspectRatio))
self.hlay.addWidget(buckling_blabel)
buckling_clabel = QtWidgets.QLabel(self)
pixmap = QtGui.QPixmap(os.path.join(iconroot, "images/logo.png"))
buckling_clabel.resize(150, 150)
buckling_clabel.setPixmap(pixmap.scaled(buckling_clabel.size(), QtCore.Qt.KeepAspectRatio))
self.hlay.addWidget(buckling_clabel)
buckling_dlabel = QtWidgets.QLabel(self)
pixmap = QtGui.QPixmap(os.path.join(iconroot, "images/logo.png"))
buckling_dlabel.resize(150, 150)
buckling_dlabel.setPixmap(pixmap.scaled(buckling_dlabel.size(), QtCore.Qt.KeepAspectRatio))
self.hlay.addWidget(buckling_dlabel)
# self.setLayout(self.hlay) # < ---
class EffLengthInfo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(EffLengthInfo, self).__init__(parent)
ilabel = QtWidgets.QLabel('Ley = 1.0 L\nLec = 1.0 L')
blabel = QtWidgets.QLabel('Ley = 0.699 L\nLec = 0.699 L')
clabel = QtWidgets.QLabel('Ley = 2.0 L\nLec = 2.0 L')
dlabel = QtWidgets.QLabel('Ley = 0.5 L\nLec = 0.5 L')
self.ilay = QtWidgets.QHBoxLayout()
self.ilay.addWidget(ilabel)
self.ilay.addWidget(blabel)
self.ilay.addWidget(clabel)
self.ilay.addWidget(dlabel)
class CheckInfo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(CheckInfo, self).__init__(parent)
icheck = QtWidgets.QCheckBox()
bcheck = QtWidgets.QCheckBox()
ccheck = QtWidgets.QCheckBox()
dcheck = QtWidgets.QCheckBox()
self.checklay = QtWidgets.QHBoxLayout()
self.checklay.addWidget(icheck, alignment=QtCore.Qt.AlignCenter)
self.checklay.addWidget(bcheck, alignment=QtCore.Qt.AlignCenter)
self.checklay.addWidget(ccheck, alignment=QtCore.Qt.AlignCenter)
self.checklay.addWidget(dcheck, alignment=QtCore.Qt.AlignCenter)
class Grid(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Grid, self).__init__(parent)
self.imagewidget = ImageWidget()
self.efflengthinfo = EffLengthInfo()
self.checkinfo = CheckInfo()
vlay = QtWidgets.QVBoxLayout(self)
vlay.addLayout(self.imagewidget.hlay) # < ---
# Error: QLayout::addChildLayout: layout "" already has a parent # < ---
vlay.addLayout(self.efflengthinfo.ilay)
vlay.addLayout(self.checkinfo.checklay)
self.setLayout(vlay)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
im = Grid()
im.show()
sys.exit(app.exec_())
i made aplication and situated objects by GridLabel. i have gray imgae in one the cells. now i want to draw rectangles only on this gray cell. but it drows only under this gray picture, and draw also out of borders of this cell. how i need to write this part of code that its lets me to draw on this gray image and to dont out from its borders?
from PyQt4 import QtGui, QtCore
import sys, os
class Example(QtGui.QWidget):
def __init__(self,parent):
super(Example, self).__init__()
self.main_image_name="main_image.png"
self.mode = 5
self.initUI()
def initUI(self):
File_name = QtGui.QLabel('Setup file name')
File_name_edit = QtGui.QLineEdit()
QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
#QMainWindow.statusBar().showMessage('Ready')
self.setGeometry(300, 300, 250, 150)
self.resize(640, 360)
self.center()
self.main_image = QtGui.QLabel(self)
self.main_image.setPixmap(QtGui.QPixmap(self.main_image_name))
btn = QtGui.QPushButton("Make setup file")
btn.setToolTip('Press <b>Detect</b> button for detecting objects by your settings')
btn.resize(btn.sizeHint())
btn.clicked.connect(QtCore.QCoreApplication.instance().quit)
btn_browse = QtGui.QPushButton("Browse")
btn_browse.clicked.connect(self.browse)
btn_set = QtGui.QPushButton("Set name")
#fullscreen
#self.main_image.setScaledContents(True)
#just centered
self.main_image.setAlignment(QtCore.Qt.AlignCenter)
#Layout
box_File_name = QtGui.QHBoxLayout()
box_File_name.addWidget(File_name)
box_File_name.addWidget(File_name_edit)
box_File_name.addWidget(btn_set)
grid = QtGui.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 = QtGui.QVBoxLayout()
number_group=QtGui.QButtonGroup() # Number group
r0=QtGui.QRadioButton("Traffic Lights")
number_group.addButton(r0)
r1=QtGui.QRadioButton("Direction")
number_group.addButton(r1)
r2=QtGui.QRadioButton("Traffic Lines H")
number_group.addButton(r2)
r3=QtGui.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 = QtGui.QHBoxLayout()
road_sign_label = QtGui.QLabel('Road signs', self)
road_sign = QtGui.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 = QtGui.QWidget()
w.resize(320, 240)
w.setWindowTitle("Select Picture")
filename = QtGui.QFileDialog.getOpenFileName(w, 'Open File', '/')
self.main_image_name = filename
self.main_image.setPixmap(QtGui.QPixmap(self.main_image_name))
def center(self):
qr = self.frameGeometry()
cp = QtGui.QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def radio0_clicked(self, enabled):
if enabled:
print "0"
self.mode=0
def radio1_clicked(self, enabled):
if enabled:
print "1"
self.mode=1
def radio2_clicked(self, enabled):
if enabled:
print "2"
self.mode=2
def radio3_clicked(self, enabled):
if enabled:
print "3"
self.mode=3
def paintEvent( self, event) :
????
class menubarex(QtGui.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 = QtGui.QAction(QtGui.QIcon('exit.png'), '&Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit application')
exitAction.triggered.connect(QtGui.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(QtGui.QIcon('icon.png'))
def closeEvent(self, event):
reply = QtGui.QMessageBox.question(self, 'Message',
"Are you sure to quit?", QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
event.accept()
else:
event.ignore()
def main():
app = QtGui.QApplication(sys.argv)
#ex = Example()
menubar = menubarex()
menubar.show()
sys.exit(app.exec_())
main()
You should write your own Qlabel class:
class myQLabel(QLabel):
def __init__(self,parent=None):
super(myQLabel, self).__init__(parent)
def paintEvent(self, QPaintEvent):
super(myQLabel, self).paintEvent(QPaintEvent)
painter = QPainter(self)
painter.setPen(QPen(Qt.red))
painter.drawArc(QRectF(50, 50, 10, 10), 0, 5760)
painter.drawRect(QRectF(50, 50, 100, 100) )
then use it :
self.main_image = myQLabel(self)
also remove the def paintEvent( self, event) : in the Example class
I use pyqt5 So I change a little the code :
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys, os
class myQLabel(QLabel):
def __init__(self,parent=None):
super(myQLabel, self).__init__(parent)
def paintEvent(self, QPaintEvent):
super(myQLabel, self).paintEvent(QPaintEvent)
painter = QPainter(self)
painter.setPen(QPen(Qt.red))
painter.drawArc(QRectF(50, 50, 10, 10), 0, 5760)
painter.drawRect(QRectF(50, 50, 100, 100) )
class Example(QWidget):
def __init__(self,parent):
super(Example, self).__init__()
self.main_image_name="icons\\add.png"
self.mode = 5
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.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")
self.mode=0
def radio1_clicked(self, enabled):
if enabled:
print("1")
self.mode=1
def radio2_clicked(self, enabled):
if enabled:
print("2")
self.mode=2
def radio3_clicked(self, enabled):
if enabled:
print("3")
self.mode=3
# def paintEvent( self, event) :
# pass
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('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()
which give me :
I have
class View(QtWidgets.QLabel):
def __init__(self):
super(View,self).__init__()
self.cropLabel = QtWidgets.QLabel(self)
self.label = QtWidgets.QLabel(self)
self.ogpixmap = QtGui.QPixmap()
fileName = r'C:/Users/user11.HPO-SAMAT/Pictures/Lake.jpg'
image = QtGui.QImage(fileName)
self.pixmap = QtGui.QPixmap.fromImage(image)
self.label.setPixmap(self.pixmap)
self.label.adjustSize()
and then I call this class:
class Viewer(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.view = View()
self.scroller = QtWidgets.QScrollArea()
self.scroller.setWidget(self.view)
self.scroller.setWidgetResizable(True)
self.scroller.adjustSize()
But QScrollArea does not seem to work (noscrollbar though the image is visible and I can expand QMainWindows to see it entirely)
What am I doing wrong ?
I do not understand so they put several labels inside View, if we remove the labels that are other we get what you want.
class View(QtWidgets.QLabel):
def __init__(self, parent=None):
super(View,self).__init__(parent)
fileName = "/home/qhipa/Pictures/1475777628875.jpg"
self.pixmap = QtGui.QPixmap(fileName)
self.setPixmap(self.pixmap)
class Viewer(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.view = View(self)
self.scroller = QtWidgets.QScrollArea(self)
self.setCentralWidget(self.scroller)
self.scroller.setWidget(self.view)
self.scroller.setWidgetResizable(True)
self.scroller.adjustSize()
Instead if you want to get several labels, it is better that the View class inherits from QWidget.
class View(QtWidgets.QWidget):
def __init__(self, parent=None):
super(View,self).__init__(parent)
self.setLayout(QtWidgets.QVBoxLayout())
self.cropLabel = QtWidgets.QLabel(self)
self.label = QtWidgets.QLabel(self)
self.layout().addWidget(self.cropLabel)
self.layout().addWidget(self.label)
self.pixmap = QtGui.QPixmap("/home/qhipa/Pictures/1475777628875.jpg")
self.label.setPixmap(self.pixmap)
self.label.adjustSize()