8.1.3 事件驱动

图形构件组成了图形界面的可见部分,在这些可见构件的背后,还有不可见的程序逻辑。 就好比家用电器都提供操作面板,用户通过操作面板控制、使用电器功能,在面板的背后是 实现功能的电路逻辑。

GUI 应用程序的特点是注重与用户的交互,因此程序的执行取决于与用户的实时交互情 况。例如 Word 程序启动后,并非一路执行到程序结束,而是在做了必要的初始化工作后就 停下来,等待用户的下一步动作。用户可能在文档窗口中输入文本,也可能通过菜单设置选 项,还可能点击工具栏里的存盘图标,总之是完全不确定的。Word 程序只能等到用户的交互 动作发生后,才去执行相应的处理代码。

由于 GUI 程序的执行流程由用户控制,并且不可预期,为了适应这种特点,我们需要采 用事件驱动的编程方法。普通程序的执行可概括为“启动——做事——终止”,而事件驱动的 程序的执行可概括为“启动——事件循环(即等待事件发生并处理之)”。作为特例,GUI 程 序的终止也是由特定事件(如关闭窗口事件)引起的。

事件(event)是针对应用程序所发生的事情,并且应用程序需要对这种事情做出响应。 程序对事件的响应其实就是调用预先编制好的代码来对事件进行处理,这种代码称为事件处 理程序(event handler)。GUI 中最常见的事件是用户的交互动作,如按下某个键或者点击鼠 标。当然在其他类型的应用程序中也会出现其他类型的事件,例如在各种监控系统中,传感 器采集环境数据并传给程序,就可视为发生了需要处理的事件。又如在面向对象程序中,向 某个对象发送消息,也可看成是发生了某种需要响应的事件。事件驱动编程(event-driven programming)就是针对这种“程序的执行由事件决定”的应用的一种编程范型。

事件驱动的程序一般都有一个主循环(main loop)或称事件循环,该循环不停地做两件 事:事件监测和事件处理。首先要监测是否发生了事件,如果有事件发生则调用相应的事件 处理程序,处理完毕再继续监测新事件。那么,主循环如何监测事件以及如何触发相应的事 件处理程序呢?这个问题牵涉到操作系统的低层机制,比较复杂。好在这部分代码是独立于 具体应用程序的,一般都由 GUI 工具包提供支持,应用程序员只需编写自己的事件处理程序。