这次传递了一些选项给这个构造作为关键参数。第一个按钮被标记为"QUIT",并被标为红色(fg是foreground的缩写)。第二个被标记为"Hello".俩个按钮都有一个command选项,这个选项指派一个函数或者一个绑定的方法,它们会在按钮被点击的时候被调用。
The button instances are stored in instance attributes. They are both packed, but this time with the side=LEFT argument. This means that they will be placed as far left as possible in the frame; the first button is placed at the frame’s left
edge, and the second is placed just to the right of the first one (at the left edge of the remaining space in the frame, that is). By default, widgets are packed relative to their parent (which is master for the frame widget, and
the frame itself for the buttons). If the side is not given, it defaults to TOP.
按钮实例被存储在实例属性中。它们都被打包,带有一个参数side=LEFT。这就意味着它们被放置在框架的最左侧。第一个按钮被放置在框架的最左边,第二个按钮紧靠第一个按钮的右边(这是框架剩余空间的最左边)。一般来说,组件打包和父组件有关(对于框架组件来说是master,而对于按钮来说是框架本身)。如果side参数没有被给定,默认值是TOP。
The “hello” button callback is given next. It simply prints a message to the console everytime the button is pressed:
接下来指派"hello"按钮的回调函数。它在按钮被按下的时候简单的在console中打印一条信息。
def say_hi(self):
print "hi there,everypne !"
Finally, we provide some script level code that creates a
Tk root widget, and one instance of the
App class using the
root widget as its parent:
最后,提供一些脚本层面的代码创建一个Tk根组件和一个使用根组件作为父组件的App类实例
root = Tk()
app = App(root)
root.mainloop()
root.destory()
The
mainloop call enters the Tk event loop, in which the application will stay until the
quit method is called (just click the QUIT button), or the window is closed.
mainloop调用进入Tk事件循环,直到quit方法被调用(只要点击QUIT按钮)或者窗口被关闭之前应用都会呆在事件循环里。
The destroy call is only required if you run this example under certain development environments; it explicitly destroys the main window when the event loop is terminated. Some development environments won’t terminate the Python process unless
this is done.
只有当在特定的开发环境中运行这个例子的时候才需要调用destroy方法。当事件循环结束的是它会明确的销毁主窗口。如果不这样做的话一些开发环境不会结束Python进程。
More on widget references
In the second example, the frame widget is stored in a local variable named frame, while the button widgets are stored in two instance attributes. Isn’t there a serious problem hidden in here: what happens when the __init__ function
returns and the frame variable goes out of scope?
在第二个例子中,frame组件存储在一个名字为frame的本地变量中,而按钮组件存储在两个实例属性中。这是不是隐藏了一个严重的问题“当__init__函数返回和frame变量超出范围以后会发生什么?
Just relax; there’s actually no need to keep a reference to the widget instance. Tkinter automatically maintains a widget tree (via the master and children attributes of each widget instance), so a widget won’t disappear when
the application’s last reference goes away; it must be explicitly destroyed before this happens (using the destroy method). But if you wish to do something with the widget after it has been created, you better keep a reference to the widget
instance yourself.
放松些,事实上不需要对保持参考组件实例保持一个参考。Tkinter会自动地维护一个组件树(通过每一个组件实例的master和children属性),所以在应用的最后一个参考离开之前这个组件不会消失,必须显示的去销毁才行(使用destroy方法)。但如果想在一个组件被创建后对它做些什么,最好是自己对组件实例保持参考。
Note that if you don’t need to keep a reference to a widget, it might be tempting to create and pack it on a single line:
注意如果不需要对一个组件保持参考,那么可以通过一行尝试创建和pack它。
Button(frame, text="hello", command=self.hello).pack(side=LEFT)
Don’t store the result from this operation; you’ll only get disappointed when you try to use that value (the
pack method returns
None). To be on the safe side, it might be better to always separate construction from packing: