使用paintEvent在QLabel中绘画 [英] Painting in a QLabel with paintEvent

查看:45
本文介绍了使用paintEvent在QLabel中绘画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在某个标签中绘制一个矩形,我使用 QtDesigner 制作了一个 GUI,该 GUI 在一个名为class Ui_MainWindow(QMainWindow):"的类中生成整个 GUI 代码,并且我在我的窗口中使用了三个选项卡.

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

from PyQt5 import QtCore, QtGui, QtWidgets从 PyQt5.QtCore 导入 Qt导入系统导入 cv2从 PyQt5.QtWidgets 导入 QMainWindow、QWidget、QLabel从 PyQt5.QtGui 导入 QPixmap、QImage类 Ui_MainWindow(QMainWindow):def __init__(self):# super(Ui_MainWindow, self).__init__()super().__init__()self.count = 0self.frame = 0self.fileName="0"self.imagesTab2 = []自我.k = 0self.i = 1自我.w = 0自我.h = 0self.coordPt = []self.dictListClasses = {脸" :[],车" : [] }self.dictColorClasses = {脸" :(0, 100, 255),汽车":(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.horizo​​ntalLayout = QtWidgets.QHBoxLayout()self.horizo​​ntalLayout.setObjectName("horizo​​ntalLayout")self.pushButton = QtWidgets.QPushButton(self.tab)self.pushButton.setObjectName("pushButton")self.horizo​​ntalLayout.addWidget(self.pushButton)self.verticalLayout_2.addLayout(self.horizo​​ntalLayout)self.label = QtWidgets.QLabel(self.tab)self.label.setText("")self.label.setObjectName("标签")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.translateMainWindow.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):如果 self.imagesTab2:如果 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)]打印(坐标点击=,self.coordPt)self.begin = e.pos()self.end = e.pos()self.label.update()打印(开始1 =,self.begin,self.end)def subWidgetMouseMoveEvent(e: QtGui.QMouseEvent):如果 self.imagesTab2:self.end = e.pos()self.label.update()def subWidgetMouseReleaseEvent(e: QtGui.QMouseEvent):如果 e.button() == Qt.LeftButton:如果 self.imagesTab2:如果 e.x() >= 0 且 e.y() >= 0 且 e.x()

上面的代码是重写三个函数:mousePressEvent、mouseReleaseEvent 和 mouseMoveEvent因为如果我只使用 def mouseMoveEvent (self, event): 例如,它在我的标签上不起作用我不知道如何将它设置为在某个标签上工作

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

谁能帮助我像这段代码一样使用我标签上的事件,谢谢

导入系统从 PyQt5.QtWidgets 导入 *从 PyQt5.QtGui 导入 QPainter、QColor、QBrush从 PyQt5 导入 QtWidgets、QtCore、QtGui类标签(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()defpaintEvent(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()自我更新()print("beegin = ", self.begin)print("end 1 = ", self.end)def mouseMoveEvent(self, event):self.end = event.pos()自我更新()def mouseReleaseEvent(self, event):self.begin = event.pos()self.end = event.pos()自我更新()def drawRectangles(self, qp):qp.setBrush(QColor(255, 0, 0, 100))qp.save() # 保存 QPainter 配置qp.drawRect(10, 15, 20, 20)qp.setBrush(QColor(0, 0, 255, 100))qp.drawRect(50, 15, 20, 20)qp.restore() # 恢复 QPainter 配置qp.drawRect(100, 15, 20, 20)类示例(QWidget):def __init__(self):super().__init__()磅 = 标签(自己)self.setGeometry(300, 300, 350, 300)self.setWindowTitle('颜色')自我展示()如果 __name__ == '__main__':app = QApplication(sys.argv)ex = 示例()sys.exit(app.exec_())

解决方案

解决方案是将 Labella 推广到 Qt Designer 中使用,为此您必须首先创建文件 labella.py.

labella.py

from PyQt5 import QtCore, QtGui, QtWidgets类标签(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()defpaintEvent(self, event):super().paintEvent(事件)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()自我更新()print("beegin = ", self.begin)print("end 1 = ", self.end)def mouseMoveEvent(self, event):self.end = event.pos()自我更新()def drawRectangles(self, qp):qp.setBrush(QColor(255, 0, 0, 100))qp.save() # 保存 QPainter 配置qp.drawRect(10, 15, 20, 20)qp.setBrush(QColor(0, 0, 255, 100))qp.drawRect(50, 15, 20, 20)qp.restore() # 恢复 QPainter 配置qp.drawRect(100, 15, 20, 20)

然后我们将 labella.py 和将调用 mainwindow.ui

的 .ui 放在同一个文件夹中<预><代码>.├── labella.py└── mainwindow.ui

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

QLabel 上右键单击并选择选项:Promote to ...

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

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

pyuic5 mainwindow.ui -o mainwindow.py -x

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

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)

Then we place in the same folder the labella.py and the .ui that will call mainwindow.ui

.
├── labella.py
└── 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 the Promote button:

and finally generate the .py again with the help of pyuic5:

pyuic5 mainwindow.ui -o mainwindow.py -x

这篇关于使用paintEvent在QLabel中绘画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆