重要

此文档涵盖 IPython 6.0 及更高版本。从 6.0 版本开始,IPython 不再支持与低于 Python 3.3 的 Python 版本兼容,包括所有版本的 Python 2.7。

如果您正在寻找与 Python 2.7 兼容的 IPython 版本,请使用 IPython 5.x LTS 版本并参考其文档(LTS 是长期支持版本)。

IPython GUI 支持说明

IPython 允许在交互式 IPython 会话中运行 GUI 事件循环。这是使用 Python 的 PyOS_InputHook 钩子完成的,当调用 raw_input() 函数并等待用户输入时,Python 会调用此钩子。IPython 针对 wx、pyqt4 和 pygtk 拥有此钩子的版本。

当在 IPython 中交互使用 GUI 程序时,不应启动 GUI 的事件循环。这是因为 PyOS_Inputhook 本身负责迭代 GUI 事件循环。

IPython 具有为每个 GUI 工具包安装所需的输入钩子以及创建所需的 GUI 主应用程序对象的工具。通常,这些主应用程序对象应仅创建一次,对于某些 GUI 工具包,必须将特殊选项传递给应用程序对象才能使其在 IPython 中正常运行。

我们需要回答以下问题

  • 谁负责创建 GUI 主应用程序对象,是 IPython 还是第三方(matplotlib、enthought.traits 等)?

  • 第三方代码检测 GUI 应用程序对象是否已创建的正确方法是什么?如果已创建,应如何检索现有实例?

  • 在 GUI 应用程序对象已创建的情况下,第三方代码应如何检测 GUI 事件循环是否正在运行。仅调用 GUI 工具包中的相关函数方法(如 IsMainLoopRunning)是不够的,因为这些方法不知道 GUI 事件循环是否通过输入钩子运行。

  • 我们可能需要一种方法,让第三方代码确定它是否在 IPython 中运行。目前,在 IPython 中运行 GUI 代码的唯一方法是使用输入钩子,但最终,基于 GUI 的 IPython 版本将以更传统的方式允许 GUI 事件循环。我们需要一种方法让第三方代码区分这两种情况。

以下是我用来调试此问题的示例代码

from matplotlib import pyplot as plt

from enthought.traits import api as traits

class Foo(traits.HasTraits):
    a = traits.Float()

f = Foo()
f.configure_traits()

plt.plot(range(10))