使用paintEvent在QLabel中绘画 [英] Painting in a QLabel with paintEvent
问题描述
我想在某个标签中绘制一个矩形,我使用 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.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("标签")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 文件:
在 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屋!