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
toPySide2
, 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
andGui
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
-
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.
-
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.