I'm trying to create a PySide GUI that gets updated by a multiprocessing Process, for example a PySide GUI that displays text in a window that gets updated after some computation. By using a QThread, I am able to update the GUI without any problems. However, if I try to do the same using a multiprocessing Process instead of a QThread (cf. the two lines of code just before sys.exit), I get an error. Here's a minimal example:
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_())
The problem is that apparently the GUI can only be manipulated from the main process, so trying to manipulate it from a new process raises this error:
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.
My immediate response was- just run the computation in a QThread. But the computation itself is pretty heavy and so I really need to run it in a separate process (and core) altogether. Thanks!