首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用QLabel和paintEvent作画

用QLabel和paintEvent作画
EN

Stack Overflow用户
提问于 2018-08-09 13:24:36
回答 1查看 3K关注 0票数 1

我想在某个标签中画一个矩形,我用QtDesigner制作了一个图形用户界面,它在一个名为"class Ui_MainWindow(QMainWindow):“的类中生成整个GUI代码,我在窗口中使用了三个选项卡。

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

代码语言:javascript
复制
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,标签就消失了,我只找到一个矩形。

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

代码语言:javascript
复制
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_())
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-09 17:13:16

解决方案是推广在Qt设计器中使用的Labella,为此您必须首先创建文件labella.py。

labella.py

代码语言:javascript
复制
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放在同一个文件夹中。

代码语言:javascript
复制
.
├── labella.py
└── mainwindow.ui

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

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

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

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

代码语言:javascript
复制
pyuic5 mainwindow.ui -o mainwindow.py -x

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51768266

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档