2012-04-15 149 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()