Answers:
emit
只是语法糖。如果查看发出信号的函数的预处理输出,您会发现emit
它已经消失了。
“魔术”发生在信号发射功能的生成代码中,您可以通过检查由moc生成的C ++代码来查看。
例如foo
,没有参数的信号会生成此成员函数:
void W::foo()
{
QMetaObject::activate(this, &staticMetaObject, 0, 0);
}
然后将代码emit foo();
预处理为简单foo();
emit
定义为Qt/qobjectdefs.h
(无论如何都以源代码的开源风格),如下所示:
#ifndef QT_NO_EMIT
# define emit
#endif
(定义保护措施是允许您通过no_keywords
QMake config选项将Qt与具有冲突名称的其他框架一起使用。)
emit
,但实际上做的比什么都不做?我发现在这种情况下使用“语法糖”只会使新手感到困惑(或者至少当我是Qt新手时我感到困惑)- emit
伪关键字似乎在发生什么不可思议的或重要的事情,而它却什么也没做全部-所有魔术都在moc
创建的常规旧函数中发生(moc
是Qt信号和插槽的魔术)。emit
是不必要的装饰,什么也没做,但看起来很重要。
emit
告诉阅读呼叫的人魔术即将发生(即,这将触发该类可能从未听说过的对象中的代码,并且这些调用可能是同步的或异步的),如果省略关键字,则基本上完全会丢失。用它。它是自动文档。“新手”应该阅读文档和教程,并且emit
始终存在(无论如何在官方文档中)。发现您可以调用该函数应该在“见识了”之后发生-此时您不再是新手。
emit
“关键字”的价值。我认为如果需要明确指出函数调用是信号,那么我宁愿使用命名约定。
emit
。
emit
psuedo-keyword-comment 的原因是要明确表明正在调用信号,那么命名约定可以做到这一点,而没有神秘并具有类似的好处。Qt不能强制执行命名约定(实际上,moc
可以强制执行它-但我不主张二者之一),但是Qt不能强制使用emit
两者。而且,emit
如果发生名称冲突,您可以“关闭” ,但是如果您有一堆正在使用它的源文件(不必要地引导),那将无济于事。
18个月后...我从@Mat的回答开始评论,然后很快就没了空间。因此答案。
IMO emit
既不是语法糖也不是简单的关键字,
connect
机制识别出确实是一个signal
,并且整个信号/插槽系统是与简单函数调用不同的惯用法。我认为这源于观察者模式。a signal
和a 之间还有一个主要区别slot
:不一定要实现信号,而插槽必须是!。
您正走在街上,看到一栋房屋着火(信号)。您拨打911(将火警信号与911响应槽连接)。仅发出信号,而该插槽由消防部门实施。可能不精确,但您明白了。让我们看一下OP的示例。
一些后端对象知道已经取得了多少进展。因此它可以简单地emit progressNotification(...)
发出信号。由显示实际进度条的类决定如何拾取此信号并对其执行。但是视图如何连接到该信号?欢迎使用Qt的信号/插槽系统。现在,可以执行一个经理类(通常是各种小部件),它可以由视图对象和数据计算对象(都为QObjects
)组成connect (m_myDataEngine, &DataEngine::progressNotification, m_myViewObj, &SimpleView::displayProgress)
。
让我们不进入管理器类的设计方面,而足以说这是信号/插槽系统的亮点。我可以专注于为我的应用程序设计一个非常干净的体系结构。我发现并非总是,但经常,我只是发出信号而实现slot。
如果可以在不发出信号的情况下使用/调用信号方法,则必然意味着您根本不需要使用该函数作为信号。
emit
确实只是一个空宏,并且是完全可选的。不是这样的关键字signal
以及slot
其中由商务部进行处理。signal
用于提供功能的实现,slot
用于创建元对象条目,以便通过SLOT(MySlot())
宏或在QML中找到它。emit
是句法建议。如果您写东西emit i++;
(但也许是您的同事),也不会抱怨,但您仍然无法连接到i++
。
第二种选择意味着您总是知道函数名称和函数参数是什么,并且将其发送到的对象被该特定函数所知道。这两种情况并不总是正确的,所以这就是为什么要制作时隙和信号的两个主要问题。“内部”信号和插槽机制只是一个表,其中包含指向所连接的每个功能的指针。
另外,请参阅此pdf文件,该文件非常清楚地说明了信号和时隙机制的性质:http: //www.elpauer.org/stuff/a_deeper_look_at_signals_and_slots.pdf
emit
这只是一个禁忌。但是即使在这种情况下,阅读问题正文也应清除所有内容,因此为-1。
emit
是不需要的。但是,很奇怪,您emit
在直接调用信号后不久就了解了,因为信号插槽系统是有关Qt的第一个要学习的知识。