使用 PyQt5 在 QLabel 中绘制图像
Posted
技术标签:
【中文标题】使用 PyQt5 在 QLabel 中绘制图像【英文标题】:Draw over image in a QLabel with PyQt5 【发布时间】:2019-04-15 12:35:44 【问题描述】:我想用鼠标在图像上绘制。 我通过这段代码简化了问题。 当我取消注释第 31 行时,代码不起作用。 我的目标是在我想从我的电脑中选择的图像上绘制并在修改后保存图像。
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(QtWidgets.QMainWindow):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(581, 463)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.selectImgeBtn = QtWidgets.QPushButton(self.centralwidget)
self.selectImgeBtn.setGeometry(QtCore.QRect(50, 80, 121, 61))
font = QtGui.QFont()
font.setFamily("Roboto")
font.setPointSize(11)
self.selectImgeBtn.setFont(font)
self.selectImgeBtn.setObjectName("selectImgeBtn")
self.drawing = False
self.brushSize = 2
self.brushColor = QtCore.Qt.black
self.lastPoint = QtCore.QPoint()
self.imageLb = QtWidgets.QLabel(self.centralwidget)
self.imageLb.setGeometry(QtCore.QRect(210, 10, 331, 201))
self.imageLb.setFrameShape(QtWidgets.QFrame.Box)
self.imageLb.setText("")
self.imageLb.setObjectName("imageLb")
self.imageLb.mousePressEvent = self.mousePressEvent
self.imageLb.mouseMoveEvent = self.mouseMoveEvent
self.imageLb.mouseReleaseEvent = self.mouseReleaseEvent
# self.imageLb.paintEvent = self.paintEvent # When i uncomment this line the program is broken
self.selectImgeBtn.clicked.connect(self.setImage)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.selectImgeBtn.setText(_translate("MainWindow", "Select Image"))
def setImage(self):
fileName, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image", "", "Image Files (*.png *.jpg *.jpeg *.bmp)")
if fileName:
pixmap = QtGui.QPixmap(fileName)
pixmap = pixmap.scaled(self.imageLb.width(), self.imageLb.height(), QtCore.Qt.KeepAspectRatio)
self.imageLb.setPixmap(pixmap)
self.imageLb.setAlignment(QtCore.Qt.AlignCenter)
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.drawing = True
self.lastPoint = event.pos()
print(self.lastPoint)
def mouseMoveEvent(self, event):
if (event.buttons() == QtCore.Qt.LeftButton) and self.drawing:
painter = QtGui.QPainter(self.imageLb)
painter.setPen(QtGui.QPen(self.brushColor, self.brushSize, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
painter.drawLine(self.lastPoint, event.pos())
self.lastPoint = event.pos()
self.imageLb.update()
def mouseReleaseEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.drawing = False
def paintEvent(self, event):
canvasPainter = QtGui.QPainter(self)
canvasPainter.drawImage(self.rect(), self.imageLb, self.imageLb.rect())
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_())
【问题讨论】:
【参考方案1】:不要在paintEvent()
之外的小部件内绘制。 Qt 不支持此功能。
您可以改为在QImage
或QPixmap
上绘制,然后在小部件的paintEvent()
中绘制该图像。如果您想合成多张图像(背景+绘图)而不是直接在背景上绘图,也可以将图像初始化为所有像素透明。
【讨论】:
感谢您的回答,我是 PyQt5 的新手,这是我的第二天,所以我不明白该怎么做,但我会尝试。【参考方案2】:我认为最适合您的方法是使用 QLabel 查看图像并使用 OpenCV 通过这些事件在图像上绘制。问题是您需要在每次更改后刷新图像。我在这个项目project 中做到了,它正在工作,但如果你使用 QT 库可能会更好。
【讨论】:
感谢您的回答,您的项目很棒。我将使用 OpenCV 完成一些任务,但现在我正在尝试使用 QT 库进行绘制。以上是关于使用 PyQt5 在 QLabel 中绘制图像的主要内容,如果未能解决你的问题,请参考以下文章