QMdiSubWindow中的FigureCanvasQTAgg嵌套最小,导致QMdiSubWindow崩溃。

2024-09-22 16:41:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试在QMdiSubWindow中设置FigureCanvasQTAgg,这样用户就可以动态地创建他/她自己的绘图。 我制作了一个非常小的独立代码:

from PyQt4 import QtGui
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import sys

class ExampleApp(QtGui.QMainWindow):
    def __init__(self):
        super(self.__class__, self).__init__()
        self.mdiarea = QtGui.QMdiArea()
        self.setCentralWidget(self.mdiarea)
        sub = QtGui.QMdiSubWindow(self.mdiarea)
        fig = Figure()
        p = FigureCanvas(fig)
        sub.layout().addWidget(p)
        sub.show()

def main():
    app = QtGui.QApplication(sys.argv)
    form = ExampleApp()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()

当我运行程序并试图最小化QtGui.QMdiSubWindow对象。当我这样做时,程序会自动退出,没有错误描述。 这可能是qt、python绑定或FigureCanvasQTAgg对象中的错误。当然也可能是我错用了这些东西。请帮助我理解当我最小化子窗口时为什么会出现segfault,并帮助我找出解决这个问题的方法。 非常感谢。在

我的环境是ubuntu14.04并使用 Qt版本:4.8.7 SIP版本:4.16.9 PyQt版本:4.11.4 MatplotLib版本:1.5.0

下面是拖放属性集的示例。看来这也有问题。在

^{pr2}$

Tags: fromimportself版本matplotlibmainsysclass
2条回答

这个问题似乎是围绕matplotlib小部件报告的大小不正确而引起的。正如@tcaswell指出的,matplotlib应该被修复,以确保这不会导致segfault。在

我将从另一个方面攻击这个问题,并尝试阻止Qt报告虚假的维度。似乎使用“内置”布局导致了这个问题。这很可能是因为布局的存在是由QMdiSubWindowQWidget继承的,但是{}的实现可能没有正确使用它。只要使用QMdiSubWindow.setWidget()方法并创建自己的布局,就可以避免segfault。在

下面是一些您自己管理布局的示例代码:

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

编辑

如果你看一下underlying C++ implementation,你会发现调用QMdiSubWindow.setWidget()要比仅仅在布局中添加小部件复杂得多!在

问题似乎是,当最小化时,小部件的高度为负(我想这是有道理的,但我找不到这一事实的任何文档;我通过添加一些print语句注意到了这一点)。解决办法就是不要在这些情况下画蛇添足。我已经提交了一个PR来修复这个上游问题,但是您可能需要使用以下命令来修补matplotlib.backends.backend_qt5agg.FigureCanvasQTAggBase.__draw_idle_agg

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

请注意,模块中的qt5不是打字错误,Qt4功能是从Qt5支持中派生出来的。在

相关问题 更多 >