为什么PYQT4在Jupyter和Ipython笔记本之间的行为会有所不同



我已经创建了一个基于pyqt4的GUI的大型Python程序。我希望该软件包可以在ipython笔记本电脑(Windows上的Python 2.7(,Jupyter Notebook(最近使用Anaconda安装的Python 3.5(中运行,以及作为命令行上传递的Python程序。我在Jupyter笔记本中运行代码时遇到问题(直接在底部查看(。

我的模块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_()

这很好。我知道需要app.exec_((来启动通过GUI交互事件工作的某种事件loop。

在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以某种方式照顾了现场的事件。

现在,在Jupyter笔记本电脑中运行相同的命令,窗口打开,但在允许任何用户交互之前冻结。因此,我相信Jupyter笔记本无法正确处理事件,因为我没有告诉它。我发现的一种方法是在运行代码之前执行命令%pylab。但是,我经常会遇到与此相关的问题,例如,在启动程序之前直接连续运行%pylab%matplotlib inline时,一旦我加载代码,这会再次冻结(奇怪的是,将两个魔法命令的顺序倒入再次工作((。另外,如果可以避免,我不想强迫我的程序的用户在每个新笔记本电脑中执行%pylab(我相信这需要MATLAB安装,这不是我程序的要求(。

我必须在myModule.py中添加哪个代码才能使内容与Jupyter笔记本中所述的用户代码兼容?谁能更清楚地解释Ipython笔记本和Jupyter笔记本电脑如何管理Qeventloop/Qapplication(或其他重要的概念(不同,以及魔术如何命令这一点?因此,我担心程序中的隐藏错误,并且希望使其尽可能强大,以免使用户感到沮丧。

这是一个工作解决方案,允许在不区分不同的ipython/jupyter版本和'raw'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_()

我发现没有用的情况不起作用。

最新更新