2012-04-15 150 views
1

我正在研究一个基于Qt的应用程序(实际上在PyQt中,但我认为这不是相关的),其中一部分涉及绘制一个潜在的连续流的数据实时显示在图表上。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(由于低帧率,视频有点迟缓,但效果是可见的)

任何想法什么可能导致这个或我可以尝试的东西?

谢谢。

回答

0

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

self.update()是一个异步调用,它将在主要事件循环再次到达后的某个时间点导致绘制事件。所以这让我想知道你的绘图是否有问题,因为当你修改你的pixmap和它实际上在paintEvent中使用它之间的同步问题。几乎看起来像你需要这个确切的代码工作是一个锁在你的paintEvent,但这很漂亮的调子。

对于一个快速测试,你可以尝试迫使事件循环冲洗后右您的呼叫更新:

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

不知道这将修复它,但它值得一试。

这实际上可能是使用适当的情况repaint(),造成直接绘制事件,因为你使用的是控制帧率做一个“动画”:self.repaint()

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