【问题标题】:Why GASP doesn't work when I run it from IDLE?为什么当我从 IDLE 运行 GASP 时它不起作用?
【发布时间】:2014-07-21 20:27:28
【问题描述】:

我制作了这个脚本:

from gasp import *
begin_graphics()

Circle((200, 200), 60)
Line((100, 400), (580, 200))
Box((400, 350), 120, 100)

update_when('key_pressed')
end_graphics()

当我从终端启动它时,它运行良好。当我从 IDLE 运行它时,它不起作用,我没有得到任何答案(shell 提示符 (>>>) 消失但没有任何反应)。

【问题讨论】:

  • “从 shell 运行”而不是“从终端启动”是什么意思?对于大多数人来说,这些情况通常是相同的——您在终端(Terminal.app、kterm、cmd.exe 本身等)中运行 shell(bash、cmd.exe 等)。如果你的意思不同,请解释一下。
  • @abarnert 我的意思是当您在终端中输入空闲时打开的窗口(该窗口的菜单栏显示 Python 2.7.6 Shell。我的错误,我应该写 IDLE(已更正)。
  • 好的,没问题,这有助于清楚。在这种情况下,我敢打赌它与问题直接相关……

标签: python shell python-idle gasp


【解决方案1】:

通常,您无法在 IDLE 中的嵌入式 Python 解释器中运行 GUI 应用程序,除非您使用的库旨在与 IDLE 集成。或者,更糟糕的是,它可能在一台机器上工作,而在另一台机器上却不行。我将在下面解释原因,但首先请相信这一点。

据我所知,gasp 的文档没有解决这个问题,但类似的库会警告您它们可能无法在 IDLE 中工作(easyguigraphics 的早期版本等)或附带有关如何在 IDLE 中使用它们的特殊说明(例如,graphics 的更高版本)。

现在,也许gasp 应该被设计为与 IDLE 集成,因为它是专门为新手设计的,其中许多新手将使用 Python 内置的 IDE。或者可能不是。但是,即使这应该是真的,这也是gasp 需要处理的事情。提交错误或功能请求,但您需要一些方法来继续工作,直到有人开始编写代码。

这里最简单的解决方案是使用不同的 IDE,它在一个完全独立的进程中运行其交互式 Python 解释器,与您在终端中自己运行它时得到的完全一样。有很多不错的选择,至少是免费的(就像啤酒一样)用于非商业用途(PyCharm、Komodo、Eclipse PyDev、带有您最喜欢的软件包集合的 emacs 等)。尽管 Stack Overflow 不是一个为您挑选最佳的建议的好地方(如果谷歌搜索还不够,请尝试在邮件列表或论坛上询问),但几乎所有这些都可以。

另一种选择:您可能需要考虑在 IDE 旁边运行增强的解释器环境(如 ipython-gtk 或带有较少软件包的 emacs),而不是使用内置于 IDE 中的解释器。当然,它们将不再紧密集成(“IDE”中的“I”),但根据我的经验,即使在整个团队都使用 PyCharm 或 PyDev 的环境中工作,我仍然最终会进行大部分交互式测试在 ipython 中;你可能会发现你也更喜欢那个。或者你可能不会,但试试看吧。


那么,为什么首先会出现问题?

首先,如果您不了解“事件循环”或“运行循环”或“主循环”是什么,请阅读Why your GUI app freezesthe Wikipedia page 或其他一些关于该概念的介绍。

通常,当您运行交互式 Python 解释器时(例如,通过在终端的 bash 或 C: 提示符下键入 python),它会在自己的进程中运行。因此,它可以启动一个 runloop 并且永远不会返回(直到您退出),并且终端不会妨碍您。

但是当您在 IDLE 中运行交互式 Python 解释器时,它实际上与 IDLE 运行在同一个进程中,IDLE 有自己的运行循环。如果你启动了一个 runloop 并且从不返回,IDLE 的 runloop 就不会运行。这意味着它不会响应来自操作系统的事件,例如“刷新窗口”或“准备打开新窗口”,因此从用户(您)的角度来看,IDLE 和您的应用程序都只是冷冻。

解决此问题的一种方法是在您的代码中为您的运行循环生成另一个线程,而不是接管主线程。 (这不适用于所有 GUI 库,但它适用于某些库。这就是 graphics 解决问题的方法。)另一种方法是生成一个全新的子进程来运行您的 GUI。 (这适用于所有 GUI 库,但工作量更大——现在您必须处理进程间通信。对新手友好的 matplotlib 包装器之一就是这样做的。)最后,您可以将运行循环与 IDLE 的 Tkinter 集成通过让一个驱动另一个来运行循环。 (不是所有的 GUI 库都可以这样驱动,但是 Tkinter 可以,并且 IDLE 可以通过猴子补丁来以这种方式工作;graphics 曾经这样做。)但是这些都不是很简单。它们可能是 gasp 本身应该做的事情,而不是你的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 2020-05-27
    • 2021-01-18
    • 1970-01-01
    相关资源
    最近更新 更多