我在Qt的初学者,试图了解SIGNAL
和SLOT
宏。 当我学习使用connect
方法将信号和槽结合,我发现教程上Qt的官方参考页使用:
connect(obj1, SIGNAL(signal(int)), obj2, SLOT(slot()))
然而,这也工作得非常好:
connect(obj1, &Obj1::signal, obj2, &Obj2::slot)
那么究竟是什么做的宏SIGNAL
和SLOT
吗? 难道他们只是看在类的对象属于并返回它的地址的信号?
那么,为什么大多数程序员使用这些宏,而不是使用&Obj1::signal
,因为后者似乎更简单,你不需要更改代码,如果信号功能变化的参数?
使用的SIGNAL
和SLOT
曾经是使连接的唯一方法宏,Qt的5之前的连接是在运行时做出和要求信号和时隙被标记在头中。 例如:
Class MyClass : public QObject
{
Q_OBJECT
signals:
void Signal();
slots:
void ASlotFunction();
};
为了避免重复,在其它的工作原理进行说明的方式的QT 4文档中 。
信号和槽机构是C ++被Qt被提供并利用扩充功能的一部分元对象编译器(MOC) 。
这解释了为什么信号和槽使用MOC。
所述第二连接方法大为改善作为指定的功能可以在编译的时候进行检查,不运行时。 此外,通过使用函数的地址,你可以参考任何类的功能,而不只是在部分标注插槽:
该文件是为Qt的5更新 。
此外,还有约了Qt 4连接运作良好的博客文章在这里和Qt 5 在这里 。
除了第一个答案。
究竟是什么做的宏信号和SLOT做
几乎没有。 看看qobjectdefs.h
:
# define SLOT(a) "1"#a
# define SIGNAL(a) "2"#a
它只是增加了1
或2
。 这意味着接下来的代码是有效的,按预期工作:
QObject *obj = new QObject;
connect(obj,"2objectNameChanged(QString)",this,"1show()");//suppose this is a pointer to a QDialog subclass
obj->setObjectName("newNAme");
为什么大多数程序员使用这些宏而不是使用像&OBJ1的::信号
- 因为这些宏只在QT5无法正常工作。
- 因为这些宏没有与重载信号的复杂性( 它可以使你的代码非常肮脏,这真的不是一件简单的事情 )
- 因为随着新的语法,有时需要使用特定的断开
更多细节在这里。
要完成TheDarkKnight的答案 ,这是一个很好的做法,以重构正在使用使用函数的地址旧的Qt 4 SIGNAL和SLOT宏的Qt 5的新语法遗留代码。
突然间,将出现在编译的时候,而不是在运行时连接错误! 这很容易使一个Qt 4连接错误,因为任何拼写错误会导致这样的错误。 另外,该功能的名称必须是完全合格的名称,即前面有完整的命名空间(如有)。
另一个好处是使用lambda的插槽功能,它可以减少需要的命名功能,如果槽体是微不足道的能力。