使用paintEvent在QLabel中绘画

时间:2018-08-09 13:24:37

标签: python pyqt pyqt5 qt-designer qlabel

我想在一个特定的标签上绘制一个矩形,我用QtDesigner制作了一个GUI,它在一个名为“ Ui_MainWindow(QMainWindow)类:”的类中生成了整个GUI代码,并且我在窗口中使用了三个选项卡。 >

我在标签上使用QMouseEvent时遇到问题,我找到了使用此代码的解决方案

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_())

上面的代码将覆盖这三个功能: mousePressEvent,mouseReleaseEvent和mouseMoveEvent 因为例如如果我仅使用def mouseMoveEvent (self, event):,它就不能在我的标签上使用,我也不知道如何设置它以在特定标签上使用

所以我尝试覆盖QPaintEvent函数,但是如果我使用上面的代码并使用此setQWidget.paintEvent = subWidgetPaintEvent,则标签消失,我只能找到一个矩形

任何人都可以像下面的代码一样帮助我使用我标签上的事件,谢谢

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_())

1 个答案:

答案 0 :(得分:1)

解决方案是将Labella升级为在Qt Designer中使用,为此,您必须首先创建文件labella.py。

labella.py

from PyQt5 import QtCore, QtGui, QtWidgets

class Labella(QtWidgets.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):
        super().paintEvent(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 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)

然后我们将labella.py和.ui放在同一文件夹中,它们将调用mainwindow.ui

.
├── labella.py
└── mainwindow.ui

通过获取以下内容来打开.ui文件:

enter image description here

QLabel上单击鼠标右键,然后选择以下选项: Promote to ...

enter image description here

填写下图所示的字段,然后按Add按钮,然后按Promote按钮:

enter image description here

,最后在pyuic5的帮助下再次生成.py:

pyuic5 mainwindow.ui -o mainwindow.py -x

enter image description here