Qt 的多处理在 windows 中有效,但在 linux 中无效
Multiprocessing with Qt works in windows but not linux
我正在使用 Qt 开发 GUI 应用程序。
当我尝试使用 multiprocessing
:
创建另一个 QApplication
时出现错误
RuntimeError: A QApplication instance already exists
我有一个主 window,它包含一个用于生成新进程的按钮,以便我可以创建一个新的 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 中实现同样的目标?
也许这对你有帮助:
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 库存在一些差异,因此 linux 应用程序只允许 qapplication 的一个实例。
Here is a mailing list with the same problem => "PySide only supports creating a single persistent instance of QApplication. This singleton exists forever and cannot be deleted."
我在谷歌搜索 python 多处理后发现了。
重点是,取决于平台multiprocessing
支持不同的方式来启动一个新进程。有很好的解释here。
因此,多处理在 Windows 中使用 spawn
作为默认方法,而在 Linux 中使用 fork
作为默认方法。差异:
产卵:
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.
分叉:
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.
于是,我得出了一个简单的解决方案:
在 if __name__=="__main__":
下方添加 multiprocessing.set_start_method('spawn')
。
set_start_method()
是 3.4 版中的新增内容。很高兴有这个更新!我不确定如何在以前的版本中设置此参数。有人知道吗?
我正在使用 Qt 开发 GUI 应用程序。
当我尝试使用 multiprocessing
:
QApplication
时出现错误
RuntimeError: A QApplication instance already exists
我有一个主 window,它包含一个用于生成新进程的按钮,以便我可以创建一个新的 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 中实现同样的目标?
也许这对你有帮助:
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 库存在一些差异,因此 linux 应用程序只允许 qapplication 的一个实例。
Here is a mailing list with the same problem => "PySide only supports creating a single persistent instance of QApplication. This singleton exists forever and cannot be deleted."
我在谷歌搜索 python 多处理后发现了。
重点是,取决于平台multiprocessing
支持不同的方式来启动一个新进程。有很好的解释here。
因此,多处理在 Windows 中使用 spawn
作为默认方法,而在 Linux 中使用 fork
作为默认方法。差异:
产卵:
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.
分叉:
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.
于是,我得出了一个简单的解决方案:
在 if __name__=="__main__":
下方添加 multiprocessing.set_start_method('spawn')
。
set_start_method()
是 3.4 版中的新增内容。很高兴有这个更新!我不确定如何在以前的版本中设置此参数。有人知道吗?