2012-06-12 27 views
6

在Mint Linux 12上使用Qt4.8,我實現了一個包含QTableView的簡單窗口來顯示模型的內容。模型數據不斷更新(日誌消息),並定期發射信號(即每隔100ms)。QWidget更新事件,但沒有可視化更新

我看到的問題是桌面上的視覺更新停頓。

我安裝計數updateRequest型事件,它應該觸發一個widget重繪(也子部件,即tableView)窗口上的事件過濾器。它們之間的平均時間約爲170毫秒,標準偏差約爲90毫秒(這是相當大的,我猜)。然而,感知的視覺更新速度每秒只有兩到三次,我不知道爲什麼。看來並非所有updateRequest事件都會觸發窗口小部件重繪,或者窗口系統會吞噬視覺更新。

作爲第二個測試中,我通過調用repaintupdate每100ms迫使窗口進行自我更新。使用repaint,我看到updateRequest類型事件的相應增加和差距的標準差減少;與update,數量沒有增加。然而,在這兩種情況下,感知更新率只有適度增加。

另外:有沒有一種很好的方法來測量小部件實際上真正重新繪製的頻率,而不必重載其paintEvent處理程序?也許從QTest


更新:我伸出我的事件過濾器也搭上paintEvent型事件。只有一個數字與1000>updateRequest-類型事件相比較。

回答

1

您應該測量事件調度員的aboutToBlock()awake()信號,並使用QElapsedTimer來測量它們之間的時間。當前線程的事件分派器實例由靜態QAbstractEventDispatcher::instance()返回。

如果事件循環在您的時間測量窗口的一小部分時間內休眠,這意味着GUI線程中會發生太多事情。你可以記錄事件循環在最後一秒鐘睡眠的時間。如果它低於10%,你可以期望緩慢的更新和什麼。請記住,更新事件在Qt::LowEventPriority之間排隊。它們將被標準排隊信號和幾乎所有其他事件搶佔。

+0

好主意!我目前正在按計劃進行緊張的時間表,所以需要幾天的時間來測試。我認爲這應該給我一個很好的負載概述,但我實際上計算了達到我的小部件的updateRequest事件,並且這些事件比感知的更新速率更接近(平均而言)。 – arne

+0

計數是好的,但它並沒有告訴你任何有關潛在問題。它只是告訴你有一個問題,當然,你可以明顯注意到它沒有寫一行代碼:) –

0

QApplication::compressEvent丟棄QEvent::UpdateRequest,如果已經有一個未處理的。因此,即使重繪(s)可以立即返回而不繪畫,如果事件被丟棄。您可以通過覆蓋compressEvent來檢查您的updateRequest事件是否被丟棄。

+0

我知道壓縮,但是不是在主事件循環/ QApplication的某處完成了嗎?我認爲如果updateRequest到達一個小部件,這應該已經完成​​。 – arne

+0

你說得對,壓縮是在EventLoop中完成的。我誤解了,你在哪裏計數事件。是的,如果事件到達小部件,壓縮已經完成。所以,不要理我的答案。 – Stefan