Qt如何实现支持传入QObject和槽的通用信号槽连接方法
通用Qt信号槽连接方法实现方案
核心实现思路
利用C++成员函数模板自动推导槽函数的类型,保留Qt信号槽的编译期类型检查特性,不需要手动处理类型转换,仅要求槽函数的参数和C类的signalC(bool)参数兼容即可。
注:原代码中存在的笔误、语法错误(类定义缺分号、对象声明类型不匹配、缺Q_OBJECT宏、信号槽语法错误)已一并修正。
完整可运行代码
类定义部分
#include <QObject> #include <QMetaObject> class A : public QObject { // Qt信号槽工作必须添加的元对象宏 Q_OBJECT public: A() {} ~A() override {} signals: void sigA(int); public slots: void slotA(bool) { // 槽函数自定义逻辑 } }; class B : public QObject { Q_OBJECT public: B() {} ~B() override {} signals: void sigB(bool); public slots: void slotB(int) { // 槽函数自定义逻辑 } }; class C : public QObject { Q_OBJECT public: C() {} ~C() override {} signals: void signalC(bool); public: // 通用连接方法核心实现 template<typename SlotFunc> QMetaObject::Connection ConnectMethod(QObject* receiverObject, SlotFunc functionPointer) { QMetaObject::Connection connection = QObject::connect(this, &C::signalC, receiverObject, functionPointer); return connection; } };
main函数实现
int main() { A* objA = new A(); B* objB = new B(); C* objC = new C(); // 调用通用连接方法,模板参数自动推导无需显式指定 QMetaObject::Connection connectionA = objC->ConnectMethod(objA, &A::slotA); QMetaObject::Connection connectionB = objC->ConnectMethod(objB, &B::slotB); // 测试触发信号 emit objC->signalC(true); // 内存释放逻辑 delete objA; delete objB; delete objC; return 0; }
注意事项
- 槽函数需要以
&类名::槽函数名的成员函数指针格式传入,不要写成对象成员调用格式objA->slotA,否则会报语法错误 - 如果槽函数存在重载,需要用
static_cast显式指定槽函数的签名,避免模板推导错误 - 该实现仅支持Qt5及以上版本的函数指针式信号槽语法,类型安全度远高于Qt4的字符串式宏写法
- 所有用到信号槽的QObject子类都必须添加Q_OBJECT宏,且项目要正确开启Qt的MOC编译
内容的提问来源于stack exchange,提问作者Anas Deshmukh
相关产品推荐
相关产品推荐

