【问题标题】:QSpacerItem crashes pyQT when instantiated twiceQSpacerItem 在实例化两次时使 pyQT 崩溃
【发布时间】:2017-02-11 12:39:12
【问题描述】:

一年多来,我一直在我的 pyQt 应用程序https://github.com/chipmuenk/pyfda 中寻找一个令人讨厌的退出时崩溃错误,并且偶然发现了它:以下代码 sn-p

    self.cmbResponseType = QtGui.QComboBox(self)
    self.cmbFilterType = QtGui.QComboBox(self)
    self.cmbDesignMethod = QtGui.QComboBox(self)

    spacer = QtGui.QSpacerItem(1, 0, QtGui.QSizePolicy.Expanding,
                                     QtGui.QSizePolicy.Fixed)

    layHFilWdg = QtGui.QHBoxLayout() # container for filter subwidgets
    layHFilWdg.addWidget(self.cmbResponseType)
    layHFilWdg.addItem(spacer)
    layHFilWdg.addWidget(self.cmbFilterType)
    layHFilWdg.addItem(spacer)
    layHFilWdg.addWidget(self.cmbDesignMethod)

将三个组合框放置在水平布局框中,它们之间的间距可变。

当我注释掉两个layHFilWdg.addItem(spacer) 指令之一时,该错误消失了(退出时不再崩溃)。我正在使用 python 2.7 ... 3.5 和 pyQt 4.8。

我在应用程序中有很多选项卡式小部件(也有很多其他错误),并且在设计流程中以某种方式抑制错误太久,这就是我花了这么长时间的原因。只有当 matplotlib 画布在一个完全不相关的子小部件中实例化时才会发生崩溃,这只是另一个怪事,让我很长一段时间都在找错误的树......

有人知道上面代码的问题出在哪里吗?

【问题讨论】:

    标签: python user-interface crash pyqt


    【解决方案1】:

    这看起来像是 Python 垃圾收集器以 Qt 不期望的顺序删除对象的典型案例。向同一个布局多次添加间隔符可能会导致 Qt 尝试将其删除两次,或者在它不再存在时将其删除。显而易见的解决方案很简单:不要那样做。

    所以要么每次创建一个新的垫片:

        def spacer():
            return QtGui.QSpacerItem(
                1, 0, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
    
        ...
    
        layHFilWdg.addItem(spacer())
    

    或者只使用布局的addStretch() 方法:

        layHFilWdg.addWidget(self.cmbResponseType)
        layHFilWdg.addStretch()
    

    【讨论】:

    • 有道理!其他小部件很难遇到类似的情况,您希望每个实例都有不同的行为,但是使用间隔...
    • 至少对于 QT 4.8.7 来说,布局是双重删除分隔符......有时是一个难以捕捉的错误
    猜你喜欢
    • 2021-05-06
    • 2019-03-29
    • 2010-09-08
    • 1970-01-01
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多