Qt / PyQt - 经常将pixmap绘制到widget,部分绘制不正确

时间:2012-04-15 00:51:03

标签: qt graph plot pyqt real-time

我正在开发一个基于Qt的应用程序(实际上是在PyQt中,但我认为这不相关),其中一部分涉及实时绘制可能连续的数据流到图表上。

我通过创建一个派生自QWidget的类来实现这一点,该类缓冲传入的数据,并且每隔30ms(默认情况下)绘制图形。在__init__()中,创建了QPixmap,并且在QTimer的每个刻度上,(1)图表向左移动了新数据占用的像素数,(2)在空间中绘制的矩形,(3)绘制的点,以及(4)update()在小部件上调用,如下(减少):

    # 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)
    # Brush setup would be here...

    pm.scroll(0-scroll, 0, scroll, 0, pm.width()-scroll, pm.height())
    p.drawRect(pm.width()-scroll, 0, scroll, pm.height())        

    # pen setup etc happens here...

    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

    self.update()

最后,paintEvent只是将像素图绘制到小部件上:

    p = QtGui.QPainter(self)
    p.drawPixmap(0, 0, self.graphPixmap)

据我所知,这应该可以正常工作,但是,当数据被非常快速地接收时(即每个刻度上绘制整个图形),并且小部件大于特定大小(大约700px), 700px区域左侧的所有内容都相当滞后。这可能最好在此视频中得到证明:http://dl.dropbox.com/u/1362366/keep/Graph_bug.swf.html(由于帧速率较低,视频有点滞后,但效果明显)

任何想法可能导致这个或我可以尝试的事情?

感谢。

1 个答案:

答案 0 :(得分:0)

我不是百分百确定这是否是问题,但我想我至少可以做出一些贡献。

self.update()是一个异步调用,它会在稍后再次到达主事件循环时在某个时刻导致绘制事件。所以它让我想知道你的绘图是否有问题,因为你修改pixmap与实际在paintEvent中实际使用时之间存在同步问题。几乎看起来你需要这个确切的代码才能在你的paintEvent中锁定,但这听起来很顽皮。

要进行快速测试,您可以尝试在调用更新后立即强制事件循环刷新:

self.update()
QtGui.QApplication.processEvents()

不确定会解决它,但值得一试。

这实际上可能是使用repaint()并导致直接绘制事件的正确情况,因为您使用受控帧率执行“动画”:self.repaint()

我发现了一个类似的问题,有人试图实时绘制心脏监护仪的图形:http://qt-project.org/forums/viewthread/10677
也许您可以尝试重构类似的代码。他不是将绘画分成两个阶段,而是使用QLabel作为显示窗口小部件,将像素图设置为QLabel,并立即绘制整个图形,而不是依赖于对widget的调用。(update()