Use of qt.Signal leads to a crash on exit

Recently, I have been investigating the source of a crash on exit.

To reproduce the crash:

./Slicer --no-main-window --testing

Notes:

  • removing the connection to the closed signal object here in the DICOM module avoids the crash on exit from happening.
  • disconnecting the signal on exit (or just after setting the connection) does not prevent the crash from happening
  • starting the application with the main window prevents the crash on exit from happening
  • a possibly related thread on the PythonQt forum is this one: Segmentation fault after emiting a signal
  • yesterday, we updated (see r28485) to use the latest version of PythonQt thinking the issue would be addressed … but it is not.

Create a script test.py with the following content:

class FooDetailsWidget(qt.QWidget):
  closed = qt.Signal() # Invoked when the dicom widget is closed using the close method
  def __init__(self):
    qt.QWidget.__init__(self)

class Foo(object):
  def __init__(self):
    self.detailsPopup = FooDetailsWidget()
    self.detailsPopup.closed.connect(self.onDetailsPopupClosed)
  def onDetailsPopupClosed(self):
    print("onDetailsPopupClosed")

d = Foo()
d.detailsPopup.closed.emit()

# In this case, disconnecting prevent the crash on exit from happening
# d.detailsPopup.closed.disconnect(d.onDetailsPopupClosed)

and running Slicer with the following allows to reproduce a crash on exit. But:

  • the condition are not exactly the same
  • disconnecting the signal prevent the crash from happening whereas in the DICOM module it does not
  • with/without --no-main-window lead to a crash
./Slicer --disable-modules --no-main-window --testing --python-script /tmp/test.py

Hi jcfr, have you solved this? The pythonQt seems to not support calling emit() directly. Do you have a workaround? Thanks

Would you like to emit another object’s signal? This was explicitly prohibited in Qt4 but to allow new syntax in Qt5 this cannot be prevented anymore. Still, it should not be done, as you would essentially lie about the internal state of the other object to all connected objects. Objects should always emit their own signals only. Objects can call other object’s slots.

1 Like

Dear all,
I dig up this thread but I think it is worth having a solution to this issue.
I am exactly in the same situation as @jcfr : I have a widget in python that emits signals and the moment I connect to these signal in another widget, I have this silent crash on exit, even if disconnection are properly implemented. I have tried several modifications without managing to find a good solution.
@jcfr have you explored a bit further this issue ?
Thanks for your input

Does the widget emit its own signal, or the tries to make make another object emit a signal? Can you provide a minimal reproducible example script?