[PyQt] Re: question about resizing behavior

Ole Streicher ole-usenet-spam at gmx.net
Tue Jul 7 16:33:08 BST 2009


Hi again,

Darren Dale <dsdale24 at gmail.com> writes:
> Nice demonstration of the problem Ole. I notice that if, after
> resizing, I pause briefly before releasing the mouse button, the
> scroll bar is more likely to resize properly. The problem is much more
> apparent if I release the mouse button immediately after resizing or
> while still dragging the window edge.

I already created a Qt bug report for that (issue number #255433, not public
for some reason). They asked me to compile a C++ only variant of the
bug.

However, I could not reproduce the problem in C++: the events occure here
always in-order independent of the processing times in the (simulated)
inner widget resize time.

I could also not reproduce the bug in PyQt4 without matplotlib by
replacing the FigureCanvasQTAgg with a QFrame and adding some random
sleep to the resize function. 

But, with some stacktracing, I found the reason:

in matplotlib.FigureCanvasQTAgg, the following piece of code is called
on a resizeEvent:

def draw( self ):

    # ... some internal code

    # Added following line to improve realtime pan/zoom on windows:
    QtGui.qApp.processEvents()

This makes the problem clear:
- if we resize the window quickly, several resizeEvents are created and
  are in the event queue of Qt
- the first one gets processed by the QVBoxLayout which starts the
  processing in its first (matplotlib) widget.
- the matplotlib widget does what it should and at some point calls 
  matplotlib.FigureCanvasQTAgg.draw(self).
  - this starts the processing of the next event in the queue which is
    the next (2nd) resize event. BUT: we are still in the processing of 
    the first event!!!
  - the 2nd event goes to the QVBoxLayout, from there to the matlotlib
    widget (eventually starting some recursive behaviour here)
  - if the 2nd event is finished, QVBoxLayout sends it to its other widget
    (the scrollbar). The scrollbar is resized according to the *2nd event*.
- if the processing of the 2nd event was finished and no more events are 
  in the queue, the matplotlib.FigureCanvasQTAgg.draw() finishes
- at the end, this will finish the processing of the first resize event 
  in the matplotlib widget and start the *first resize event* for the
  scrollbar

This is exactly the behaviour that I described in my first posting. It
is caused by the QtGui.qApp.processEvents() call in the draw() function.

So, I think this is clearly a bug in matplotlib:
QtGui.qApp.processEvents() should not be called while processing another
event.

Darren, I dont know your position with respect to matplotlib: are you a
developer and thus aware of the bug or shall I post this again on the
matplotlib mailing list?

Best regards

Ole



More information about the PyQt mailing list