【问题标题】:Qt/PyQt - frequently drawing pixmap to widget, partly not drawing correctlyQt/PyQt - 经常将像素图绘制到小部件,部分绘制不正确
【发布时间】:2012-04-15 00:51:02
【问题描述】:

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

我通过创建一个派生自 QWidget 的类来实现这一点,该类缓冲传入的数据,并每 30 毫秒绘制一次图形(默认情况下)。在__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)

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

有什么想法可能导致这种情况或我可以尝试的事情吗?

谢谢。

【问题讨论】:

    标签: qt graph plot pyqt real-time


    【解决方案1】:

    我不能 100% 确定这是否是问题所在,但我认为我至少可以做出一些贡献。

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

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

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

    不确定是否会修复它,但值得一试。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-15
      相关资源
      最近更新 更多