I want to paint a rectangle in a certain label, I made a GUI with QtDesigner that generates the whole GUI code in one class called "class Ui_MainWindow(QMainWindow):" and I am using three tabs in my window.
I had a problem using the QMouseEvent on my labels, I found a solution using this code
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
import sys
import cv2
from PyQt5.QtWidgets import QMainWindow, QWidget, QLabel
from PyQt5.QtGui import QPixmap, QImage
class Ui_MainWindow(QMainWindow):
def __init__(self):
# super(Ui_MainWindow, self).__init__ ()
super().__init__()
self.count = 0
self.frame = 0
self.fileName="0"
self.imagesTab2 = []
self.k = 0
self.i = 1
self.w = 0
self.h = 0
self.coordPt = []
self.dictListClasses = {
"face" :[],
"car" : [] }
self.dictColorClasses = {
"face" :(0, 100, 255),
"car" : (0,255, 0) }
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(655, 364)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
self.tabWidget.setObjectName("tabWidget")
self.tab = QtWidgets.QWidget()
self.tab.setObjectName("tab")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tab)
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton = QtWidgets.QPushButton(self.tab)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.verticalLayout_2.addLayout(self.horizontalLayout)
self.label = QtWidgets.QLabel(self.tab)
self.label.setText("")
self.label.setObjectName("label")
self.label.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.label.setFrameShadow(QtWidgets.QFrame.Sunken)
self.setMouseEventDelegate(self.label)
self.verticalLayout_2.addWidget(self.label)
self.verticalLayout_2.setStretch(1, 1)
self.tabWidget.addTab(self.tab, "")
self.tab_2 = QtWidgets.QWidget()
self.tab_2.setObjectName("tab_2")
self.tabWidget.addTab(self.tab_2, "")
self.verticalLayout.addWidget(self.tabWidget)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 655, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.tabWidget.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Open"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Tab 1"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Tab 2"))
self.pushButton.clicked.connect(self.openFileTab2)
def setMouseEventDelegate (self, setQWidget):
def subWidgetMousePressEvent(e: QtGui.QMouseEvent):
if self.imagesTab2:
if e.button() == Qt.LeftButton:
po = int(e.x()*self.w/self.label.width())
pa = int(e.y()*self.h/self.label.height())
self.coordPt = [(po, pa)]
print("coords click = ", self.coordPt)
self.begin = e.pos()
self.end = e.pos()
self.label.update()
print("begin 1= ",self.begin, self.end)
def subWidgetMouseMoveEvent(e: QtGui.QMouseEvent):
if self.imagesTab2:
self.end = e.pos()
self.label.update()
def subWidgetMouseReleaseEvent(e: QtGui.QMouseEvent):
if e.button() == Qt.LeftButton:
if self.imagesTab2:
if e.x() >= 0 and e.y() >= 0 and e.x()<self.label.width() and e.y()<self.label.height():
po = int(e.x()*self.w/self.label.width())
pa = int(e.y()*self.h/self.label.height())
self.coordPt.append((po, pa))
print("coords release = ", self.coordPt)
self.begin = e.pos()
self.end = e.pos()
self.label.update()
print("begin 2= ",self.begin, self.end)
self.dictListClasses["car"].append(self.coordPt)
print("LL + ", self.dictListClasses)
setQWidget.mousePressEvent = subWidgetMousePressEvent
setQWidget.mouseReleaseEvent = subWidgetMouseReleaseEvent
setQWidget.mouseMoveEvent = subWidgetMouseMoveEvent
def openFileTab2(self):
self.imagesTab2, _ = QtWidgets.QFileDialog.getOpenFileNames(None,"Select one or more images to open", "/Images","Images (*.jpg *.jpeg .*bmp .*png);;All Files (*)")
if self.imagesTab2:
self.showImageInLabel(self.imagesTab2[0])
# self.label_9.setText("Image 1")
def showImageInLabel(self, img):
pix = QPixmap(img)
self.w = pix.width()
self.h = pix.height()
print("Image resolution = ", '(',self.w,')', '(',self.h,')')
pix = pix.scaled(self.size(), aspectRatioMode=QtCore.Qt.KeepAspectRatio, ) # To scale image for example and keep its Aspect Ration
self.label.setPixmap(pix)
self.label.setScaledContents(True)
def nextImageTab2(self):
if not self.imagesTab2:
print("No files, please open one or more images")
return
if self.i < len(self.imagesTab2):
path = self.imagesTab2[self.i]
self.showImageInLabel(path)
self.i += 1
print(self.i)
x = "Image " + str(self.i)
# self.label_9.setText(x)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
The code above is to override the three functions :
mousePressEvent, mouseReleaseEvent and mouseMoveEvent
because if I use only def mouseMoveEvent (self, event):
for example, it doesn't work on my label I don't know how to set it to work on a certain label
So I tried to override the QPaintEvent function but if I use the code like above and use this setQWidget.paintEvent = subWidgetPaintEvent
the label disappears and i find only a rectangle
Can anyone helps me to use the events on my Label like in this code and thanks
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPainter, QColor, QBrush
from PyQt5 import QtWidgets, QtCore, QtGui
class Labella(QLabel):
def __init__(self, parent):
super().__init__(parent=parent)
self.setStyleSheet('QFrame {background-color:white;}')
self.resize(300, 300)
self.begin = QtCore.QPoint()
self.end = QtCore.QPoint()
def paintEvent(self, event):
qp = QtGui.QPainter(self)
br = QtGui.QBrush(QtGui.QColor(100, 10, 10, 40))
qp.setBrush(br)
qp.drawRect(QtCore.QRect(self.begin, self.end))
def mousePressEvent(self, event):
self.begin = event.pos()
self.end = event.pos()
self.update()
print("beegin = ", self.begin)
print("end 1 = ", self.end)
def mouseMoveEvent(self, event):
self.end = event.pos()
self.update()
def mouseReleaseEvent(self, event):
self.begin = event.pos()
self.end = event.pos()
self.update()
def drawRectangles(self, qp):
qp.setBrush(QColor(255, 0, 0, 100))
qp.save() # save the QPainter config
qp.drawRect(10, 15, 20, 20)
qp.setBrush(QColor(0, 0, 255, 100))
qp.drawRect(50, 15, 20, 20)
qp.restore() # restore the QPainter config
qp.drawRect(100, 15, 20, 20)
class Example(QWidget):
def __init__(self):
super().__init__()
lb = Labella(self)
self.setGeometry(300, 300, 350, 300)
self.setWindowTitle('Colours')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
The solution is to promote the Labella to be used in Qt Designer, for this you must first create the file labella.py.
labella.py
Then we place in the same folder the labella.py and the .ui that will call
mainwindow.ui
You open the .ui file by obtaining the following:
Press the right click on the
QLabel
and select the option: Promote to ...Fill in the fields as shown in the following image, then press the
Add
button and then thePromote
button:and finally generate the .py again with the help of pyuic5: