Uploaded image for project: 'Qt for Python'
  1. Qt for Python
  2. PYSIDE-2990

Slot Executed in Signal's Thread Even With Auto & QueuedConnection

    XMLWordPrintable

Details

    • Bug
    • Resolution: Invalid
    • Not Evaluated
    • None
    • 6.8
    • PySide
    • None
    • macOS, Windows

    Description

      It's first reported here.

       The slot is always executed in the signal caller's thread, even with explicit QueuedConnection, when a worker approach is used. The following minimal example is almost identical to the example from the official document.

      import sys
      
      from PySide6.QtCore import QObject, Signal, QThread, Qt, Slot
      from PySide6.QtWidgets import QMainWindow, QApplication
      
      
      class Worker(QObject):
          update = Signal()
      
          def run(self):
              print(f"worker: {QThread.currentThread().objectName()}")
              self.update.emit()
      
      
      class Window(QMainWindow):
          def __init__(self, parent=None):
              super().__init__(parent)
              worker = Worker()
              thread = QThread(self)
              thread.setObjectName('test thread')
              worker.moveToThread(thread)
              thread.started.connect(worker.run)
              worker.update.connect(self.update)
              thread.start()
      
          @Slot()
          def update(self):
              print(f"window: {QThread.currentThread().objectName()}")
      
      
      if __name__ == '__main__':
          app = QApplication()
          w = Window()
          w.show()
          sys.exit(app.exec())
      

      The output is

      worker: Qt mainThread
      window: test thread
      

      However, the problem doesn't exist when switched to subclassing QThread:

      import sys
      
      from PySide6.QtCore import QObject, Signal, QThread, Qt, Slot
      from PySide6.QtWidgets import QMainWindow, QApplication
      
      
      class Thread(QThread):
          update = Signal()
      
          def run(self):
              print(f"thread: {QThread.currentThread().objectName()}")
              self.update.emit()
      
      
      class Window(QMainWindow):
          def __init__(self, parent=None):
              super().__init__(parent)
              thread = Thread(self)
              thread.setObjectName('test thread')
              thread.update.connect(self.update)
              thread.start()
      
          @Slot()
          def update(self):
              print(f"window: {QThread.currentThread().objectName()}")
      
      
      if __name__ == '__main__':
          app = QApplication()
          w = Window()
          w.show()
          sys.exit(app.exec())
      

      I tried the cpp equivalent version and it works fine. Source code is attached in the zip file. Result of cpp version:

      2025-01-21 18:19:49.155575-0500 qt_test[86901:106814649] Worker::process  "test thread"
      2025-01-21 18:19:50.033013-0500 qt_test[86901:106814599] Window::process  "Qt mainThread"
      

      Attachments

        1. cpp-test.zip
          3 kB
        2. pyside2990_fixed.py
          1 kB
        3. pyside2990.py
          1 kB

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              crmaurei Cristian Maureira-Fredes
              yuanxun Xun Yuan
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes