24

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

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

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

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

4

5 回答 5

14

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

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

于 2010-02-24T12:51:46.740 回答
13

可以用信号
报错吗?

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

可以假设将处理信号吗?

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

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

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

于 2010-02-24T16:42:33.627 回答
11

可以假设将处理信号吗?

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

于 2010-02-24T10:29:22.963 回答
6

可以用信号报错吗?

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

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

可以假设将处理信号吗?

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

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

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

于 2010-02-24T16:33:48.953 回答
4

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

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

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

于 2010-02-24T10:29:58.790 回答