Skip to content Skip to sidebar Skip to footer

Running A Pyqt Application Twice From One Prompt In Spyder

I run a pyqt4 application in spyder, I exit with QtGui.QMainWindow.close() and it returns me to the spyder python interpreter prompt. However, if I try and run the application agai

Solution 1:

To run the PyQt application again in Spyder, the running application must be deleted/destroyed but we can't use sys.exit() because it will try to close Python. One solution that works for me (Python 3.4.1, Spyder 2.3.5.2, PyQt 4.10.4) is to use QtCore.QCoreApplication.instance().quit() and deleteLater as shown in this example:

import sys
from PyQt4 import QtGui, QtCore

classWindow(QtGui.QMainWindow):
    """PyQt app that closes successfully in Spyder.
    """def__init__(self):
        super().__init__()
        self.setGeometry(200, 100, 400, 300)
        self.button()

    defbutton(self):
        btn = QtGui.QPushButton('Quit', self)
        btn.setGeometry(150, 125, 100, 50)
        btn.clicked.connect(self.quitApp)

    defquitApp(self):
        QtCore.QCoreApplication.instance().quit()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    app.aboutToQuit.connect(app.deleteLater)
    win = Window()
    win.show()
    app.exec_()

Solution 2:

I have experienced the same problem but never really found a true fix. However, I have found a workaround that solves the problem for me, and also works for the sample code in Eelco van Vliet's answer.

The problem seems to be that there is a global QApplication stored in the Python interpreter that is not destroyed between invocations of the program. Instead of instantiating a new QApplication at the start of execution, I check to see if this exists and if it does, I use the existing one rather than creating a new one:

if __name__=="__main__":
    if QCoreApplication.instance() != None:
        app = QCoreApplication.instance()
    else:
        app = QApplication(sys.argv)
    form = Form()
    form.show()
    app.exec_()

Solution 3:

This actually appears to a problem with the IPython kernel and its interaction with PyQt. Basically, IPython seems to hang on to the Qt instance and it needs to get cleared before being reinstantiated. This can be done quite simply by rebinding the variable holding the Qt instance to something else:

app = 0
app = QtGui.QApplication([])
...
sys.exit(app.exec_())

This is derived from here, which is derived from (and more fully explained) here.

Solution 4:

I had the same problem. The simple example below reproduces the issue (using python 3.4)

When you run this this the first time it works, closing the window and running the second time fails. You can use the reset kernel in spyder, but this slows down development time.

What works for me is to type

%reset

on the command line of the current kernel. This will reset the variables QtCriticalMsg, QtSystemMsg, etc. After that you can rerun your code.

Although this is slightly faster than restarting the kernel, it is still annoying. Apparently the Qt variables are not cleared from the memory after closing the window. Anybody a suggestion how to force a clean memory from the program after exitting ? This would probably prevent having to type reset each time and solve the issue

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Form(QDialog):

    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.setAttribute(Qt.WA_DeleteOnClose)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|
                                     QDialogButtonBox.Cancel)
        grid = QGridLayout()
        grid.addWidget(buttonBox, 4, 0, 1, 2)
        self.setLayout(grid)

        self.connect(buttonBox, SIGNAL("accepted()"),
                     self, SLOT("accept()"))
        self.connect(buttonBox, SIGNAL("rejected()"),
                     self, SLOT("reject()"))
        self.setWindowTitle("Set Number Format (Modal)")


if __name__=="__main__":
    app = QApplication(sys.argv)
    form = Form()
    form.show()
    app.exec_()

Post a Comment for "Running A Pyqt Application Twice From One Prompt In Spyder"