PySide2 with Python3 Built-In Multiprocessing



  • 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


 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.