【问题标题】:When to use signals and slots and when not to何时使用信号和插槽,何时不使用
【发布时间】:2011-01-20 11:24:23
【问题描述】:

我们正在使用提供信号和插槽的 Qt,我觉得 真的 很方便。然而,强大的力量伴随着巨大的责任,我认为很容易滥用这个功能。

有没有关于信号槽使用的最佳实践?我很难以这种方式找到一些通用指南。一些问题(我对此有明确的看法,但并非我团队的所有成员都同意):

  • 可以使用信号报错吗?
  • 可以假设将处理信号吗?
  • 可以使用信号来启动操作吗?例如。 signal displayInfoScreen() 必须由显示信息屏幕的插槽处理。

非常欢迎任何其他关于何时应该/不应该使用信号的意见!

【问题讨论】:

    标签: c++ qt signals-slots qt-signals


    【解决方案1】:

    用信号报告可以吗
    错误?

    是的,例如,参见 QFtp,其中 done 信号携带状态。它不携带实际错误,只是发生错误的信息。

    可以假设一个信号会 处理?

    没有。但是,发送者永远不能假设您的特定应用程序可以依赖它。例如,代表 File - New 的 QAction 需要处理才能使应用程序正常工作,但 QAction 对象却不在乎。

    信号可以用来启动吗 行动?例如。信号 displayInfoScreen() 必须由 显示信息屏幕的插槽。

    同样,是的,例如 QAction 对象。但是如果你希望能够重用组件,你必须小心确保实际的类不依赖它。

    【讨论】:

    • 被接受,因为这个答案提供了在 Qt 中使用的简单示例。你认为错误是可以的,但只有在处理是异步的时候?
    • 谢谢!而且,是的,否则,添加状态返回值或状态参数(如 QString::toInt 所做的那样)。
    【解决方案2】:

    可以使用信号报错吗?

    是的,但我通常会根据情况来决定。如果错误可能异步发生,那么指示这种错误的信号绝对是正确的。如果错误仅在客户端代码调用某个函数时发生,那么错误应该在该函数的响应中,而不是作为信号。但是,有很多情况可以根据具体情况进行处理。

    此外,信号槽机制可以使跨线程通信更容易(这很可能被认为是异步情况),我将为此目的使用它们(错误或否)。

    可以假设一个信号会被处理吗?

    信号(从哲学上讲)旨在表明某事已经发生。正如其他人所指出的那样,假设信号将与一个插槽匹配,甚至只与 一个 其他插槽匹配,这绝不是一个好主意。

    信号可以用来启动动作吗?例如。信号 displayInfoScreen() 必须由显示信息屏幕的插槽处理。

    信号可用于启动操作,但可能与您的想法不同。该信号表明 foo 已经发生。如果监控您的类的代码决定当 foo 发生时,应该显示一个对话框,然后使用该信号来启动该操作。但是,发出信号的类通常不负责确保发生正确的操作,因为它不负责执行该操作。 (如果是,那么它应该是同一类的一部分,并且不需要信号。)

    【讨论】:

      【解决方案3】:

      信号和槽是强大的,因为它可以解耦对象。您不能假设一个信号连接了一个插槽,如前所述。

      基于信号/槽的设计的一个主要缺点是你可以很容易地跟踪你实现的逻辑,因为一个对象的一个​​动作可以触发连接到的任何其他对象的其他动作发出的信号。更容易产生不需要的副作用、递归调用等。

      【讨论】:

        【解决方案4】:

        信号/槽(也称为事件)是消除对象之间耦合的好方法。

        例如,它们不是让视图了解模型的工作原理以及模型何时发生变化,而是“倾听”模型。该模型负责说明它何时发生变化,发生了什么变化。

        事件的问题在于当您根据客户要求设计事件时。例如,你不应该有一个信号displayInfoScreen,因为它假设了一些关于使用这个信号的对象。相反,它应该是infoChanged,而InfoScreenDisplayer 会监听此信号以将其显示在屏幕上。如果您需要,您可以稍后添加 InfoTweeterPoster,以便在 Tweeter 发生更改时发布信息。

        【讨论】:

        • 你写了又名事件,但事实并非如此。 Qt 带有一个单独的事件基础结构。
        【解决方案5】:

        可以假设一个信号会被处理吗?

        不,不是。信号是一种即发即弃的东西。谁连接到信号以及它做什么不应该是发射器的关注点。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多