我正在使用Qt开发GUI应用程序。
当我尝试使用QApplication
创建另一个multiprocessing
时出现错误:
RuntimeError:QApplication实例已存在
我有一个主窗口,其中包含一个用于生成新进程的按钮,以便我可以创建一个新的GUI实例。基本上是这样的:
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_())
它适用于Windows但在Linux中提供RuntimeError
。
这是因为Windows和Linux之间的多处理机制存在差异吗?我怎么能在Linux中实现同样的目标呢?
答案 0 :(得分:7)
我在一些谷歌搜索python多处理后想通了。
重点是,取决于平台multiprocessing
支持不同的方式来启动新进程。有一个很好的解释here。
因此,多处理使用spawn
作为Windows中的默认方法,而使用fork
作为Linux中的默认方法。差异:
菌种:
父进程启动一个新的python解释器进程。子进程只会继承运行进程对象
run()
方法所需的那些资源。特别是,不会继承父进程中不必要的文件描述符和句柄。
叉:
父进程使用
os.fork()
来分叉Python解释器。子进程在开始时实际上与父进程相同。父进程的所有资源都由子进程继承。
因此,我找到了一个简单的解决方案:
在multiprocessing.set_start_method('spawn')
下面添加if __name__=="__main__":
。
set_start_method()
是3.4版中的新功能。很高兴有这个更新!我不知道如何在以前的版本中设置此参数。有人知道吗?
答案 1 :(得分:0)
也许这有助于你:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import multiprocessing
import sys
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
btn = QPushButton('run new instance')
self.windows = []
btn.clicked.connect(self.create_window)
self.setCentralWidget(btn)
def create_window(self):
self.windows.append(ChildWindow())
class ChildWindow(QMainWindow):
def __init__(self, parent=None):
super(ChildWindow, self).__init__(parent)
self.show()
if __name__=="__main__":
app=QApplication(sys.argv)
ex = MainWindow()
ex.show()
sys.exit(app.exec_())
我使用了pyqt4,因为我不想为此安装pyside。我认为qt-librarys在跨平台上存在一些差异,因此linux应用程序只允许qapplication的一个实例。
Here is a mailing list with the same problem => " PySide仅支持创建QApplication的单个持久化实例。这个单例永远存在,无法删除。"