-1

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

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
May
  • 1
  • 2
  • 6
  • I still think that you're architecting it horribly wrong if you really think you need to do what you think you need to do. Please edit your question and provide some background as to exactly what you're doing and why this weird requirement has come up. – Kuba hasn't forgotten Monica Sep 13 '13 at 06:08

1 Answers1

0

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.

Community
  • 1
  • 1
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • I know a little about the mechanism of update().Actually,paintEvent here is applied to draw data from serial port.Is eventfilter or something else available here? – May Sep 13 '13 at 04:26
  • Well, you seem to misunderstand the mechanism if you insist on applying it in such an awkward way :( – Kuba hasn't forgotten Monica Sep 13 '13 at 06:08