二回

2016-10-03 2 views
1

私は1年以上のための私のPyQtはアプリケーションhttps://github.com/chipmuenk/pyfdaで厄介なクラッシュアポン出るバグを狩猟してきたがインスタンス化され、ちょうど偶然それを発見したときQSpacerItemはPyQtはをクラッシュ:次のコードスニペット二回

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) 

は、水平レイアウトボックスに3つのコンボボックスを配置し、間隔を変えて配置します。

2つのlayHFilWdg.addItem(spacer)命令のいずれかをコメントアウトすると、バグが消えます(終了時にクラッシュしなくなります)。私はpython 2.7 ... 3.5とpyQt 4.8を使用しています。

私は、アプリケーションにたくさんのタブ付きウィジェットを持っていて(他にもたくさんのバグがありました)、何とかバグをあまりにも抑えた設計フローで働いていました。 matplotlibキャンバスが完全に無関係なサブウィジェット内でインスタンス化されたときにクラッシュが発生するのはちょっと別の奇妙なことであり、長い間間違ったツリーを樹立しました...

問題がどこにあるか上記のコードですか?

答えて

1

これはPythonのガベージコレクタがQtが期待していない順序でオブジェクトを削除する典型的なケースのようです。同じレイアウトにスペーサーを複数回追加すると、Qtがそれを2回削除しようとしたり、もはや存在しなくなったときに削除したりする可能性があります。明白な解決策は簡単です:それをしないでください。

だから、どちらかのたびに新しいスペーサーを作成します。

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

    ... 

    layHFilWdg.addItem(spacer()) 

か、単にレイアウトのaddStretch()メソッドを使用します。

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

理にかなっています!各インスタンシエーションで異なる動作が期待される他のウィジェットと同様の状況に遭遇するのは難しいでしょう。 – Chipmuenk

+0

少なくともQT 4.8.7の場合、スペーサーはスペーサーをダブルで削除しています... A時々見つけにくいバグ – MofX