PyQt4を使用してPythonで画像上にポリゴンを描画して、アイテムにタグを付けたいと思います。QGraphicsSceneで画像ビューアを実装することはできましたが、オブジェクトのペイント/更新の背後にある概念がわかりません。
私がやりたいのは、追加と編集をサポートするPolygonクラスです。私を混乱させるのはQGraphicsScene.addItem
、さまざまなペイントまたは更新方法です。私が実装したいのは
- 完成していないときに多角形を線として描く
- 完了したら、塗りつぶされたポリゴンとして描画します
アルゴリズムの部分はOKですが、私が理解していないのは、ペイントまたは更新関数をどのように実装するかということです。
これが私の混乱です
元のサンプルファイルには、ペイントgraphicsview/collidingmice
を行う特別な関数があります。def paint(self, painter, option, widget):
paint関数を呼び出す関数がないため、QGraphicsViewによって呼び出される特別な名前だと思いますが、painterとは何か、paint関数は何を実装する必要があるのかわかりません。
一方、多くのオンラインチュートリアルでは、関数を見つけdef paintEvent(self, event):
ました。これは、graphicsview/paintとはまったく異なる概念に従っているようです。
おそらくそれをよりよく説明するために:私にとって、OpenGLがシーンを更新する方法は明確です。ここでは、常にすべてをクリーンアップし、要素を1つずつ再描画します。そこで、あなたはあなたが描きたいアイテムの世話をし、適切なものを描きます。常に最新の状態を描画しているため、更新方法はありません。このQtGUIの方法は私にとって新しいものです。シーンに追加したアイテムはどうなるのか教えてください。シーンに追加されたものを編集するにはどうすればよいですか?常に更新される「ループ」はどこにありますか?
これが可能な限り最小の形式の私のソースです。最初のポリゴンを作成し、そのポイントの印刷を開始します。これまでに、paintメソッドが1回呼び出され(なぜ1回だけ?)、このエラーが発生するようになりまし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()