Opened 9 years ago

Closed 8 years ago

#633 closed defect (fixed)

Status messages cause havoc by running event loop

Reported by: Tom Goddard Owned by: Tom Goddard
Priority: major Milestone:
Component: Window Toolkit Version:
Keywords: Cc: pett@…
Blocked By: Blocking:
Notify when closed: Platform: all
Project: ChimeraX

Description

To get status messages to appear we run the Qt event loop when the status message is changed with an ExcludeUserEvents argument. Unfortunately this does not prevent bad side-effects from happening during status messages.

Here are two volume examples.

I noticed opening an Imaris volume series causes the first volume to be read twice even though it should be cached after the first read (which took 5 seconds). But status messages clearly show it being read twice. Debugging showed that while the first read was in progress, a status message announcing the percentage complete of reading that file causes event processing. That causes a 0.5 second timer to go off to update the Volume Viewer panel histogram, which in the middle of the previous incomplete file read, starts reading the file a second time. QTimer is clearly not excluded in the status message event processing.

A second example. Moving the volume series slider continuously sometimes causes (1 in 100 frames) time to not be hidden, and it remains superimposed with the time that is shown. Debugging shows that during MapSeries.show_time(t) call a status message is shown, events are processed, and during that event processing a QSlider.valueChanged signal is emitted causing MapSeries.show_time(t2) to be called while still in the previous show_time() call. This seems like a clear case of a user event (slider motion) even though the event processing has ExcludeUserEvents set.

About 4 hours were spent debugging the above 2 problems with no simple fix. We need to provide status / progress messaging that does not run the event loop.

Change History (2)

comment:1 by Tom Goddard, 9 years ago

Eric looked some months ago at getting Qt to paint the status line without processing events, but ran into difficulties. Many web discussions of this problem have not found any way to make Qt paint a widget without processing events.

Another idea is to render the status line as OpenGL, basically leveraging our 2d label code to draw text into a status line QWindow which is an opengl widget, using its on OpenGL context. This extreme solution also has problems. The OpenGL swap buffers can (likely) block to sync with 60 Hz display vertical refresh. So frequent status messages could keep the program blocked most of the time. Putting the OpenGL drawing of status text in a separate thread is possible. But if it is a Python thread running Python code then it will prevent the main thread from running unless the global interpreter lock is released. I don't know if PyOpenGL calls release the interpreter lock.

An even more desperate idea is to have a separate process display the status messages. It is not clear if it is possible for a separate process to render into the main process window. Maybe the Chromium processes Qt uses for html widgets do that, or maybe they use shared memory to communicate the rendering. Tests long ago suggested that a QWebEngineView like the log does not get redrawn unless the Qt event loop runs.

comment:2 by Tom Goddard, 8 years ago

Resolution: fixed
Status: assignedclosed

Made status bar render with OpenGL with no Qt event processing.

Note: See TracTickets for help on using tickets.