I am using Qt for developing GUI applications.
I get an error when I try to create another QApplication
using multiprocessing
:
RuntimeError: A QApplication instance already exists
I have a main window, which contains a button for spawning a new process so that I can create a new GUI instance. Basically like this:
from PySide.QtCore import *
from PySide.QtGui import *
import multiprocessing
import sys
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
btn = QPushButton('run new instance')
btn.clicked.connect(self.create_daemon)
self.setCentralWidget(btn)
def create_daemon(self):
p = multiprocessing.Process(target=new_window)
p.start()
def new_window():
app=QApplication(sys.argv)
ex = MainWindow()
ex.show()
sys.exit(app.exec_())
if __name__=="__main__":
app=QApplication(sys.argv)
ex = MainWindow()
ex.show()
sys.exit(app.exec_())
It works in Windows but gives the RuntimeError
in Linux.
Is this because of difference in multiprocessing mechanism between Windows and Linux? How could I achieve the same thing in Linux?
I figured out after some googling of python multiprocessing.
The point is, depends on the platform multiprocessing
supports different ways to start a new process. There is a very good explanation here.
So, what happens is that multiprocessing use spawn
as the default method in Windows, while use fork
as the default method in Linux. The Difference:
spawn:
The parent process starts a fresh python interpreter process. The child process will only inherit those resources necessary to run the process objects
run()
method. In particular, unnecessary file descriptors and handles from the parent process will not be inherited.
fork:
The parent process uses
os.fork()
to fork the Python interpreter. The child process, when it begins, is effectively identical to the parent process. All resources of the parent are inherited by the child process.
Thus, I came to a simple solution:
add multiprocessing.set_start_method('spawn')
bellow if __name__=="__main__":
.
set_start_method()
is new in version 3.4. Great to have this update! I am not sure how to set this parameter in previous versions. Anyone knows?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With