QSpacerItem在实例化两次

时间:2016-10-03 14:16:38

标签: python user-interface crash pyqt

我已经在我的pyQt应用程序https://github.com/chipmuenk/pyfda中搜索了一个令人讨厌的崩溃崩溃错误超过一年了,并且偶然发现了它:以下代码片段

    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。

我在应用程序中有很多带标签的小部件(并且还有许多其他错误)并且已经在一个设计流程中工作,以某种方式抑制了这个bug太长时间,这就是为什么它花了我这么久。崩溃只发生在matplotlib画布已在一个完全不相关的子组件中实例化时,只是另一种奇怪的事情让我长时间咆哮错误的树...

有人知道上面的代码存在问题吗?

1 个答案:

答案 0 :(得分:3)

这看起来像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()