[PyQt] Re: question about resizing behavior

Ole Streicher ole-usenet-spam at gmx.net
Fri Jul 3 08:37:29 BST 2009


Hello Darren,

Darren Dale <dsdale24 at gmail.com> writes:
> Somebody reported some strange resizing behavior at the matplotlib mailing
> list. 

The "somebody" was me :-)

Here some additional information:

If you printout the resize (overwritten) events of the scrollbar and the
matplotlib widgets (see code below), you will see that sometimes the
events are not processed in-order:

ScrollBar start 640
ScrollBar   end 640
  Diagram start 640
  Diagram   end 640

occurs when I just started, which is correct. But when one changes the
horizontal size, the following happens (printouts which obviously belong
to the same resize event are marked with the same number of stars):

*     Diagram start 633
**    Diagram start 608 
[...]
**    Diagram   end 608
**  ScrollBar start 608
**  ScrollBar   end 608
*     Diagram   end 633
*   ScrollBar start 633
*   ScrollBar   end 633

What you see is that

- the matplotlib FigureCanvasQTAgg gets its first resize event
- during its processing inside FigureCanvasQTAgg a second event
  occurred
- this second event is processed *faster* by FigureCanvasQTAgg than 
  the first event
- thus, the second event occurs *first* on the scrollbar
- the first resize event only occurs after the second on the scrollbar
- this leads to a wrong size of the scrollbar
- this may occur even nested (removed "[...]" in the printout above)

This may be a bug in FigureCanvasQTAgg (it is not synchonized in the
processing of resize events, allowing events to bypass), or in
Qt/QVBoxLayout (same argument there). I am not deep enough inside Qt to
know the API details here.

Best regards

Ole
-----------------------------8<------------------------------------------
import sys

from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
from matplotlib.figure import Figure

class MyDiagram(FigureCanvasQTAgg):
    def __init__(self, fig):
        FigureCanvasQTAgg.__init__(self, fig)

    def resizeEvent(self, event):
        print '  Diagram start', event.size().width()
        FigureCanvasQTAgg.resizeEvent(self, event)
        print '  Diagram   end', event.size().width()


class MyScrollBar(QtGui.QScrollBar):
    def __init__(self, parent):
        QtGui.QScrollBar.__init__(self, QtCore.Qt.Horizontal, parent)

    def resizeEvent(self, event):
        print 'ScrollBar start', event.size().width()
        QtGui.QScrollBar.resizeEvent(self, event)
        print 'ScrollBar   end', event.size().width()

class DiagramWidget(QtGui.QWidget):
   def __init__(self, parent=None):
       QtGui.QWidget.__init__(self, parent)

       self.scrollbar = MyScrollBar(self)

       fig = Figure()
       axes = fig.add_subplot(111)
       axes.plot(xrange(100))
       self.diagram = MyDiagram(fig)
       self.diagram.setParent(self)

       layout = QtGui.QVBoxLayout(self)
       self.setLayout(layout)
       layout.addWidget(self.diagram)
       layout.addWidget(self.scrollbar)

a = QtGui.QApplication(sys.argv)
w = DiagramWidget()
w.show()
a.exec_()

-----------------------------8<------------------------------------------



More information about the PyQt mailing list