假设通过点击按钮来触发槽函数,对于信号槽的连接有如下几种方式:
1、槽函数声明在public slots下
(1)通过signal/slots方式连接信号槽
connect(button, SIGNAL(clicked()), this, SLOT(func()));
(2)通过作用域的方式连接信号槽
connect(button, &QPushButton::clicked, this, &showTable::func);
2、槽函数是一个全局函数
connect(btn, &QPushButton::clicked, func); //func是全局函数指针
3、槽函数是一个lambda函数
connect(button, &QPushButton::clicked, [](int i) {qDebug() << "hello" << i << endl; });
4、槽函数是普通成员函数
class demo { public: void func(){} } connect(button, &QPushButton::clicked, demoClass, &demo::func); //只能通过作用域方式连接
5、在ui中设置了按钮,信号槽的简便连接方式
在UI中放置了一个QPushButton按钮,并把类名设置为open,对于点击按钮触发的信号槽可以这样写:
class demo { public: void on_open_clicked(){} }
格式为on_xxx_clicked,就自动实现了按钮和槽函数的连接,不需要connect。
6、信号可以连接信号
class demo { public slots: void func(){} signals: void trigger(); } connect(button, SIGNAL(clicked()), demoClass, SIGNAL(trigger())); //信号连接信号 connect(demoClass, SIGNAL(trigger()), demoClass, SLOT(func())); //信号槽连接
点击按钮触发clicked信号,又因为按钮信号连接了demo类的信号,所以触发clicked信号后会触发trigger信号,最后触发func槽函数。
7、信号和槽函数参数类型必须一一对应,参数个数可以不一致,信号的参数个数要多于槽函数的参数个数,但是类型必须一一对应
(1)信号槽参数类型一致,个数一致
class demo { public slots: void triggerSlot(QString){} signals: void void triggerSignal(QString); } connect(demoClass, SIGNAL(triggerSignal(QString)), demoClass, SLOT(triggerSlot(QString)));
(2)信号槽参数类型一一对应,但个数不一致
class demo { public slots: void triggerSlot(QString){} signals: void void triggerSignal(QString, int); } connect(demoClass, SIGNAL(triggerSignal(QString, int)), demoClass, SLOT(triggerSlot(QString)));
需要注意的问题:
(1)如果信号发生重载就不可以直接用作用域的方式连接,因为无法判断传递什么类型的参数。
(2)同一个信号槽connect连接多次问题:connect连接多次,发一次信号,槽函数会被执行多次。
(3)如果出现connect连接时报不明确的问题,那是因为QT不允许多继承情况下,多个父类继承QObject,需要加QObject::connect()作用域