title: pyqt - error while running, probably wrong paintevent method implementation
body: <p>Me and my colleagues are writing a data processing application in python.
  We are currently working on the frontend part of the application.</p>
  
  <p>We have a big problem though, that's that the application gets the following error after a random amount of time:</p>
  
  <pre><code>QWidget::repaint: Recursive repaint detected
  </code></pre>
  
  <p>This one also pops up from time to time:</p>
  
  <pre><code>QPainter::begin: Paint device returned engine == 0, type: 1
  </code></pre>
  
  <p>This is the file where all gui related stuff happens, I cut out the irrelevant methods for the sake of not being to lengthy:</p>
  
  <p>gfx.py:</p>
  
  <pre><code>import sys, random, math
  
  from PyQt4 import QtGui, QtCore
  from random import randrange
  
  from eventbased import listener
  
  app = QtGui.QApplication(sys.argv)
  
  def exec():
      return app.exec_()
  
  class MapView(QtGui.QMainWindow, listener.Listener):
      def __init__(self, mapimagepath = 0, nodes = 0):
  
          QtGui.QMainWindow.__init__(self)
          listener.Listener.__init__(self)
  
  
          self.setWindowTitle('Population mapping')
          self.map = Map(self, mapimagepath)
  
          self.setCentralWidget(self.map)
  
          self.map.start()
          self.center()
  
  
      def center(self):
          screen = QtGui.QDesktopWidget().screenGeometry()
          size = self.geometry()
          self.move(50, 0)
  
  
      def handle(self, event):
          if(event.type == 0):
              self.map.addNode(event.object.scanner)
          if(event.type == 1):
              self.map.delNode(event.object.scanner)
          if(event.type == 2):
              self.map.addBranch(event.object.node1.scanner, event.object.node2.scanner)
          if(event.type == 3):
              self.map.delBranch(event.object.node1.scanner, event.object.node2.scanner)
          if(event.type == 4):
              self.map.changeNode(event.object.scanner.sensorid, event.result)
          if(event.type == 5):
              self.map.changeBranch(event.object.node1.scanner.sensorid, event.object.node2.scanner.sensorid, event.result)
  
  
          self.repaint(self.map.contentsRect())
          self.update(self.map.contentsRect())
  
  
  
  ######################################################################
  
  class Map(QtGui.QFrame):
  
      def __init__(self, parent, mapimagepath):
          QtGui.QFrame.__init__(self, parent)
  
          #self.timer = QtCore.QBasicTimer()
  
          #coordinaten hoeken NE en SW voor kaart in map graphics van SKO 
          self.realmap = RealMap( 
              mapimagepath,
              (51.0442, 3.7268), 
              (51.0405, 3.7242),
              550, 
              800)
  
          parent.setGeometry(0,0,self.realmap.width, self.realmap.height)
          self.refreshspeed = 5000
  
          self.mapNodes = {}
  
      def addNode(self, scanner):
          coord = self.realmap.convertLatLon2Pix((scanner.latitude, scanner.longitude))
  
          self.mapNodes[scanner.sensorid] = MapNode(scanner, coord[0], coord[1])
  
      # type: 4 --&gt; changenode    ,   
      #((change, gem_ref, procentuele verandering ref), scanner object)
      def changeNode(self, sensorid, branchdata):
          self.mapNodes[sensorid].calcDanger(branchdata[2])
  
      def paintEvent(self, event):
  
          painter = QtGui.QPainter(self)
          rect = self.contentsRect()
  
          #teken achtergrond
          self.realmap.drawRealMap(painter)
  
          #teken nodes
          for sensorid, mapNode in self.mapNodes.items():
              mapNode.drawMapNode(painter, self.realmap)
  
  
  ######################################################################
  
  class RealMap:
      def __init__(self, path, coordRightTop, 
          coordLeftBot, width, height, pixpermet = 2.6):
  
          self.path = path
          self.coordLeftBot = coordLeftBot
          self.coordRightTop = coordRightTop
  
          self.width = width
          self.height = height
  
          self.realdim = self.calcRealDim()
  
          self.pixpermet = pixpermet
  
      def drawRealMap(self, painter):
          image = QtGui.QImage(self.path)
          painter.drawImage(0,0,image)
  
  
  ######################################################################
  
  class MapNode:
      dangertocolor = {"normal":"graphics//gradients//green.png",
                      "elevated":"graphics//gradients//orange.png",
                      "danger":"graphics//gradients//red.png"}
  
      def __init__(self, scanner, x, y, danger = 0):
          self.scanner = scanner
          self.x = x
          self.y = y
          self.danger = 'normal'
  
          self.calcDanger(danger)
  
      def drawMapNode(self, painter, realmap):
          radiusm = self.scanner.range
          radiusp = radiusm*realmap.pixpermet
          factor = radiusp/200        # basis grootte gradiënten is 200 pixels.
  
          icon = QtGui.QImage("graphics//BT-icon.png")
  
          grad = QtGui.QImage(MapNode.dangertocolor[self.danger])
          grad = grad.scaled(grad.size().width()*factor, grad.size().height()*factor)
  
  
          painter.drawImage(self.x-100*factor,self.y-100*factor, grad)
          painter.drawImage(self.x-10, self.y-10,icon)
          painter.drawText(self.x-15, self.y+20, str(self.scanner.sensorid) + '-' + str(self.scanner.name))
  </code></pre>
  
  <p>An object is made through our application class:</p>
  
  <pre><code>    mapview = gfx.MapView(g_image)
      mapview.show()
  </code></pre>
  
  <p>So the first question is. What are we doing wrong in the paintEvent method?</p>
  
  <p><strong>Secondly question</strong>
  Is there a way to make the paintevent not be called at EVERY RANDOM THING that happens ? (like mouseovers, etc)?</p>
  
  <p>I tried something like:</p>
  
  <pre><code>def paintEvent(self, event):
      if(isinstance(event, QtGui.QPaintEvent)):
  
          painter = QtGui.QPainter(self)
          rect = self.contentsRect()
  
          #teken achtergrond
          self.realmap.drawRealMap(painter)
  
          #teken nodes
          for sensorid, mapNode in self.mapNodes.items():
               mapNode.drawMapNode(painter, self.realmap)
      else:
          pass
  </code></pre>
  
  <p>This 'works' but is to general I guess.. It actually makes the error appear a lot faster then without the conditional.</p>