您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

有什么魔术可以阻止Tkinter程序在交互式shell中阻塞?

有什么魔术可以阻止Tkinter程序在交互式shell中阻塞?

实际上,这并不是在这里重要的交互式解释器,而是在TTY上等待输入。您可以从如下脚本中获得相同的行为:

import tkinter
t = tkinter.Tk()
input()

(在Windows上,您可能必须在pythonw.exe中而不是python.exe中运行该脚本,但是否则,您不必执行任何特殊操作。)

那么它是怎样工作的?最终,诀窍归结为PyOS_InputHook-readline模块工作的方式相同。

如果stdin是TTY,则每次它尝试使用input()code模块的各个位,内置REPL等来获取一行时,Python都会调用已安装的任何内容PyOS_InputHook而不仅仅是从stdin中读取。

它可能更容易理解什么readline:它试图select在标准输入或类似,循环为每个输入新的字符,或每0.1秒或每一个信号。

什么Tkinter确实是相似的。因为它必须处理Windows,所以它更加复杂,但是在* nix上,它的行为与相似readline。除了Tcl_DoOneEvent每次在循环中都在调用

这就是关键。Tcl_DoOneEvent重复调用与执行完全相同mainloop

(线程使一切变得更复杂,当然,但是让我们假设你还没有创建任何后台线程。在你真正的代码,如果你想创建后台线程,你只需要一个线程所有的Tkinter东西,上街区mainloop反正, 对?)

因此,只要您的Python代码将大部分时间都花在了TTY输入上(就像交互式解释器通常那样),则Tcl解释器会不断变化,而GUI也会响应。如果您在除TTY输入之外的其他位置上使Python解释器块阻塞,则Tcl解释器未运行,并且您的GUI没有响应。

如果您想在纯Python代码中手动执行相同的操作怎么办?如果您想例如将Tkinter GUI和select基于网络的客户端集成到单线程应用程序中,就需要这样做,对吗?

这很容易:从另一个驱动一个循环。

您可以select设置0.02s的超时(认输入挂钩使用相同的超时),并在t.dooneevent(Tkinter.DONT_WAIT)每次循环中调用

或者,您也可以通过致电来让Tk开车mainloop,但是请使用after和朋友来确保您select经常打电话。

其他 2022/1/1 18:37:12 有454人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶