Search code examples
pythonpysidezeromqpyside6

QThread Destroyed while thread is still running


I am trying to run ZeroMQ in a QThread. What I do is when a message arrives I emit the msg_received signal. In the App class the show_my_window method is connected to it so it will display a simple dialog.

The problem is as soon as I close that dialog, I get the following

QThread: Destroyed while thread is still running

Process finished with exit code -1073740791 (0xC0000409)

Here is my code:

class ZMQThread(QThread):
    msg_received = Signal()

    def __init__(self):
        super(ZMQThread, self).__init__()
        self.context = zmq.Context()
        self.socket = self.context.socket(zmq.REP)
        self.socket.bind("tcp://*:3344")

    def run(self):
        while True:
            message = self.socket.recv()
            self.msg_received.emit()
            
class MyWindow(QtWidgets.QDialog):
    def __init__(self):
        super(MyWindow, self).__init__()
        self.ui = Ui_MyDialog()
        self.ui.setupUi(self)
        self.ui.ButtonOK.clicked.connect(self.ok)

    def ok(self):
        self.accept()
  
class App:
    def __init__(self):
        self.qtapp = QtWidgets.QApplication([])
        self.my_window = MyWindow()
        self.zmq_thread = ZMQThread()
        self.zmq_thread.msg_received.connect(self.show_my_window)
        self.zmq_thread.start()

    def show_my_window(self):
        self.my_window.show()


if __name__ == '__main__':
    my_gui = App()
    sys.exit(my_gui.qtapp.exec())

I don't have a main window here, wondering if that could be a problem? I don't want a main window, this app will run on the tray but first I want to implement this part. I have checked some very similar questions but after checking those solutions they did not work. What could be the issue here?


Solution

  • By default, Qt ends the eventloop when the last open window is closed, and when the eventloop ends, the QThread does not close correctly. The solution is to disable this feature using the quitOnLastWindowClosed property:

    self.qtapp = QtWidgets.QApplication([])
    self.qtapp.setQuitOnLastWindowClosed(False)