pok*_*oke 16 python tkinter interactive-shell
注意:这有点是对问题的跟进:Tkinter - 我什么时候需要调用mainloop?
通常在使用Tkinter时,您调用Tk.mainloop来运行事件循环并确保正确处理事件并且窗口保持交互而不会阻塞.
在交互式shell中使用Tkinter时,似乎不需要运行主循环.举个例子:
>>> import tkinter
>>> t = tkinter.Tk()
Run Code Online (Sandbox Code Playgroud)
将出现一个窗口,它不会阻止:您可以与它进行交互,拖动它并关闭它.
因此,交互式shell中的某些内容似乎确实创建了一个窗口并在后台运行事件循环.
现在为有趣的事情.再次从上面举例,但是在下一个提示中(不关闭窗口),输入任何内容 - 而不是实际执行它(即不要按回车键).例如:
>>> t = tkinter.Tk()
>>> print('Not pressing enter now.') # not executing this
Run Code Online (Sandbox Code Playgroud)
如果您现在尝试与Tk窗口进行交互,您将看到它完全阻止.因此,当我们向交互式shell输入命令时,我们认为将在后台运行的事件循环停止.如果我们发送输入的命令,您将看到事件循环继续,我们在阻塞期间所做的任何操作都将继续处理.
所以最大的问题是:交互式shell中发生的这种魔力是什么?当我们没有明确地执行它时,什么运行主循环?为什么我们输入命令时需要停止(而不是在执行命令时停止)?
注意:以上在命令行解释器中的工作方式与此类似,而不是IDLE.对于IDLE,我假设GUI实际上并不会告诉底层解释器已经输入了某些内容,而只是将输入保存在本地,直到它被执行.
aba*_*ert 10
它实际上不是一个在这里很重要的交互式解释器,而是在等待TTY上的输入.你可以从这样的脚本中获得相同的行为:
import tkinter
t = tkinter.Tk()
input()
Run Code Online (Sandbox Code Playgroud)
(在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经常打电话.
| 归档时间: |
|
| 查看次数: |
2553 次 |
| 最近记录: |