我什么时候需要在Tkinter应用程序中调用mainloop?

我见过的每一个tkinter.mainloop教程声称, tkinter.mainloop必须被调用来绘制窗口和事件来处理,而且他们总是调用这个函数,即使在hello world程序中。 但是,当我在交互式shell中尝试这些时,窗口绘制正确,而不必调用主循环。 这个在tkinter中embeddedmatplotlibgraphics的例子产生了一个相对复杂的应用程序,用于在tkinter窗口中平移,缩放和调整graphics的大小,再次,如果你去掉mainloop调用并在交互式shell中运行代码, 。 当然,如果我在交互式shell之外运行脚本(在mainloop被移除的情况下),程序结束得太快以至于看不到会发生什么,但是如果我添加一个调用来保存程序打开一切正常的工作(我正在运行python 3.2.2在Linux上)。

那么主循环究竟做了什么,什么时候需要调用呢?

编辑:澄清,如果我打开GNOMEterminal和types

 $python3 >>> import tkinter >>> root = tkinter.Tk() 

一个窗口立即出现,而不必调用主循环,更复杂的tkinterfunction似乎也可以工作(例如,向窗口添加button)。 在IDLE中,调用mainloop是必要的。 根据我的理解,任何东西都不应该被绘制,直到主循环被调用,才能处理任何事件。

您的主要问题的答案是,当您准备好运行应用程序时,您必须调用一次mainloop。

mainloop循环mainloop是一个无限循环,看起来大致像这样(这些不是方法的实际名称,名称仅仅是为了说明这一点):

 while True: event=wait_for_event() event.process() if main_window_has_been_destroyed(): break 

在这种情况下,“事件”是指用户交互(鼠标点击,按键等)以及来自工具包或OS /窗口pipe理器的绘制或重绘小部件的请求。 如果该循环没有运行,事件不会得到处理。 如果事件没有得到处理,屏幕上就不会显示任何内容,除非您有自己的无限循环运行,否则程序可能会退出。

那么,为什么你不需要交互调用呢? 这只是一个方便,因为否则一旦调用mainloop ,就不可能input任何命令,因为mainloop运行直到主窗口被销毁。

将程序与交互式GUI进行比较,以计算第100个斐波纳契数。 后面所有的程序都要按照从上到下的顺序执行一系列的步骤。 这套步骤及其顺序可以事先知道,不pipe你运行多less次程序,它都会保持不变。

但是GUI程序是不同的:在任何时刻,它必须能够处理各种不同types的事件和交互。 这个要求通常使用称为事件循环的编程构造来实现。 事件循环是程序的中央控制结构。 它等待事件发生,然后分派适当的处理程序。

你没有提到你正在使用哪个交互式shell,但我猜它是空闲的。 IDLE本身是一个Tkinter程序,它已经有一个事件循环。 所以可能你正在input到shell中的Tkinter代码已经绑定到IDLE的事件循环。

如下:

 from tkinter import * tk = Tk() canvas = Canvas(tk, width=500, height=500) canvas.pack() canvas.create_line(0, 0, 500, 500) mainloop() 

我已经决定了,不是直接在mainloop中直接插入脚本中的任何地方,而是将其添加为atexit一部分 – 也就是说,当Python解释器决定开始closures时,它将进入Tk主循环。 这样就可以阻止它完成closures序列,直到用户实际告诉Tk退出(IE,在Mac上使用命令-Q,或者在Windows中单击红色的X)。

 from Tkinter import Tk root = Tk() import atexit atexit.register(root.mainloop) 

似乎没有必要从系统命令行调用mainloop 。 Python解释器将继续运行,因为它正在等待你的input(直到你运行exit() )。