title: Animated Progress Bars in QTableView - how?
body: <p>I have a QTableView in which I want to draw a column with progress bars.<br>
  I considered the Qt Torrent example application and re-implemented the paint() function of the QStyledItemDelegate like this:</p>
  
  <pre><code>def paint(self, painter, option, index):
      if index.column() == 1:
  
          progressBar = QtGui.QStyleOptionProgressBarV2()
          progressBar.state = QtGui.QStyle.State_Enabled
          progressBar.direction = QtGui.QApplication.layoutDirection()
          progressBar.rect = option.rect
          progressBar.fontMetrics = QtGui.QApplication.fontMetrics()
          progressBar.minimum = 0
          progressBar.maximum = 100
          progressBar.textAlignment = QtCore.Qt.AlignCenter
          progressBar.textVisible = True
  
          progressBar.progress = 20 # for testing
  
          QtGui.QApplication.style().drawControl(QtGui.QStyle.CE_ProgressBar, progressBar, painter)
  
      return super(progressBarDelegate, self).paint(painter, option, index)
  </code></pre>
  
  <p>However, this gave me a column of greyed-out progress bars - with no animation.  <a href="http://www.bonhardapple.com/shared-with-others/delegated-style.png" rel="nofollow">Screenshot here.</a><br>
  This isn't what the screenshots in the docs portray of the example.</p>
  
  <p>Then I found out about QTableView's setIndexWidget().<br>
  I tried to implement setIndexWidget() whenever data() was called on the model but no progress bars were shown.<br>
  So I thought I'd try setIndexWidget() in the delegate paint() code.<br>
  I created a dictionary (self.parent.progressBarPool) to track which progress bars had been manufactured - to avoid excessive creation/deletion I guess.</p>
  
  <pre><code>def paint(self, painter, option, index):
      if index.column() == 1:
  
          if not index.row() in self.parent.progressBarPool:
              progressBar = QtGui.QProgressBar()
              self.parent.progressBarPool[index.row()] = progressBar
              progressBar.setMinimum(0)
              # progressBar.setAutoFillBackground(True) # docs say this needs to be true, but you get a better row-highlight appearance with it False
              self.parent.tableView.setIndexWidget(index, progressBar)
          else:
              progressBar = self.parent.progressBarPool[index.row()]
  
          progressBar.setValue(20) # for testing
  
      return super(progressBarDelegate, self).paint(painter, option, index)
  </code></pre>
  
  <p>This looked great (<a href="http://www.bonhardapple.com/shared-with-others/first-glance.png" rel="nofollow">screenshot here</a>), however, when I scrolled, the progress bars didn't move in concert with the rest of the scroll area.<br>
  They floated above the cells which scrolled away underneath them (<a href="http://www.bonhardapple.com/shared-with-others/scrolled.png" rel="nofollow">screenshot</a>)</p>
  
  <p>I've now hacked things a bit so that the self.parent.progressBarPool is deleted when there's a wheelEvent.<br>
  This causes a flickery redraw on (one type of) scroll but feels like a growing stack of hacks rather than a solution.<br>
  Accordingly, I would appreciate any advice on the right way to do this.</p>
  
  <p>With thanks,</p>
  
  <p>Dave.</p>
  
  <p>pyqt 4.10.1<br>
  qt 4.8.4<br>
  Mac OS 10.6.8  </p>