Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Unsolved PySide2 with Python3 Built-In Multiprocessing

    Language Bindings
    pyside2 python3 multiprocessing qthread
    3
    3
    1612
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • GLaDOS1105
      GLaDOS1105 last edited by

      I try to modify the original code written in PyQt5 to PySide2 as the license problems. In the original code (PyQt5), I use multiprocessing in QThread to increase CPU usage, and it works perfectly. However, after modified to PySide2, the code generates a series of error and destroy the GUI. The following is a minimized example to cause the problem.

      The following code works well when I use the PyQt5 instead of PySide2.

      import sys
      import multiprocessing as mp
      from PyQt5.QtCore import QThread
      from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
      
      class Task(QThread):
          def run(self):
              print('task started')
              with mp.Pool() as pool:
                  res = pool.map(mp_task, range(10000))
              print('task finished', res)
      
      def mp_task(x):
          # some heavy tasks
          ret = 0
          for i in range(x + 50000):
              ret += i
          return ret
      
      class Gui(QMainWindow):
          def __init__(self):
              super().__init__()
              button = QPushButton('click me')
              button.clicked.connect(self.do_task)
              self.setCentralWidget(button)
      
          def do_task(self):
              self.thread = Task()
              self.thread.start()
      
      def main():
          app = QApplication(sys.argv)
          window = Gui()
          window.show()
          sys.exit(app.exec_())
      
      if __name__ == '__main__':
          main()
      

      However, if I change the import package from PyQt5 to PySide2, for example,

      from PySide2.QtCore import QThread
      from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton
      

      after clicking the button, the GUI will be destroyed and the program generates the following error messages (some repeated messages has been omitted):

      QObject: Cannot create children for a parent that is in a different thread.
      (Parent is QApplication(0x1cb19c0), parent's thread is QThread(0x1948cc0), current thread is Task(0x7fc1d0005390)
      QObject: Cannot create children for a parent that is in a different thread.
      (Parent is QApplication(0x1cb19c0), parent's thread is QThread(0x1948cc0), current thread is Task(0x7fc1d0005390)
      QObject: Cannot create children for a parent that is in a different thread.
      (Parent is QApplication(0x1cb19c0), parent's thread is QThread(0x1948cc0), current thread is Task(0x7fc1d0005390)
      qt.qpa.xcb: QXcbConnection: XCB error: 128 (Unknown), sequence: 548, resource id: 88080397, major code: 130 (Unknown), minor code: 2
      qt.qpa.xcb: QXcbConnection: XCB error: 128 (Unknown), sequence: 552, resource id: 88080397, major code: 130 (Unknown), minor code: 2
      QObject: Cannot create children for a parent that is in a different thread.
      (Parent is QApplication(0x1cb19c0), parent's thread is QThread(0x1948cc0), current thread is Task(0x7fc1d0005390)
      

      Interestingly, if I put the contents of the main() function to global scope, the problem solved! For example:

      if __name__ == '__main__':
          app = QApplication(sys.argv)
          window = Gui()
          window.show()
          sys.exit(app.exec_())
      

      Maybe there are some differences between PyQt5 and PySide2 in QThread and lead to this fatal error. If I do not want to move QApplication and Gui into global scope, how could I fix the problem?

      Testing environment: Ubuntu 18.04 64-bit, Python3.6, PyQt5 5.11.2, PySide2 5.11.1

      D 1 Reply Last reply Reply Quote 0
      • D
        Dermot Doran @GLaDOS1105 last edited by

        @GLaDOS1105

        I hit the same problem recently trying to send messages from a PySide2.QRunnable via PyPubSub to the main GUI thread. The only thing I can recommend is to try adapting your code to using the QThreadPool class instead of the multiprocessing module.

        1 Reply Last reply Reply Quote 0
        • L
          LoremIpsum last edited by

          I confirm the same observation, that the script runs with PyQt5 (pyqt5 5.15.4) installed via pip and fails when run with PySide2 (PySide2-5.15.2) installed via pip:

          QObject::moveToThread: Current thread (0x22b951c64b0) is not the object's thread (0x22b951c6c50).
          Cannot move to target thread (0x22b951c64b0)
          
          qt.qpa.plugin: Could not load the Qt platform plugin "windows" in "" even though it was found.
          This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
          
          Available platform plugins are: direct2d, minimal, offscreen, webgl, windows.
          

          Following the advice of this thread (https://forum.qt.io/topic/93085/qt-python-development-pyside2/6), I removed the PySide2 installed via pip and installed the version via conda-forge (v 5.13.2) and was able to run the script. So, it appears a matter of packaging/dependencies rather than a strict inability for PySide2 to handle it or something related to the version.

          1 Reply Last reply Reply Quote 0
          • First post
            Last post