何时使用信号和槽,何时不使用

发布于 2024-08-22 22:53:57 字数 311 浏览 8 评论 0原文

我们使用的 Qt 提供了信号和槽,我觉得这非常方便。然而,能力越大,责任越大,我认为这个功能也很容易被滥用。

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

  • 可以使用信号来报告错误吗?
  • 可以假设信号将被处理吗?
  • 信号可以用来发起行动吗?例如,signal displayInfoScreen() 必须由显示信息屏幕的槽来处理。

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

We're using Qt that offers signals and slots which I find really convenient. However, with great power comes great responsibility and I think it's very easy too misuse this feature.

Are there any best-practices for signal-slot usage? I'm having a hard time to find some general guidelines in this manner. Some questions (I have clear opinions about, but that not all members of my team agree with):

  • Is it ok to use signals to report errors?
  • Is it ok to assume that a signal will be handled?
  • Can signals be used to initiate actions? E.g. signal displayInfoScreen() must be handled by a slot that shows an info screen.

Any other opinions on when signals should/shouldn't be used are very welcome!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

蒗幽 2024-08-29 22:53:57

信号和槽非常强大,因为它可以解耦对象。正如前面所回答的,您不能假设信号已连接插槽。

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

Signals and slots are powerful because decouples objects. You can't assume that a signal has a slot connected, as previously answered.

A major drawback of signal/slot based design is that you can very easy loose track of the logic you implemented, since one action of an object can trigger other actions of any other object that connected to a signal emitted. It is much easier to have unwanted side effects, recursive calls, etc.

梦言归人 2024-08-29 22:53:57

可以使用信号来报告吗
错误?

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

可以假设信号会
处理吗?

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

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

再说一遍,是的,例如 QAction 对象。但如果您希望能够重用组件,则必须小心确保实际的类不依赖于它。

Is it ok to use signals to report
errors?

Yes, for instance, see QFtp, where the done signal carries a status. It does not carry the actual error, just information that an error has occured.

Is it ok to assume that a signal will
be handled?

No. The sender can never assume that, however, your particular application can depend on it. For instance, the QAction representing File - New needs to be handled for the application to work, but the QAction object couldn't care less.

Can signals be used to initiate
actions? E.g. signal
displayInfoScreen() must be handled by
a slot that shows an info screen.

Again, yes, for instance the QAction object. But if you want to be able to reuse components, you must be careful to ensure that the actual class does not depend on it.

向日葵 2024-08-29 22:53:57

可以假设信号将被处理吗?

不,不是。信号是一种“一劳永逸”的东西。谁连接到信号以及它做什么不应该是发射器关心的。

Is it ok to assume that a signal will be handled?

No it's not. Signals are fire-and-forget type of things. Who connects to a signal and what it does should not be the emitter's concern.

箜明 2024-08-29 22:53:57

使用信号报告错误可以吗?

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

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

可以假设信号将被处理吗?

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

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

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

Is it ok to use signals to report errors?

Yes, but I would generally make this situation-dependent. If the error might occur asynchronously, then a signal to indicate such is definitely proper. If the error only occurs when client code calls one certain function, then the error should be in the response from that function, not as a signal. However, there are a wide array of situations in between that might be done on a case-by-case basis.

Also, signal-slot mechanisms can make cross-thread communication easier (which might well be considered the asynchronous case), and I will use them for that purpose (error or no).

Is it ok to assume that a signal will be handled?

Signals are (philosophically) designed to indicate that something has happened. As others have indicated, it's never a good idea to assume that a signal will be matched with a slot, or even with just one other slot.

Can signals be used to initiate actions? E.g. signal displayInfoScreen() must be handled by a slot that shows an info screen.

Signals can be used to initiate actions, but probably not in the way you are thinking. The signal indicates that foo has happened. If the code monitoring your class decides that when foo happens, a dialog should be shown, then the signal was used to initiate that action. However, it's generally not the responsibility of the class emitting the signal to ensure that the proper action occurs, because it is not responsible for doing that action. (If it was, then it should be part of the same class, and no signal would be needed.)

剧终人散尽 2024-08-29 22:53:57

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

例如,它们没有了解模型如何工作以及模型何时更改的视图,而是“监听”模型。模型负责说明何时发生变化、发生了什么变化。

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

Signals/slots (also called events) are a good way to remove coupling between objects.

For example, instead of having views that understand how the model works, and when the model changes, they "listen" to the model. The model is responsible of saying when it changes, what changes.

The problem with events is when you design your events with client requirements. For example, you should not have a signal displayInfoScreen because it assumes something about objects using this signal. Instead, it should be infoChanged and the InfoScreenDisplayer listens to this signals to display it on screen. If you need, you could add later a InfoTweeterPoster that post the info on Tweeter whenever they change.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文