0

私はPyQt4に基づいてGUIを備えた大きなPythonプログラムを作成しました。私は、このパッケージをIPythonノートブック(WindowsでPython 2.7を使った古いインストール)、Jupyterノート(最近Python 3.5をAnacondaでインストールしたもの)、およびコマンドラインでPythonプログラムとして使うことをお勧めします。 Jupyterのノートブックでコードを実行する際に問題が発生しています(下部に直接表示されています)。なぜPyQt4はJupyterとIPythonノートブックの動作が違うのですか?

マイモジュールmymodule.pyは、この(非常に簡略化され、他の多くのpythonファイルからのショーの前におよそ10Kライン)のように見える

from PyQt4 import QtCore, QtGui 

class MyModule(object): 
    def __init__(self): 
     self.window = QtGui.QMainWindow() 
     self.window.show() 

、コマンドラインからの典型的な使用法がある

python myscript.py 

次のファイルでmyscript.py

from PyQt4 import QtCore, QtGui 
import mymodule 

m = mymodule.MyModule() 

APP = QtGui.QApplication.instance() 
APP.exec_() 

この動作は問題ありません。 Guiの対話イベントを通して動作するEventLoopを起動するには、APP.exec_()が必要であることを理解しています。 IPythonのノートブックで

、ユーザーは通常、

import mymodule 
m = mymodule.MyModule() # opens the gui 
# this still leaves the console active to allow things like this: 
m.change_color("red") 

をして私はIPythonは何とかシーンの背後にあるイベントループの世話をすることunderstant問題、せずにこれを実行することができます。

Jupyterノートブックで同じコマンドを実行すると、ウィンドウが開きますが、ユーザーの操作を許可する前にフリーズします。だから私は、ジュピターのノートブックは、そうするように言わなかったので、イベントを適切に扱わないと信じています。私が見つけた1つの方法は、コードを実行する前にコマンド%pylabを実行することです。しかし、プログラムを起動する前に%pylab%matplotlib inlineを連続して実行しているときなど、私は頻繁にこれに関連した問題に遭遇します。これはコードをロードすると凍結します(奇妙なことに、 。また、私のプログラムのユーザには、新しいノートブックに%pylabを強制的に実行させたくない場合もあります(私のプログラムの要件ではないmatlabのインストールが必要だと思うからです)。

Jupyterノートブックで説明されているユーザコードと互換性があるようにするには、mymodule.pyにどのようなコードを追加する必要がありますか?誰もが、IPythonのノートブックやJupyterのノートブックがQEventLoop/QApplication(あるいは重要なコンセプトは何であるか)をどうやって違った方法で管理しているのか、そして魔法のコマンドがこれをどのように混乱させるのかをもっと明確に説明できますか?私はこのために私のプログラムに隠されたバグを恐れており、ユーザを苛立たせないようにできるだけ頑強にしたいと考えています。

答えて

0

ここでは、異なるIPython/Jupyterバージョンと '未加工' Pythonを区別せずにコードを実行できるようにする実用的な解決策を示します。私__init__.pyファイルには、最初にこのセクションが含まれています

# enable IPython QtGui support if needed 
try: 
    from IPython import get_ipython 
    get_ipython().magic('gui qt') 
except BaseException as e: 
    # issued if code runs in bare Python 
    print('Could not enable IPython gui support: %s.' % e) 

# get QApplication instance 
from PyQt4 import QtCore, QtGui 
APP = QtGui.QApplication.instance() 
if APP is None: 
    print('Creating new QApplication instance "mymodule"') 
    APP = QtGui.QApplication(['mymodule']) 

生のPython上で実行中のスクリプトはその後、これだけを必要とします:

import mymodule # imports the above code 
from PyQt4 import QtCore, QtGui 
if __name__ == '__main__': 
    QtGui.QApplication.instance().exec_() 

私は、これは動作しません何のユースケースを発見しました。

関連する問題