2010-02-24 99 views
22

我们使用Qt提供的信号和插槽,我发现真的是方便。然而,强大的力量带来了巨大的责任,我认为这种功能很容易被滥用。什么时候使用信号和插槽,什么时候不使用

是否有信号插槽使用的最佳做法?我很难用这种方式找到一些通用的指导方针。一些问题(我有明确的意见,但不是我的团队所有成员都同意):

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

关于什么时候应该/不应该使用信号的任何其他意见是很欢迎欢迎!

回答

12

它是确定使用信号来报告
错误?

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

可以假设信号 被处理?

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

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

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

+0

接受此答案提供了在Qt中使用的简单示例。你认为错误是好的,但只有当处理是异步的时候? – larsmoa 2010-02-26 21:57:15

+0

谢谢!而且,是的,否则,请添加状态返回值或状态参数(如QString :: toInt所做的那样)。 – e8johan 2010-02-28 09:28:56

10

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

不,它不是。信号是火灾和忘记类型的东西。谁连接到一个信号,它的作用不应该是发射器的问题。

3

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

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

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

+6

你写了a.k.a.事件,但事实并非如此。 Qt带有一个单独的事件基础结构。 – e8johan 2010-02-24 16:38:50

11

信号和插槽功能强大,因为decouples对象。正如以前所回答的那样,您不能假定信号有插槽连接。

基于信号/槽设计的主要缺点是,你可以很容易了,履带你实现,由于对象的一个​​动作可以触发连接到发射的信号的任何其它物体的其他动作的逻辑。具有不需要的副作用,递归调用等容易得多。

5

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

是的,但我通常会做出这种情况依赖。如果错误可能异步发生,那么表明这种情况的信号是绝对正确的。如果错误只发生在客户代码调用某个函数时,那么错误应该来自该函数的响应,而不是信号。但是,在各个案例之间可能会有各种各样的情况。另外,信号插槽机制可以使跨线程通信更容易(这可能被认为是异步情况),并且我将使用它们用于该目的(错误或不)。

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

信号(哲学上)被设计为表示发生了某些事情。正如其他人所指出的那样,假设一个信号将与一个插槽相匹配,或者甚至只与一个其他插槽相匹配也不是一个好主意。

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

信号可以用来启动动作,但可能不像你想的那样。该信号表明foo已经发生。如果监控班级的代码决定发生10富时时应显示一个对话框,然后使用该信号启动该操作。然而,一般来说,发布信号的职责不是确保发生适当的行为,因为它不负责执行该行为。 (如果是的话,那应该是同一类的一部分,将需要无信号)。

相关问题