Multiple instances of QApplication in one process
I’m working on a PyQt 4 application for my employer Chess. Of course I’m writing plenty of unit tests for it as well. Those tests have to be cleanly separated from each other, so every test that requires the entire application to be up and running should have its own instance. And this is where it gets tricky, as Qt (and thus PyQt) assumes that there will only be one application, and if that application quits the process quits.
In my unit tests, this is not the case. Every test can potentially start and stop an application, and the test suite will continue running. This caused a segmentation fault (a.k.a. segfault) the second time the QApplication closed.
After a lot of puzzling I found out that QtGui.qApp needs to refer to the
running QApplication instance, and be set to None
when the application has
been closed. After I implemented this the segfaults went away.
This is my ApplicationTest
mix-in class that I use for controlling my
application lifespan. It contains a little trick to stop the application as soon
as it has started:
class MyApplicationClass(QtGui.QApplication):
started = QtCore.pyqtSignal()
def exec_(self):
self.started.emit()
return QtGui.QApplication.exec_()
class _ApplicationTest(object):
'''Mix-in class that can start and stop an application.'''
APP_CLASS = MyApplicationClass
def __init__(self):
self.app = None
QtGui.qApp = None
def create_app(self):
'''Creates and returns a new application'''
self.app = self.APP_CLASS([])
QtGui.qApp = self.app
return self.app
def stop_app(self):
'''Stops the application.'''
if not self.app: return
self.app.started.connect(self.app.quit,
type=QtCore.Qt.QueuedConnection)
self.app.exec_()
QtGui.qApp = None
self.app = None