LeoAnth
LeoAnth

Reputation: 127

closing a pyqt widget in ipython notebook without using sys.exit()

I am trying to run through some pyqt5 tutorials in the ipython notebook, but have an issue where every second time I run a code block the kernal undergoes a forced restart. Here is the smallest code which causes the problem:

import sys
from PyQt5.QtWidgets import QApplication, QWidget

if __name__ == '__main__':

    app = QApplication(sys.argv)

    w = QWidget()
    w.setWindowTitle('Simple')
    w.show()

    sys.exit(app.exec_())

I am running the Ipython3 notebook and python 3, as well as pyqt5, and using Ubuntu 14.04. It should be noted that this problem does not occur when running this same code via a script in terminal.

Some other unrelated questions have suggested that my problem could be due to sys.exit() messing with the instance of python(I hope that is the correct term) instead of just closing my pyqt application. This happens the first time I run the code, so that the second time it runs the kernel is forced to restart. Is this the problem? and if so how do I work around this?

If more info is required, please ask.

Upvotes: 2

Views: 2400

Answers (1)

Ron Schutjens
Ron Schutjens

Reputation: 81

I tried out Taar's solution but still got a dead kernel after calling the cell with main more than twice.The problem is creating multiple Qapplications, this crashes the notebook.

There is multiple solutions I found, but to just being able to run a qt application use the following in the first cell:

%gui qt
from PyQt5.QtWidgets import QApplication, QWidget

and in the second cell:

 if __name__ == '__main__':

        w = QWidget()
        w.setWindowTitle('Simple')
        w.show()

You can call the second cell as many times as you want and it will work. the magic line %gui qt opens a QApplication for your notebook.

If you need more control (like being able to exit() it) there is various solutions that amount to checking if there is a Qapplication instance open. Here is an example:

import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5 import QtCore

second cell:

if __name__ == '__main__':

    app = QtCore.QCoreApplication.instance()
    if app is None:
        app = QApplication(sys.argv)

    w = QWidget()
    w.setWindowTitle('Simple')
    w.show()

    app.exec_()

This method does require closing the window before rerunning it (else they will be queued up: run 3x without closing the window, now you need to close the window 3x in a row). It will at least get you started with a properly loaded screen upon executing the cell. (anyone feel welcome to correct this example).

Some references for the second example: here, and here. But I don't know enough about how the qt gui interacts with the notebook to solve any problem with the above example.

Upvotes: 3

Related Questions