首页 » 父与子的编程之旅:与小卡特一起学Python » 父与子的编程之旅:与小卡特一起学Python全文在线阅读

《父与子的编程之旅:与小卡特一起学Python》18.1 事件

关灯直达底部

如果我在现实生活中问你,“什么是事件”,你可能会说这是“发生的某件事情”。这是一个很好的定义,这个定义在编程中也同样适用。很多程序都需要对“发生的事情”做出反应。比如说:

  • 移动或点击鼠标;

  • 按键;

  • 经过了一定时间。

目前为止,我们写的大多数程序自始至终都沿着一条可以预测的路径运行,可能中间会有一些循环或条件。不过,除此以外还有另外一类程序,称为事件驱动程序(event-driven program),它们的做法完全不同。事件驱动程序基本上只是“原地不动”,什么也不做,等待着有事件发生。一旦事件确实发生,它们就会做出反应,完成所有必要的工作来处理这个事件。

Windows 操作系统(或者其他 GUI)就是这种事件驱动程序的一个很好的例子。打开 Windows 计算机时,启动后它只是“原地不动”,不会启动任何程序,你也不会看到鼠标光标在屏幕上移动。不过,如果你开始移动或点击鼠标,就会有情况发生。鼠标光标会在屏幕上移动,“开始”菜单会弹出,或者会做其他事情。

事件循环

为了让一个事件驱动程序“看到”有事件发生,它必须“寻找”这些事件。程序必须不断地扫描计算机内存中用来指示事件发生的部分。只要程序在运行,就会反复这样做。回顾第 8 章,我们已经了解了程序如何反复做某些事情,这要使用一个循环。不断寻找事件的这个特殊循环叫做事件循环(event loop)。

前两章完成的 Pygame 程序中,最后总是有一个 while 循环。我们说过,这个循环会在程序运行期间一直运行。这个 while 循环就是 Pygame 的事件循环。(要了解退出代码是如何工作的,首先要知道这个事件循环。)

事件队列

只要有人移动或点击了鼠标或者按下了按键,就会发生事件。这些事件去哪里了呢?在上一节中我说过,事件循环会一直不断地搜索内存的某个部分。内存中存储事件的部分叫做事件队列(event queue)。

术语箱

队列(queue)读作“Q”。日常生活中,这就表示排队。

在编程中,队列通常指一个列表,其中的元素按某种特定的顺序到达,或者将按某种特定的顺序使用。

事件队列就是发生的所有事件的列表,这些事件按它们发生的顺序排列。

事件处理器

如果编写一个 GUI 程序或游戏,程序必须知道用户什么时候按下一个按键或者移动了鼠标。这些按键、点击和移动鼠标都是事件,而且程序必须知道如何应对这些事件,它必须处理事件。程序中处理某个事件的部分称为一个事件处理器(event handler)。

并不是每一个事件都要处理。在桌面上移动鼠标时,会创建成百上千个事件,因为事件循环运行得非常快。每一个瞬间(远远不到 1 秒),即使鼠标只是移动了一点点,也会生成一个新的事件。不过你的程序可能并不关心鼠标的每一个小小的移动。它可能只关心用户什么时候点击某个部分。所以你的程序可以忽略 mouseMove 事件,只关注 mouseClick 事件。

事件驱动程序中,对于所关心的各种事件会有相应的事件处理器。如果你有一个游戏使用键盘上的方向键来控制一艘船的移动,可能要为 keyDown 事件编写一个处理器。相反,如果使用鼠标控制这艘船,就可能为 mouseMove 事件写一个事件处理器。

现在就来看我们的程序中可以使用的一些具体事件。我们还会使用 Pygame,所以这一章后面讨论的所有事件都来自 Pygame 的事件队列。其他 Python 模块会提供不同的事件。例如,我们将在第 20 章讨论另外一个名为 PyQt 的模块。PyQt 有自己的事件集,其中一些事件与 Pygame 有所不同。不过,对于不同的事件集(甚至在不同的编程语言中),处理事件的方式通常都是一样的。对于每个事件系统来说可能都不完全一样,不过相同点还是远远多于不同点。