我对区别的印象如下:
假设你有一个服务器设备,运行一个无限循环,监听一些外部客户端事件并通过执行一些代码来响应它们。
(它可以是 CPU,监听来自设备的中断,也可以是客户端 Javascript 浏览器代码,监听用户点击或服务器端网站代码,监听用户请求网页或数据)。
或者它可以是您的 Qt 应用程序,运行它的主循环。
我将假设您在 Linux 上运行 Qt 并使用用于绘图的 X 服务器来解释。
我可以区分两个主要区别,尽管第二个有争议:
- 事件代表您的硬件,是一个小的有限集。信号代表您的 Widget 层逻辑,可以任意复杂且数量众多。
事件是来自客户端的低级消息。事件集是严格限制的集(约 20 种不同的事件类型),由硬件(例如鼠标单击/双击/按下/释放、鼠标移动、键盘键按下/释放/按住等)确定,并在协议中指定应用程序和用户之间的交互(例如 X 协议)。
例如在创建 X 协议时,没有多点触控手势,只有鼠标和键盘,因此 X 协议不会理解您的手势并将它们发送到应用程序,它只会将它们解释为鼠标点击。因此,随着时间的推移,X 协议的扩展被引入。
X 事件对小部件一无所知,小部件只存在于 Qt 中。 X 事件只知道 X 窗口,这是小部件组成的非常基本的矩形。您的 Qt 事件只是围绕 X 事件/Windows 事件/Mac 事件的一个薄包装器,为不同的操作系统原生事件提供了一个兼容层,以方便 Widget 级逻辑层作者。
小部件级别的逻辑处理信号,因为它们包含您操作的小部件级别的含义。此外,一个信号可以由于不同的事件而被触发,例如鼠标单击“保存”菜单按钮或键盘快捷键,例如 Ctrl-S。
- 抽象地说(这不完全是关于 Qt!),事件本质上是异步的,而信号(或其他术语的钩子)是同步的。
比如说,你有一个函数 foo(),它可以触发 Signal 或发出 Event。
如果它触发信号,信号将在与函数相同的代码线程中执行,导致它在函数之后。
另一方面,如果它发出事件,事件被发送到主循环,它取决于主循环,何时将该事件传递给接收方以及接下来会发生什么。
因此 2 个连续的事件甚至可能以相反的顺序传递,而 2 个连续触发的信号保持连续。
不过,术语并不严格。 Unix中的“信号”作为进程间通信的一种方式应该更好地称为事件,因为它们是异步的:您在一个进程中调用信号并且永远不知道事件循环何时切换到接收进程并执行信号处理程序.
附注请原谅我,如果我的一些例子在字母方面不是绝对正确的。精神上还是不错的。