[PyQt] Object-based paint/update in Qt/PyQt4
Zsolt Ero
zsolt.ero at gmail.com
Tue Oct 23 13:49:37 BST 2012
I'd like to tag items by drawing polygons over an image in Python using
PyQt4. I was able to implement the image viewer with QGraphicsScene but I
don't understand the concept behind painting/updating objects.
What I'd like to do is a Polygon class, what supports adding and editing.
What confuses me is theQGraphicsScene.addItem and the different paint or
update methods. What I'd like to implement is to
1. draw a polygon as lines while not complete
2. draw it as a filled polygon once complete
The algorithm part is OK, what I don't understand is that how do I
implement the paint or update functions.
*Here is my confusion*
*In the original example file*: graphicsview/collidingmice there is a
special function def paint(self, painter, option, widget): what does the
painting. There is no function calling the paint function, thus I'd think
it's a special name called by QGraphicsView, but I don't understand what is
a painter and what should a paint function implement.
*On the other hand in numerous online tutorials* I find def
paintEvent(self, event): functions, what seems to follow a totally
different concept compared to the graphicsview / paint.
Maybe to explain it better: for me *the way OpenGL does the scene-update is
clear*, where you always clean everything and re-draw elements one by one.
There you just take care of what items do you want to draw and draw the
appropriate ones. There is no update method, because you are drawing always
the most up-to-date state. This Qt GUI way is new to me. *Can you tell me
what happens with an item after I've added it to the scene*? How do I *edit
something* what has been added to the scene, *where is the always updating
'loop'*?
Here is my source in the smallest possible form, it creates the first
polygon and starts printing it's points. I've arrived so far that the paint
method is called once (why only once?) and there is this
errorNotImplementedError:
QGraphicsItem.boundingRect() is abstract and must be overridden. (just copy
any jpg file as big.jpg)
Thanks, Zsolt
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()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20121023/fa328c3f/attachment-0001.html>
More information about the PyQt
mailing list