使用Python,PYQT5,我想在Qlabel小部件中的图像上方绘制多边形。我使用了一个简单的Qmainwindow,它带有在QT设计器中生成的标签小部件(下面的代码)。
我知道在Qmainwindow中有一些关于abaut绘图的信息,如下所示:
PyQT5: How to interactively paint on image within QLabel Widget?-在Qlabel小部件中没有解决方案。
Draw over image in a QLabel with PyQt5-标记的解决方案尚不清楚,因为还无法解决在Qlabel上的绘制
[PYQT5 drawing line-Qlabel上的paintevent正在运行,但不在图像顶部
Painting in a QLabel with paintEvent-但也无法解决在图像上方绘制的问题。
让我知道,如果您有解决此问题的方法。
import sys
from PyQt5.QtCore import Qt
from PyQt5 import QtWidgets, uic, QtCore, QtGui
from PyQt5.QtGui import QPixmap, QPainter, QPolygon, QPen, QBrush
from PyQt5.QtCore import QPoint
from polygon_ui import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, obj=None, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.setupUi(self)
pixmap = QPixmap("img.png")
self.label.setPixmap(pixmap)
self.label.mousePressEvent = self.getPixel
self.pol = []
def getPixel(self, event):
x = event.pos().x()
y = event.pos().y()
self.pol.append(QPoint(int(x),int(y)))
print(x,y, self.pol)
def paintEvent(self, event):
painter = QPainter(self)
#painter.drawPixmap(self.rect(), self.image)
painter.setPen(QPen(Qt.black, 5, Qt.SolidLine))
painter.setBrush(QBrush(Qt.red, Qt.VerPattern))
#points = QPolygon([ QPoint(10,10), QPoint(10,100),
# QPoint(100,10), QPoint(100,100)])
points = QPolygon(self.pol)
painter.drawPolygon(points)
def mouseMoveEvent(self, event):
pass
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
polygon_ui的代码在这里-只是由QT-Designer使用Mainwindow + Qlabel生成的:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(621, 641)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(10, 10, 600, 600))
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 621, 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)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "TextLabel"))
如果要在图像上添加诸如多边形,直线,圆形等元素,则不要使QLabel复杂化,因为例如,使用当前代码,您将在以下窗口中绘画QLabel,所以它不会被看到,与QLabel一起使用的可能解决方案是获取QPixmap并将其绘制在顶部。
[一个更好的选择是使用Qt Graphics Framework,其中将图像设置为QGraphicsPixmapItem,并将多边形设置为QGraphicsPixmapItem的子项,如下所示:
from PyQt5 import QtCore, QtGui, QtWidgets
class GraphicsView(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
scene = QtWidgets.QGraphicsScene(self)
self.setScene(scene)
self._pixmap_item = QtWidgets.QGraphicsPixmapItem()
scene.addItem(self.pixmap_item)
self._polygon_item = QtWidgets.QGraphicsPolygonItem(self.pixmap_item)
self.polygon_item.setPen(QtGui.QPen(QtCore.Qt.black, 5, QtCore.Qt.SolidLine))
self.polygon_item.setBrush(QtGui.QBrush(QtCore.Qt.red, QtCore.Qt.VerPattern))
@property
def pixmap_item(self):
return self._pixmap_item
@property
def polygon_item(self):
return self._polygon_item
def setPixmap(self, pixmap):
self.pixmap_item.setPixmap(pixmap)
def resizeEvent(self, event):
self.fitInView(self.pixmap_item, QtCore.Qt.KeepAspectRatio)
super().resizeEvent(event)
def mousePressEvent(self, event):
sp = self.mapToScene(event.pos())
lp = self.pixmap_item.mapFromScene(sp)
poly = self.polygon_item.polygon()
poly.append(lp)
self.polygon_item.setPolygon(poly)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
view = GraphicsView()
self.setCentralWidget(view)
view.setPixmap(QtGui.QPixmap("img.png"))
self.resize(640, 480)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
更新:
如果要使用OP设计,则实现起来很简单:
创建一个名为graphicsview.py的文件,在其中实现GraphicsView逻辑:
graphicsview.py
from PyQt5 import QtCore, QtGui, QtWidgets
class GraphicsView(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
scene = QtWidgets.QGraphicsScene(self)
self.setScene(scene)
self._pixmap_item = QtWidgets.QGraphicsPixmapItem()
scene.addItem(self.pixmap_item)
self._polygon_item = QtWidgets.QGraphicsPolygonItem(self.pixmap_item)
self.polygon_item.setPen(QtGui.QPen(QtCore.Qt.black, 5, QtCore.Qt.SolidLine))
self.polygon_item.setBrush(QtGui.QBrush(QtCore.Qt.red, QtCore.Qt.VerPattern))
@property
def pixmap_item(self):
return self._pixmap_item
@property
def polygon_item(self):
return self._polygon_item
def setPixmap(self, pixmap):
self.pixmap_item.setPixmap(pixmap)
def resizeEvent(self, event):
self.fitInView(self.pixmap_item, QtCore.Qt.KeepAspectRatio)
super().resizeEvent(event)
def mousePressEvent(self, event):
sp = self.mapToScene(event.pos())
lp = self.pixmap_item.mapFromScene(sp)
poly = self.polygon_item.polygon()
poly.append(lp)
self.polygon_item.setPolygon(poly)
用QGraphicsView在Polygon_ui中替换QLabel:
polygon_ui.py
from PyQt5 import QtCore, QtGui, QtWidgets
from graphicsview import GraphicsView
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(621, 641)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = GraphicsView(self.centralwidget)
self.label.setGeometry(QtCore.QRect(10, 10, 600, 600))
self.label.setObjectName("label")
# ...
还原main.py
main.py
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from polygon_ui import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, obj=None, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.setupUi(self)
pixmap = QtGui.QPixmap("img.png")
self.label.setPixmap(pixmap)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
另一种方法是升级窗口小部件,因此在这种类型中有很多示例,因此我省去了显示过程:
另一个更简单的选择是使用QLabel作为容器,并使用布局设置GraphicsView:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from polygon_ui import Ui_MainWindow
class GraphicsView(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
scene = QtWidgets.QGraphicsScene(self)
self.setScene(scene)
self._pixmap_item = QtWidgets.QGraphicsPixmapItem()
scene.addItem(self.pixmap_item)
self._polygon_item = QtWidgets.QGraphicsPolygonItem(self.pixmap_item)
self.polygon_item.setPen(QtGui.QPen(QtCore.Qt.black, 5, QtCore.Qt.SolidLine))
self.polygon_item.setBrush(QtGui.QBrush(QtCore.Qt.red, QtCore.Qt.VerPattern))
@property
def pixmap_item(self):
return self._pixmap_item
@property
def polygon_item(self):
return self._polygon_item
def setPixmap(self, pixmap):
self.pixmap_item.setPixmap(pixmap)
def resizeEvent(self, event):
self.fitInView(self.pixmap_item, QtCore.Qt.KeepAspectRatio)
super().resizeEvent(event)
def mousePressEvent(self, event):
sp = self.mapToScene(event.pos())
lp = self.pixmap_item.mapFromScene(sp)
poly = self.polygon_item.polygon()
poly.append(lp)
self.polygon_item.setPolygon(poly)
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, obj=None, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.setupUi(self)
self.graphicsview = GraphicsView()
lay = QtWidgets.QVBoxLayout(self.label)
lay.addWiget(self.graphicsview)
pixmap = QtGui.QPixmap("img.png")
self.graphicsview.setPixmap(pixmap)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())