QSpacerItem 在实例化两次时使 pyQT 崩溃
Posted
技术标签:
【中文标题】QSpacerItem 在实例化两次时使 pyQT 崩溃【英文标题】:QSpacerItem crashes pyQT when instantiated twice 【发布时间】: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 画布在一个完全不相关的子小部件中实例化时才会发生崩溃,这只是另一个怪事,让我很长一段时间都在找错误的树......
有人知道上面代码的问题出在哪里吗?
【问题讨论】:
【参考方案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 来说,布局是双重删除分隔符......有时是一个难以捕捉的错误以上是关于QSpacerItem 在实例化两次时使 pyQT 崩溃的主要内容,如果未能解决你的问题,请参考以下文章