【问题标题】:What are the differences between event and signal in QtQt中的事件和信号有什么区别
【发布时间】:2012-03-08 14:17:17
【问题描述】:

我很难理解 Qt 中信号和事件之间的区别,有人可以解释一下吗?

【问题讨论】:

  • 我认为这是一个真正的问题,不应该被关闭。这是来自 Qt 社区文档的答案: Qt 中的事件是一个对象,它代表发生的有趣事情;事件和信号之间的主要区别在于,事件针对我们应用程序中的特定对象(决定如何处理该事件),而信号是“在野外”发出的。从代码的角度来看,所有事件都是 QEvent [doc.qt.nokia.com] 的某个子类的实例,并且所有 QObject 派生类都可以覆盖 QObject::event() 虚方法以处理事件。 .

标签: qt events signals


【解决方案1】:

我对区别的印象如下:

假设你有一个服务器设备,运行一个无限循环,监听一些外部客户端事件并通过执行一些代码来响应它们。

(它可以是 CPU,监听来自设备的中断,也可以是客户端 Javascript 浏览器代码,监听用户点击或服务器端网站代码,监听用户请求网页或数据)。

或者它可以是您的 Qt 应用程序,运行它的主循环。

我将假设您在 Linux 上运行 Qt 并使用用于绘图的 X 服务器来解释。

我可以区分两个主要区别,尽管第二个有争议:

  1. 事件代表您的硬件,是一个小的有限集。信号代表您的 Widget 层逻辑,可以任意复杂且数量众多。

事件是来自客户端的低级消息。事件集是严格限制的集(约 20 种不同的事件类型),由硬件(例如鼠标单击/双击/按下/释放、鼠标移动、键盘键按下/释放/按住等)确定,并在协议中指定应用程序和用户之间的交互(例如 X 协议)。

例如在创建 X 协议时,没有多点触控手势,只有鼠标和键盘,因此 X 协议不会理解您的手势并将它们发送到应用程序,它只会将它们解释为鼠标点击。因此,随着时间的推移,X 协议的扩展被引入。

X 事件对小部件一无所知,小部件只存在于 Qt 中。 X 事件只知道 X 窗口,这是小部件组成的非常基本的矩形。您的 Qt 事件只是围绕 X 事件/Windows 事件/Mac 事件的一个薄包装器,为不同的操作系统原生事件提供了一个兼容层,以方便 Widget 级逻辑层作者。

小部件级别的逻辑处理信号,因为它们包含您操作的小部件级别的含义。此外,一个信号可以由于不同的事件而被触发,例如鼠标单击“保存”菜单按钮或键盘快捷键,例如 Ctrl-S

  1. 抽象地说(这不完全是关于 Qt!),事件本质上是异步的,而信号(或其他术语的钩子)是同步的。

比如说,你有一个函数 foo(),它可以触发 Signal 或发出 Event。 如果它触发信号,信号将在与函数相同的代码线程中执行,导致它在函数之后

另一方面,如果它发出事件,事件被发送到主循环,它取决于主循环,何时将该事件传递给接收方以及接下来会发生什么。

因此 2 个连续的事件甚至可能以相反的顺序传递,而 2 个连续触发的信号保持连续。

不过,术语并不严格。 Unix中的“信号”作为进程间通信的一种方式应该更好地称为事件,因为它们是异步的:您在一个进程中调用信号并且永远不知道事件循环何时切换到接收进程并执行信号处理程序.

附注请原谅我,如果我的一些例子在字母方面不是绝对正确的。精神上还是不错的。

【讨论】:

  • 这个答案太棒了。
【解决方案2】:

event 是封装在一个类 (QEvent) 中的 message,该类在事件循环中处理并分派给可以接受该消息或传给其他人处理。它们通常是为了响应鼠标点击等外部系统事件而创建的。

信号和槽QObjects 相互交流的一种便捷方式,更类似于回调函数。在大多数情况下,当发出“信号”时,任何连接到它的槽函数都会被直接调用。例外情况是信号和槽跨越线程边界时。在这种情况下,信号本质上将被转换为事件。

【讨论】:

    【解决方案3】:

    事件直接传递给类的事件处理方法。它们可供您在子类中重载并选择如何以不同方式处理事件。事件也会从孩子传递到父母,直到有人处理它或它从末端脱落。

    另一方面,信号是公开发出的,任何其他实体都可以选择连接和收听它们。它们通过事件循环并在队列中处理(如果它们在同一个线程中,也可以直接处理)。

    【讨论】:

      【解决方案4】:

      事件是发生在对象内的事情。通常,您会在对象自己的类代码中处理它们。

      信号由对象发出。该对象基本上是在通知其他对象发生了什么事。其他对象可能会因此而做某事或不做某事,但这不是发射器的工作来处理它。

      【讨论】:

      • 严格来说,这个答案非常好。我什至可以说事件可以被抛出一个可以传播的对象......这也假设应该存在一个信号总线(消息总线)并且对象需要在该总线上注册,应用过滤器来捕获信号(消息)他们想要处理......通常应该这样做......但情况并非总是如此。
      猜你喜欢
      • 2015-05-11
      • 1970-01-01
      • 1970-01-01
      • 2010-12-20
      • 1970-01-01
      • 2013-05-09
      • 2012-03-16
      • 1970-01-01
      相关资源
      最近更新 更多