マルチプロセッシング プロセスによって更新される PySide GUI を作成しようとしています。たとえば、計算後に更新されるウィンドウにテキストを表示する PySide GUI です。QThread を使用することで、問題なく GUI を更新できます。ただし、QThread の代わりにマルチプロセッシング プロセスを使用して同じことを行おうとすると (sys.exit の直前の 2 行のコードを参照)、エラーが発生します。最小限の例を次に示します。
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 はメイン プロセスからしか操作できないため、新しいプロセスから 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 で計算を実行することでした。しかし、計算自体はかなり重いので、完全に別のプロセス (およびコア) で実行する必要があります。ありがとう!