使用发射与调用信号,就好像它是Qt中的常规函数​​一样

比方说,我有这个信号:

signals: void progressNotification(int progress); 

我最近才了解到Qt中的emit关键字。 到目前为止,我习惯于像普通函数那样调用它们来执行信号。 所以,而不是:

 emit progressNotification(1000 * seconds); 

我会写:

 progressNotification(1000 * seconds); 

像这样调用它们似乎是行得通的,所有连接的插槽都会执行,那么使用emit关键字会导致不同的行为,还是只是语法糖?

emit只是句法糖。 如果你看看发射信号的函数的预处理输出,你会看到emit刚刚消失。

信号发射function的生成代码中出现了“魔术”,您可以通过检查moc生成的C ++代码来查看它。

例如,一个没有参数的foo信号产生这个成员函数:

 void W::foo() { QMetaObject::activate(this, &staticMetaObject, 0, 0); } 

代码emit foo(); 被预处理为简单的foo();

Qt/qobjectdefs.h (源代码的源代码开放源代码)中定义了emit ,如下所示:

 #ifndef QT_NO_EMIT # define emit #endif 

(定义的守卫是允许你通过no_keywords QMakeconfiguration选项使用Qt与其他具有碰撞名称的框架。)

18个月后……我在@Mat的回答下开始评论,很快就没了房间。 这样的答案。

IMO emit既不是语法糖,也不是简单的关键字

  1. 它生成代码(如上面的@Mat所解释的),
  2. 它有助于connect机制认识到这确实是一个signal ,而且
  3. 它使您的信号成为“更大”系统的一部分,信号和响应(时隙)可以同步或asynchronous执行或排队,具体取决于信号发出的位置和方式。 这是信号/插槽系统非常有用的function。

整个信号/插槽系统是一个不同于一个简单的函数调用的习惯用法。 我相信这源于观察者模式。 signalslot之间也有一个主要的区别:一个信号不必被执行,而一个时隙必须是

你走在街上,看到一个房子着火(一个信号)。 您拨打911( 用911响应插槽连接火警信号 )。 信号只是散发出来的 ,而这个插槽由消防部门执行的。 可能是不准确的,但你明白了。 我们来看看OP的例子。

一些后端对象知道已经取得了多less进展。 所以它可以简单地emit progressNotification(...)信号。 显示实际进度条的课程取决于该信号并在其上执行。 但是,视图如何连接到这个信号? 欢迎来到Qt的信号/插槽系统。 现在可以设想一个pipe理类(通常是一个sorting小部件),它由一个视图对象和一个数据计算对象(都是QObjects )组成,可以执行connect (m_myDataEngine, &DataEngine::progressNotification, m_myViewObj, &SimpleView::displayProgress)

让我们不要深入经理类的devise方面,但足以说这是信号/时隙系统发光的地方。 我可以专注于为我的应用程序devise一个非常干净的架构。 并不总是,但往往是,我发现我只是发出信号,但实施插槽

如果可以使用/调用一个信号方法而没有发出信号,那么这就意味着你从来不需要这个函数作为一个信号

第二个选项意味着你总是知道函数名和函数参数是什么,并且你发送给它的那个对象被这个特定的函数所知道。 这两种情况并不总是正确的,所以槽和信号是两个主要的原因。 信号和插槽机制只是一个表,指向每个连接的function。

另外,看看这个pdf,它非常清楚地解释了信号和插槽机制的性质: http : //www.elpauer.org/stuff/a_deeper_look_at_signals_and_slots.pdf