Ich habe ein großes Python-Programm mit GUI basierend auf PyQt4 erstellt. Ich möchte, dass das Paket sowohl in einem IPython-Notizbuch (alte Installation mit Python 2.7 unter Windows) als auch in Jupyter-Notizbuch (Python 3.5 kürzlich mit Anaconda installiert) und als Python-Programm in der Befehlszeile ausgeführt wird. Ich habe Probleme beim Ausführen des Codes im Jupyter-Notizbuch (siehe unten).Warum verhält sich PyQt4 zwischen Jupyter und IPython-Notebook anders?
Mein Modul mymodule.py sieht wie folgt aus (extrem vereinfacht, etwa 10k Zeilen vor der Show aus vielen anderen Python-Dateien):
from PyQt4 import QtCore, QtGui
class MyModule(object):
def __init__(self):
self.window = QtGui.QMainWindow()
self.window.show()
Die typische Verwendung von Befehlszeile ist
python myscript.py
mit der folgenden Datei myscript.py
from PyQt4 import QtCore, QtGui
import mymodule
m = mymodule.MyModule()
APP = QtGui.QApplication.instance()
APP.exec_()
Das funktioniert gut. Ich verstehe, dass APP.exec() benötigt wird, um eine Art von EventLoop zu starten, die durch die Gui-Interaktionsereignisse funktioniert.
In einem IPython Notebook, in der Regel der Benutzer tut
import mymodule
m = mymodule.MyModule() # opens the gui
# this still leaves the console active to allow things like this:
m.change_color("red")
ich ohne Probleme laufen kann dies, wo ich understant dass IPython nimmt irgendwie Pflege der Ereignisschleife hinter der Szene.
Jetzt, die gleichen Befehle in Jupyter Notizbuch ausgeführt, öffnet sich ein Fenster, aber friert ein, bevor jede Benutzerinteraktion zugelassen wird. Ich glaube also, dass das Jupyter Notizbuch die Ereignisse nicht richtig behandelt, weil ich es nicht gesagt habe. Eine Möglichkeit, die ich gefunden habe, ist die Ausführung des Befehls %pylab
vor dem Ausführen meines Codes. Ich stoße jedoch häufig auf damit zusammenhängende Probleme, zum Beispiel wenn ich %pylab
und %matplotlib inline
in direkter Folge vor dem Start meines Programms starte, führt das wieder zum Einfrieren, sobald ich meinen Code geladen habe (kurioserweise funktioniert die umgekehrte Reihenfolge der beiden magischen Befehle wieder) . Außerdem möchte ich den Benutzer meines Programms nicht dazu zwingen,% pylab in jedem neuen Notizbuch auszuführen, wenn es vermieden werden kann (auch weil ich glaube, dass dies eine Matlab-Installation erfordert, was für mein Programm nicht erforderlich ist).
Welchen Code muss ich in mymodule.py hinzufügen, um die Kompatibilität mit dem beschriebenen Benutzercode im Jupyter Notebook herzustellen? Kann jemand klarer erklären, wie IPython Notebook und Jupyter Notebook die QEventLoop/QApplication (oder was ist das wichtige Konzept hier) anders handhaben und wie die magischen Befehle damit umgehen? Ich habe deshalb Angst vor versteckten Fehlern in meinem Programm und möchte es so robust wie möglich machen, um die Benutzer nicht zu frustrieren.