我想通过使用 PyQt4 在 Python 中的图像上绘制多边形来标记项目。我能够使用 QGraphicsScene 实现图像查看器,但我不理解绘画/更新对象背后的概念。
我想做的是一个多边形类,它支持添加和编辑。让我感到困惑的是QGraphicsScene.addItem
不同的绘制或更新方法。我想实现的是
- 在不完整的情况下将多边形绘制为线
- 完成后将其绘制为填充多边形
算法部分还可以,我不明白的是如何实现绘制或更新功能。
这是我的困惑
在原始示例文件中:graphicsview/collidingmice
有一个特殊的函数def paint(self, painter, option, widget):
是什么画。没有调用paint函数的函数,因此我认为它是QGraphicsView调用的特殊名称,但我不明白什么是painter以及paint函数应该实现什么。
另一方面,在众多在线教程中,我发现def paintEvent(self, event):
函数与图形视图/绘制相比似乎遵循完全不同的概念。
也许更好地解释一下:对我来说,OpenGL 进行场景更新的方式很清楚,您总是清理所有内容并一一重新绘制元素。在那里,您只需处理要绘制的项目并绘制适当的项目。没有更新方法,因为您总是在绘制最新状态。这种 Qt GUI 方式对我来说是新的。你能告诉我将一个项目添加到场景后会发生什么吗?如何编辑已添加到场景中的内容,始终更新的“循环”在哪里?
这是我的最小可能形式的来源,它创建了第一个多边形并开始打印它的点。到目前为止,我已经调用了一次绘制方法(为什么只调用一次?)并且有这个错误NotImplementedError: QGraphicsItem.boundingRect() is abstract and must be overridden
。(只需将任何 jpg 文件复制为 big.jpg)
from __future__ import division
import sys
from PyQt4 import QtCore, QtGui
class Polygon( QtGui.QGraphicsItem ):
def __init__(self):
super(Polygon, self).__init__()
self.points = []
self.closed = False
def addpoint( self, point ):
self.points.append( point )
print self.points
def paint(self, painter, option, widget):
print "paint"
class MainWidget(QtGui.QWidget):
poly_drawing = False
def __init__(self):
super(MainWidget, self).__init__()
self.initUI()
def initUI(self):
self.scene = QtGui.QGraphicsScene()
self.img = QtGui.QPixmap( 'big.jpg' )
self.view = QtGui.QGraphicsView( self.scene )
self.view.setRenderHint(QtGui.QPainter.Antialiasing)
self.view.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.pixmap_item = QtGui.QGraphicsPixmapItem( self.img, None, self.scene)
self.pixmap_item.mousePressEvent = self.pixelSelect
self.mypoly = Polygon()
layout = QtGui.QVBoxLayout()
layout.addWidget( self.view )
self.setLayout( layout )
self.resize( 900, 600 )
self.show()
def resizeEvent(self, event):
w_scale = ( self.view.width() ) / self.img.width()
h_scale = ( self.view.height() ) / self.img.height()
self.scale = min( w_scale, h_scale)
self.view.resetMatrix()
self.view.scale( self.scale, self.scale )
def pixelSelect(self, event):
if not self.poly_drawing:
self.poly_drawing = True
self.mypoly = Polygon()
self.scene.addItem( self.mypoly )
point = event.pos()
self.mypoly.addpoint( point )
def main():
app = QtGui.QApplication(sys.argv)
ex = MainWidget()
sys.exit(app.exec_())
if __name__ == '__main__':
main()