PDA

View Full Version : PyQt4 - part of a QPixmap not drawing correctly



emorris
16th February 2012, 15:17
Hi,
I'm currently working on a PyQt4 application, part of which is a basic graph widget. The widget's purpose is to accept data via a slot, and plot the points. The way it currently works is by storing the incoming data in a list, and a QTimer triggers a method to plot the pending data every x milliseconds.

However, I've noticed that when the widget is bigger than a certain width (~ 700 px on my PC) and the timer has a short enough interval (~ 30 ms on my PC, but even as much as 200 ms on another machine), the left part of the image vary rarely updates. It seems very odd, as the right section of the graph works great.

Originally I had thought that it could be that the next graph was starting to be plotted before the previous one had finished, but I made use of a QMutex, only plotting if it was unlocked, and the issue still occurs.

I'm pretty sure the issue is in the modifying of the QPixmap rather than the paintEvent, which simply copies the pixmap to the widget.

If anyone has any ideas of what could be the problem, they would be very much appreciated.

The method which actually plots the points onto the QPixmap:

def _plotPendingDataPoints(self):
pm=self.graphPixmap
penw=self._penWidth
points=self._pendingPoints

# Return if nothing to plot
if (len(points)==0): return

# Wait for lock on the list
_ml=QtCore.QMutexLocker(self._pendingPointsMutex)

# Plot only if we can lock the graph mutex
if (not(self._plotPointsMutex.tryLock())):
return

# Amount of pixels to scroll
scroll=penw*len(points)

# The first point is not plotted now, so don't shift the graph for it
if (self.firstPoint()):
scroll-=1

p=QtGui.QPainter(pm)

p.setBrush(QtGui.QBrush(QtGui.QColor("white")))
p.setPen(QtCore.Qt.NoPen)

# Scroll graph and fill in new area
pm.scroll(0-scroll, 0, scroll, 0, pm.width()-scroll, pm.height())
p.drawRect(pm.width()-scroll, 0, scroll, pm.height())


# Turn on antialiasing
p.setRenderHint(QtGui.QPainter.Antialiasing)

# Set up pen for drawing lines
pen = QtGui.QPen(QtGui.QColor("black"))
pen.setWidth(penw)
p.setPen(pen)

offset=scroll
for point in points:
yValNew = self.graphHeight - (self.scalePoint(point))

# Skip first point
if (not(self.firstPoint())):
p.drawLine(pm.width()-offset-penw, self.yVal, pm.width()-offset, yValNew)

self.yVal = yValNew
offset-=penw


# Queue update
self.update()

# Clear pending points
self._pendingPoints=[]

# Unlock the mutex
self._plotPointsMutex.unlock()