如何全局监听Qt类的信号?无需逐个连接该类的每个实例
如何监听某个类所有实例发出的信号?
Qt本身没有提供直接监听某类所有实例信号的内置API,但可以通过以下几种方式实现类似需求:
方法一:通过全局信号转发器(推荐)
创建一个单例的信号转发类,让所有Foo实例在构造时自动将自身的test信号转发到这个全局转发器,之后只需连接一次转发器的信号即可捕获所有Foo实例的信号。
步骤1:实现全局信号转发器
#include <QObject> class FooSignalHub : public QObject { Q_OBJECT public: // 获取单例实例 static FooSignalHub* instance() { static FooSignalHub hub; return &hub; } signals: // 和Foo类的test信号签名一致 void test(int x); private: // 禁止外部实例化 FooSignalHub() = default; };
步骤2:修改Foo类,自动转发信号
在Foo的构造函数中,将自身的test信号连接到全局转发器的同名信号:
class Foo: public QWidget { Q_OBJECT public: Foo(QWidget* parent = 0) : QWidget(parent) { // 自动连接自身信号到全局转发器 connect(this, &Foo::test, FooSignalHub::instance(), &FooSignalHub::test); } signals: void test(int x); };
步骤3:单次连接实现全局监听
之后只需连接一次全局转发器的信号,就能捕获所有Foo实例发出的test信号:
connect(FooSignalHub::instance(), &FooSignalHub::test, [this](int x) { // 处理所有Foo实例的test信号 });
方法二:批量遍历已有实例连接信号
如果所有Foo实例都有共同的父对象,可以遍历父对象的所有子部件,筛选出Foo类型的实例批量连接:
// 假设parent是所有Foo实例的父部件 for (auto widget : parent->findChildren<Foo*>()) { connect(widget, &Foo::test, [this](int x) { // 处理信号 }); }
注意:这种方法仅对已经创建的实例有效,后续动态创建的Foo实例需要额外手动连接。
内容的提问来源于stack exchange,提问作者Cesar
相关产品推荐
相关产品推荐

