Python Tkinter 应用窗口

Application Windows

Base Windows

In the simple examples we’ve used this far, there’s only one window on the screen; the root window. This is automatically created when you call the Tk constructor, and is of course very convenient for simple applications:

在前面的简单示例中,在屏幕上仅有一个窗口:根窗口。根窗口可以在调用Tk构造器的时候会自动创建,这对于简单的应用程序来说是很实用的。

from Tkinter import *

root = Tk()

# create window contents as children to root...

root.mainloop()

If you need to create additional windows, you can use the Toplevel widget. It simply creates a new window on the screen, a window that looks and behaves pretty much like the original root window:

如果需要创建额外的窗口,可以使用Toplevel组件。它简单的在屏幕上创建一个新的窗口,这个窗口的外观和行为都跟原始的根窗口都很相似。

from Tkinter import *

root = Tk()

# create root window contents...

top = Toplevel()

# create top window contents...

root.mainloop()


There’s no need to use pack to display the  Toplevel, since it is automatically displayed by the window manager (in fact, you’ll get an error message if you try to use  pack or any other geometry manager with a  Toplevel widget).

无需使用pack去显示Toplevel,因为它会被窗口管理器自动的显示(实际上如果使用pack或者其他Toplevel组件的几何管理器,会出现一条错误信息)

Menus

Tkinter provides a special widget type for menus. To create a menu, you create an instance of the Menu class, and use add methods to add entries to it:

Tkinter为menus提供了一个特殊的组件。可以通过创建一个Menu类的实例去创建一个menu,然后使用add方法去添加入口。

  • add_command(label=string, command=callback) adds an ordinary menu entry.

  • add_command(label=string, command=callback) 添加一个普通的菜单入口.

  • add_separator() 添加一个分隔线。用于归类菜单入口。

  • add_cascade(label=string, menu=menu instance)添加一个子菜单(另一个Menu实例)。它可以是一个下拉菜单,也可以是一个折叠菜单,这取决于parent.

Here’s an example:

这里有一个例子:

Creating a small menu
</pre>

from Tkinter import *

def callback():
    print "called the callback!"

root = Tk()

# create a menu
menu = Menu(root)
root.config(menu=menu)

filemenu = Menu(menu)
menu.add_cascade(label="File", menu=filemenu)
filemenu.add_command(label="New", command=callback)
filemenu.add_command(label="Open...", command=callback)
filemenu.add_separator()
filemenu.add_command(label="Exit", command=callback)

helpmenu = Menu(menu)
menu.add_cascade(label="Help", menu=helpmenu)
helpmenu.add_command(label="About...", command=callback)

mainloop()

In this example, we start out by creating a Menu instance, and we then use the config method to attach it to the root window. The contents of that menu will be used to create a menubar at the top of the root window. You don’t have to pack the menu, since it is automatically displayed by Tkinter.

在这个例子中,开始创建了一个Menu实例,然后使用config方法把它依附到根窗口。这个menu的内容是在根窗口的最上面创建一个菜单栏。无需使用pack,因为Tkinter会自动的显示它。

Next, we create a new Menu instance, using the menubar as the widget parent, and the add_cascade method to make it a pulldown menu. We then call add_command to add commands to the menu (note that all commands in this example use the same callback), and add_separator to add a line between the file commands and the exit command.

然后创建了一个新的Menu实例,使用菜单栏作为这个组件的parent,使用add_cascade方法使之成为一个下拉菜单。调用add_command方法为这个菜单添加命令行(注意这个例子中所有的命令行都是使用同一个callback),使用add_separator在file命令行和exit命令行直接添加一个分割线。

Finally, we create a small help menu in the same fashion.

最后用同样的方式创建了一个小help菜单。

Toolbars

Many applications place a toolbar just under the menubar, which typically contains a number of buttons for common functions like open file, print, undo, etc.

许多应用程序把工具栏放置到菜单栏下方,这些工具栏通常包含一些普通的功能按钮,比如打开文件、打印、撤销等等

In the following example, we use a Frame widget as the toolbar, and pack a number of ordinary buttons into it.

在下面这个例子里,使用了一个Frame组件作为工具栏,并且放置了一些原生的按钮在里面

Creating a simple toolbar

from Tkinter import *

root = Tk()

def callback():
    print "called the callback!"

# create a toolbar
toolbar = Frame(root)

b = Button(toolbar, text="new", width=6, command=callback)
b.pack(side=LEFT, padx=2, pady=2)

b = Button(toolbar, text="open", width=6, command=callback)
b.pack(side=LEFT, padx=2, pady=2)

toolbar.pack(side=TOP, fill=X)

mainloop()

The buttons are packed against the left side, and the toolbar itself is packed against the top most side, with the fill option set to X. As a result, the widget is resized if necessary, to cover the full with of the parent widget.

这些按钮被靠最左边放置,工具栏本身则紧靠最顶端,选项fill设置为X。为了去填满整个父组件,这些组件可能会重置大小。

Also note that I’ve used text labels rather than icons, to keep things simple. To display an icon, you can use the PhotoImage constructor to load a small image from disk, and use the image option to display it.

这里使用了文件标签而非图标文件,这样做事为了保持简洁。如果想使用一个图标,可以使用PhotoImage构造器从硬盘加载一个小图像,然后使用image选项去展示它。

Status Bars

Finally, most applications sport a status bar at the bottom of each application window. Implementing a status bar with Tkinter is trivial: you can simply use a suitably configured Label widget, and reconfigure the text option now and then. Here’s one way to do it:

通常大部分的应用程序都会在每个应用窗口的底部展示一个状态栏。使用Tkinter去部署一个状态栏是很简单的:使用一个大小合适的Label组件,偶尔需要重新编辑一下text选项。

 
status = Label(master, text="", bd=1, relief=SUNKEN, anchor=W)
status.pack(side=BOTTOM, fill=X)

If you wish to be fancy, you can use the following class instead. It wraps a label widget in a convenience class, and provides set and clear methods to modify the contents.

如果想更漂亮些,可以使用下面的类。它把一个label组件转换成一个常用类。并且提供了set和clear方法去修改内容。

A Status Bar Class (File: tkSimpleStatusBar.py)

class StatusBar(Frame):

    def __init__(self, master):
        Frame.__init__(self, master)
        self.label = Label(self, bd=1, relief=SUNKEN, anchor=W)
        self.label.pack(fill=X)

    def set(self, format, *args):
        self.label.config(text=format % args)
        self.label.update_idletasks()

    def clear(self):
        self.label.config(text="")
        self.label.update_idletasks()

The set method works like C’s printf function; it takes a format string, possibly followed by a set of arguments (a drawback is that if you wish to print an arbitrary string, you must do that as set(“%s”, string)). Also note that this method calls the update_idletasks method, to make sure pending draw operations (like the status bar update) are carried out immediately.

这个set方法就像C语言里面的printf函数,它展示一个格式化的可能带有很多参数的字符串(一个缺点就是如果想打印任意字符串,必须使用set(“%s”,string))。为了确保绘画操作能及时被展示出来,这个方法使用了update_idletasks方法。

But the real trick here is that we’ve inherited from the Frame widget. At the cost of a somewhat awkward call to the frame widget’s constructor, we’ve created a new kind of custom widget that can be treated as any other widget. You can create and display the status bar using the usual widget syntax:

但真正的戏法是继承自Frame组件,对frame组件构造器的不灵活调用的代价就是我们创建了一类定制组件,可以使用常规窗口部件语法去创建和展示一个状态栏。

status = StatusBar(root)
status.pack(side=BOTTOM, fill=X)

We could have inherited from the Label widget itself, and just extended it with set and clear methods. This approach have a few drawbacks, though:

继承自Label组件本身,使用set和clear方法去扩展它。这种方法有一些缺点:

  • It makes it harder to maintain the status bar’s integrity. Some team members may cheat, and use config instead of set. That’s not a big deal, until the day you decide to do some extra processing in the set method. Or the day you decide to use a Canvas widget to implement a fancier status bar.

  • 它使得维护状态栏的一致性变得困难。一些团队成员可能欺骗,使用config而非set。在你决定对set方法做一些额外处理或者使用Canvas组件去部署一个更加漂亮的状态栏之前,这都不是一个大问题。

  • It increases the risk that your additional methods conflict with attributes or methods used by Tkinter. While the Frame and Toplevel widgets have relatively few methods, other widgets can have several dozens of widget specific attributes and methods.

  • 它增加了这些额外方法和Tkinter方法和属性冲突的风险。因为Frame和Toplevel组件拥有比较少的方法,而其他的组件则可能拥有数打的具体的属性和方法。

  • Future versions of Tkinter may use factory functions rather than class constructors for most widgets. However, it’s more or less guaranteed that such versions will still provide Frame and Toplevel classes. Better safe than sorry, in other words.

  • 对于大多数组件,未来版本的Tkinter可能使用工厂函数而非类构造器。多少有一些保证,这些版本都会继续提供Frame和Toplevel类。总之,有备无患。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值