title: Object-based paint/update in Qt/PyQt4
body: <p>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.</p>
  
  <p>What I'd like to do is a Polygon class, what supports adding and editing. What confuses me is the <code>QGraphicsScene.addItem</code> and the different paint or update methods. What I'd like to implement is to</p>
  
  <ol>
  <li>draw a polygon as lines while not complete</li>
  <li>draw it as a filled polygon once complete</li>
  </ol>
  
  <p>The algorithm part is OK, what I don't understand is that how do I implement the paint or update functions.</p>
  
  <p><em>Here is my confusion</em></p>
  
  <p><strong>In the original example file</strong>: <code>graphicsview/collidingmice</code> there is a special function <code>def paint(self, painter, option, widget):</code> 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.</p>
  
  <p><strong>On the other hand in numerous online tutorials</strong> I find <code>def paintEvent(self, event):</code> functions, what seems to follow a totally different concept compared to the graphicsview / paint. </p>
  
  <p>Maybe to explain it better: for me <strong>the way OpenGL does the scene-update is clear</strong>, 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. <strong>Can you tell me what happens with an item after I've added it to the scene</strong>? How do I <strong>edit something</strong> what has been added to the scene, <strong>where is the always updating 'loop'</strong>?</p>
  
  <p>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 error <code>NotImplementedError: QGraphicsItem.boundingRect() is abstract and must be overridden</code>. (just copy any jpg file as big.jpg)</p>
  
  <pre><code>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()
  </code></pre>