我已经成为Qt程序员已经有一段时间了,我理解Qt的大多数一般功能。我仍然对connect语句如何在运行时将信号连接到插槽感到困惑。基本上我想了解在编译时会发生什么以及在运行时会发生什么......
编译时间:元对象编译器将生成代码以在另外的cpp文件中实现一个信号(每个类包含一个Q_OBJECT)。
运行时间:信号映射到一个插槽,插槽被执行?这是我不清楚的部分... SIGNAL和SLOTS是扩展为信号/插槽名称的字符串表示的宏...这和元对象如何帮助在运行时映射到插槽的调用?细节将不胜感激......
编辑: 这个链接会给你一个更好的主意..(只有你对血腥细节感兴趣...) http://dev.libqxt.org/libqxt/wiki/Meta_Object_Format
将此与QMetaObject的文档相结合,事情应该变得清晰......
答案 0 :(得分:2)
有多种方法可以将信号连接到方法(信号/插槽)。
但是,它们都围绕着获取正确的方法编号。
在拥有正确的方法编号和要调用它的对象之后,只需在QObject中调用虚拟化函数(qt_metacall),该函数从给定的数字中找到正确的调用方法。您可以在MOC生成的文件中找到此功能。此外,在该生成的文件中,您可以找到一个创建类的静态QMetaObject的行。此对象将插槽和信号的名称注册到方法编号。
这些可能会提供一些有趣的内容:
http://doc.qt.io/qt-5/qmetaobject.html
http://doc.qt.io/qt-5/metaobjects.html
http://doc.qt.io/qt-5/signalsandslots.html
通过使用调试器运行插槽激活,您还可以学到很多东西。
答案 1 :(得分:0)
基本上,信号和插槽与Objective-C中的消息类似。
宏使预处理器用一些代码替换它们,这些代码“注册”并“查找”调用插槽时要有效执行的函数/方法。
这允许更大的灵活性,因为发出信号或调用插槽的代码不需要了解使用它们的其他代码模块。每个插槽和信号生成一个签名,在运行时查找,然后调用。
如果您熟悉C / C ++,可以将其与动态库进行比较。在运行时查找符号,然后使用它们的地址让CPU“跳转”到它们来执行。
此外,这些链接可能对您有所帮助: