问题描述
在Mint Linux 12上使用Qt4.8,我实现了一个包含 QTableView
的简单窗口来显示模型的内容。模型数据不断更新(日志消息), dataChanged()
信号定期发出(即每100ms)一次。
Using Qt4.8 on a Mint Linux 12, I implemented a simple window containing a QTableView
to show contents of a model. The model data is continually updated (log messages) and the dataChanged()
signal is emitted on a regular basis (i.e. every 100ms).
我看到的问题是对表上的视觉更新造成阻碍。
The problem I see is stuttering visual updates on the table.
我在窗口上安装了一个事件过滤器,它计数 updateRequest
- type事件,它应该触发小部件重绘(也在子小部件,即 tableView
)。它们之间的平均时间约为170毫秒,标准偏差约为90毫秒(这是相当大的,我猜)。然而,感知的视觉更新速率仅为每秒两三次,我不知道为什么。似乎并非所有 updateRequest
事件都会触发窗口小部件重绘,或者窗口系统会隐藏可视更新。
I installed an event filter on the window that counts updateRequest
-type events, which should trigger a widget repaint (also on child widgets, i.e. the tableView
). These come in with an average time of ~170ms between them and a standard deviation of ~90ms (which is rather large, I guess). However, the perceived visual update rate is only two or three times a second and I wonder why. It seems that not all updateRequest
events trigger a widget repaint or that the window system swallows visual updates.
第二个测试,我通过每100ms调用 repaint
或更新
强制窗口更新自己。使用 repaint
,我看到 updateRequest
类型事件相应增加,并且间隙的标准偏差减小;与更新
,数字没有增加。但是,在这两种情况下,感知更新率只有适度增加。
As a second test, I forced the window to update itself by calling repaint
or update
every 100ms. Using repaint
, I saw a corresponding increase in updateRequest
-type events and a decrease of the standard deviation of the gaps; with update
, the number did not increase. However, there was only a moderate increase of perceived update rate in both cases.
此外:有一个很好的方法来测量小部件实际上真正重画的频率,重载其 paintEvent
处理程序?可能来自 QTest
?
Also: Is there a good method to measure how often a widget is actually really repainted without having to overload its paintEvent
handler? Maybe something from QTest
?
/ strong>我扩展我的事件过滤器也捕获 paintEvent
-type事件。只有一个数字的数字与> 1000 updateRequest
类型事件。
Update: I extended my event filter to also catch paintEvent
-type events. There are only a one-digit number of those versus > 1000 updateRequest
-type events.
推荐答案
您应该调试事件分派器的 aboutToBlock()
和 awake()
之间使用 QElapsedTimer
。用于当前线程的事件分派器的实例由静态 QAbstractEventDispatcher :: instance()
返回。
You should instrument the event dispatcher's aboutToBlock()
and awake()
signals, and measure time between them using a QElapsedTimer
. The instance of the event dispatcher for the current thread is returned by the static QAbstractEventDispatcher::instance()
.
如果事件循环睡眠时间测量窗口的一小部分,这意味着GUI线程中有太多的东西。你可以保持一个事件循环睡眠的时间,比如说,在最后一秒。如果它低于10%,你可以期待缓慢的更新和whatnot。请记住,更新事件使用 Qt :: LowEventPriority
排队。它们将被标准排队信号和几乎所有其他事件所抢占。
If the event loop sleeps for a very small fraction of your time measurement window, it means there's too much stuff going on in the GUI thread. You can keep a count of how long the event loop slept, say, during the last second. If it's below 10%, you can expect slow updates and whatnot. Remember that update events are queued with Qt::LowEventPriority
. They will be preempted by standard queued signals and almost all other events.
这篇关于QWidget更新事件,但没有可视更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!