QWidget update events but no visual update

2019-06-19 17:10发布

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.

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.

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.

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?


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.

2条回答
ゆ 、 Hurt°
2楼-- · 2019-06-19 18:03

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().

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.

查看更多
We Are One
3楼-- · 2019-06-19 18:04

QApplication::compressEvent discards QEvent::UpdateRequest, if there is already one unprocessed. Thus even repaint(s) can return immediately without painting, if the event is discarded. You can check, if your updateRequest events are discarded by overwriting compressEvent.

查看更多
登录 后发表回答