Chinaunix首页 | 论坛 | 博客
  • 博客访问: 72570
  • 博文数量: 26
  • 博客积分: 628
  • 博客等级: 中士
  • 技术积分: 315
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-22 11:57
文章分类

全部博文(26)

文章存档

2012年(4)

2011年(19)

2010年(3)

我的朋友

分类: Python/Ruby

2011-04-25 10:23:27


终于该让我们的按钮们干点实事了. 我们把焦点再转回之前的最后两个基本界面任务中来 -- 编写事件处理器, 和将控件和事件绑定到对应的事件处理器上来.

注意这个程序中, 我们会将之前创建的所有按钮都去掉, 回到一个最简单的情况, 即界面上只有两个按钮: "OK"和"Cancel".

你应该还记得上个程序中我们说过, 基本的界面任务中有一个叫"绑定". "绑定"是定义在下列各项之间建立连接的过程:

* 控件
* 事件
* 事件处理器

一个事件处理器一般是一个方法或函数, 用于当事件发生时处理对应的事件. [在java中, 事件自带器被称为"监听器". 我很喜欢这么叫, 因为它清晰的描述了它们干的活 -- "监听"事件, 并反馈.]

在tkinter中, 创建一个绑定是通过调用bind()方法来实现的, 它是每个tkinter控件都有的方法. 用法如下:

widget.bind(event_type_name, event_handler_name)

这种绑定叫"事件绑定".

[还有一个方法可以绑定一个事件处理器到一个控件上. 它被称为"命令绑定", 我们会在下面几个程序中都会看到它的身影. 但是现在, 我们先看看事件绑定. 一旦我们明白了事件绑定, 那命令绑定就很好理解了.]

开始前, 我们先解释一个可能发生混淆的地方. "button"这个词会用来表示两个完全不同的事件: (1) 一个按钮控件 -- 一个在显示器上显示的GUI控件 --, (2) 你鼠标上的一个键 -- 你所按下的鼠标键的类型值. 为了避免这种混淆, 我会用"button widget"和"mouse button"这样的叫法来加以区分.

(1)
我们将button1控件上的""事件(点击鼠标左键)绑定到"self.button1Click"上. 当button1被鼠标左键点击后, self.button1Click()方法就会被调用.

(3)
注意, 虽然在执行"bind"操作时没有指定, 但self.button1Click()函数还是需要两个参数. 第一个肯定是"self", 第二个是事件对象. 当发生某事件时, 绑定技术总会隐含的传入一个事件对象作为参数.

在python/tkinter中, 当事件发生, 它会发生一个特定的事件对象. 事件对象是非常有用的, 因为它承载了所有的信息和一些很用的方法. 你可以得到这个事件对象是哪种事件产生的, 产生该事件的控件, 等等.

(4)
那么, 当button1被按下时, 我们想干点啥呢? 嗯, 我们让它先干点简单的吧. 就让它每次将自己的颜色从绿到黄循环转换吧.

(2)
我们让button2("Goodbye!"按钮)来干一些有用的事. 在这儿我们让它来关闭整个窗口. 所以我们把button2上的左键按下绑定到button2Click()上, 然后

(6)
我们让button2Click()来关闭根窗口(myapp的父窗口). 它会有一个副作用, 即销毁所有与root相关的子窗口. 简单的说, 就是整个GUI窗口都会被销毁.

当然, 要做这个myapp就需要知道它的父亲是谁. 所以

(7)
我们在它的构造函数中, 来记住父窗口.

*代码示例*

程序运行时, 会有两个按钮. 按"OK"会改变它的颜色. 按"Cancel"会退出整个程序.

当我们的窗口打开时, 如果你按TAB键, 你会发现焦点会在两个按钮间进行切换. 但是如果你按ENTER/RETURN/键却不会发生任何事. 这是因为我们绑定的只是鼠标按键, 而不是键盘事件. 我们下一步也会将键盘事件绑定到按钮上.

最后, 注意两个按钮的文本不一样长, 所以两个按钮的大小也不同. 这样十分难看. 我们在下一个程序中就来解决这个问题.

  1. from Tkinter import *

  2. class MyApp:
  3.     def __init__(self, parent):
  4.         self.myParent = parent ### (7) remember my parent, the root
  5.         self.myContainer1 = Frame(parent)
  6.         self.myContainer1.pack()
  7.         
  8.         self.button1 = Button(self.myContainer1)
  9.         self.button1.configure(text="OK", background= "green")
  10.         self.button1.pack(side=LEFT)    
  11.         self.button1.bind("", self.button1Click) ### (1)
  12.         
  13.         self.button2 = Button(self.myContainer1)
  14.         self.button2.configure(text="Cancel", background="red")
  15.         self.button2.pack(side=RIGHT)
  16.         self.button2.bind("", self.button2Click) ### (2)
  17.         
  18.     def button1Click(self, event): ### (3)
  19.         if self.button1["background"] == "green": ### (4)
  20.             self.button1["background"] = "yellow"
  21.         else:
  22.             self.button1["background"] = "green"
  23.     
  24.     def button2Click(self, event): ### (5)
  25.         self.myParent.destroy() ### (6)

  26.         
  27. root = Tk()
  28. myapp = MyApp(root)
  29. root.mainloop()
阅读(1139) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~