Skip to content Skip to sidebar Skip to footer

A FigureCanvasQTAgg Nested In A QMdiSubWindow Segfaults When I Minimize The QMdiSubWindow

I am trying to have FigureCanvasQTAgg inside QMdiSubWindow such that the user can create his/her own plots on the fly. I have made this very small self contained code: from PyQt4

Solution 1:

The issue seems to be that when minimized the widget has a negative height (I guess that makes sense, but I can not find any documentation of this fact; I noticed this by adding some print statements). The solution is to just not draw in those cases. I have submitted a PR to fix this upstream, but you might need to monky patch matplotlib.backends.backend_qt5agg.FigureCanvasQTAggBase.__draw_idle_agg with:

def __draw_idle_agg(self, *args):
    if self.height() < 0 or self.width() < 0:
        self._agg_draw_pending = False
        return
    try:
        FigureCanvasAgg.draw(self)
        self.update()
    finally:
        self._agg_draw_pending = False

Note that the qt5 in the module is not a typo, the Qt4 functionality is derived from the Qt5 support.


Solution 2:

The issue seems to revolve around an incorrect size being reported for the matplotlib widget. As @tcaswell points out, matplotlib should be fixed to ensure this doesn't cause a segfault.

I'm going to attack the problem from the other side and try to stop Qt from reporting bogus dimensions. It seems that using the "inbuilt" layout causes the issue. This is likely because the existence of the layout is inherited by QMdiSubWindow from QWidget, but the implementation of QMdiSubWindow likely does not use it correctly. As long as you use the QMdiSubWindow.setWidget() method, and create your own layouts, the segfault is avoided.

Here is some example code with a layout that you manage yourself:

p = FigureCanvas(fig)
container = QtGui.QWidget()
layout = QtGui.QVBoxLayout(container)
layout.addWidget(p)        
sub.setWidget(container)

EDIT

If you look at the underlying C++ implementation you can see that a call to QMdiSubWindow.setWidget() is a lot more complicated than just adding the widget to the layout!


Post a Comment for "A FigureCanvasQTAgg Nested In A QMdiSubWindow Segfaults When I Minimize The QMdiSubWindow"