我正在尝试创建一个由多处理进程更新的 PySide GUI,例如在经过一些计算后更新的窗口中显示文本的 PySide GUI。通过使用 QThread,我可以毫无问题地更新 GUI。但是,如果我尝试使用多处理进程而不是 QThread 来执行相同的操作(参见 sys.exit 之前的两行代码),我会收到错误消息。这是一个最小的例子:
import sys
from PySide import QtCore, QtGui
from multiprocessing import Process
import time
class GUI(QtGui.QMainWindow):
def __init__(self):
super(GUI, self).__init__()
self.initUI()
def initUI(self):
self.text = "normal text"
self.setGeometry(300, 300, 500, 300)
self.setWindowTitle('TestGUI')
self.show()
def paintEvent(self, event):
qp = QtGui.QPainter()
qp.begin(self)
self.drawText(event, qp)
qp.end()
def drawText(self, event, qp):
qp.setPen(QtGui.QColor(0,0,0))
qp.setFont(QtGui.QFont('Decorative', 50))
qp.drawText(event.rect(), QtCore.Qt.AlignCenter, self.text)
@QtCore.Slot(str)
def setText(self, text):
self.text = text
print self.text
self.repaint()
class Communicate(QtCore.QObject):
updateGUI = QtCore.Signal(str)
class MyThread(QtCore.QThread):
def __init__(self, com):
super(MyThread, self).__init__()
self.com = com
def run(self):
count = 0
while True:
self.com.updateGUI.emit("update %d" % count)
count += 1
time.sleep(1)
def loopEmit(com):
while True:
com.updateGUI.emit(time.ctime())
time.sleep(1)
# Create and show GUI
app = QtGui.QApplication(sys.argv)
gui = GUI()
gui.show()
# connect signal and slot properly
com = Communicate()
com.updateGUI.connect(gui.setText)
thread = MyThread(com)
thread.start() # this works fine
time.sleep(0.5)
p = Process(target=loopEmit, args=[com])
p.start() # this breaks
sys.exit(app.exec_())
问题是显然只能从主进程操作 GUI,因此尝试从新进程操作它会引发此错误:
The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().
Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.
我的直接反应是——只需在 QThread 中运行计算。但是计算本身非常繁重,所以我真的需要完全在一个单独的进程(和核心)中运行它。谢谢!