How can I make paintEvent triggered only when update is called?

霸气de小男生 提交于 2019-12-13 09:46:06

问题


It is known that QWidget::paintEvent is triggered automatically the moment widget becomes visible or any event from the basic window happens. What should I do if I only want the paintEvent to be issued in response to update()?


回答1:


It'd make no sense for a paintEvent not to be issued whenever the widget needs to be painted. Your reason to demand such an option means that you're trying to use the Qt API in a way it wasn't meant to be used. I can't quite imagine yet a particular design that would lead you to such use, sorry about that.

So, the only thing I can tell you is how you'd use update(). The idiomatic way of handling widget updates is as follows:

  1. The source of data that the widget uses is updated. For example, the text or some variable affecting the visible contents is changed. Often this data is a Q_PROPERTY of the widget. The setter function is updating the member variable that stores the value and calls update(). The setter should not perform any expensive computations - they should be deferred until the paint event.

  2. If the properties are changed multiple times before the event loop has a chance to run, the update events get coalesced. Internally, a call to update() results in posting an event to the event queue of the GUI thread. If there already is an update event in the queue for the given widget, the events get coalesced. The following invariant is preserved: at any given time, there can only be one update event for any particular widget in an event queue.

  3. When the control returns to the event loop, the update event gets dispatched to the widget, ending up in calling your reimplementation of QWidget::paintEvent(...). This implementation should do the calculations necessary to paint the widget, and do the actual painting. If the calculations are extensive, they should be relegated to a worker thread.

Example

Let's say an application is receiving data from a serial port, modeled as a QIODevice (a QSerialPort is one). You could do as follows:

  1. Connect QIODevice's readyRead signal to a slot in a parser QObject.

  2. The slot receives and parses the data. It then emits a signal with processed data (for example, a vector of floating point values). This signal is connected to a newData slot in the widget.

  3. The newData slot adds the data as-is to a queue, and schedules an update(). This is very fast if you're using Qt's data structures, or if your data class is modeled after them and uses implicit sharing with copy-on-write.

  4. The update() dequeues all data sets and plots them. The QWidget::scroll() method comes handy for scrolling plots.



来源:https://stackoverflow.com/questions/18777535/how-can-i-make-paintevent-triggered-only-when-update-is-called

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!