QSpacerItem crashes pyQT when instantiated twice
<p>I've been hunting a nasty crash-upon-exit bug in my pyQt Application <a href="https://github.com/chipmuenk/pyfda" rel="nofollow">https://github.com/chipmuenk/pyfda</a> for more than a year now and have just found it by chance: The following code snippet</p>

<pre><code>    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)
</code></pre>

<p>places three combo boxes in a horizontal layout box with variable spacing between them.</p>

<p>The bug disappears (no more crash upon exit) when I comment out one of the two <code>layHFilWdg.addItem(spacer)</code> instructions. I'm using python 2.7 ... 3.5 and pyQt 4.8.</p>

<p>I've got lot of tabbed widgets (and had a lot of other bugs as well) in the application and had worked in a design flow that somehow suppressed the bug for too long, that's why it took me so long. That the crash only happens when a matplotlib canvas has been instantiated in a completely unrelated subwidget is just another weirdness that made me bark up the wrong tree for a long time ... </p>

<p>Has anybody got an idea where the problem lies with the code above?</p>

<p>This looks like a typical case of the Python garbage-collector deleting objects in an order that Qt is not expecting. It's possible that adding a spacer multiple times to the same layout may result in Qt trying to delete it twice, or delete it when it's no longer there. With the obvious solution being simply: don't do that.</p>

<p>So either create a new spacer each time:</p>

<pre><code>    def spacer():
        return QtGui.QSpacerItem(
            1, 0, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)

    ...

    layHFilWdg.addItem(spacer())
</code></pre>

<p>or just use the layout's <code>addStretch()</code> method:</p>

<pre><code>    layHFilWdg.addWidget(self.cmbResponseType)
    layHFilWdg.addStretch()
</code></pre>

python user-interface crash pyqt