Qt编程信号与槽连接
因为业务需求,最近刚刚开始学习Qt编程。在使用信号与槽连接的时候遇到的不少问题。
看图
图上三个PushButton的对象名称分别为btn1,btn2,btn3。
现在要分别处理三个PushButton的clicked信号:
Btn1对应的槽名称为btn1Click()
Btn2对应的槽名称为on_btn2_clicked();
Btn3对应的槽名称为on_click_btn3()
在对应的ui_XXXXX.h文件中有如下代码
编译后,通过Qt的控制台报出如下错误:
启动程序后单击三个按钮都能够实现预期的功能。
在Qt的帮助文档中对QMetaObject::connectSlotsByName函数有如下的说明:
翻译过来的大概意思是:递归查询object的所有子类对象,并按照
void on_
格式将对象的槽与对应的信号进行连接。
假设有一个名为button1的QPushButton类子对象。捕获button1 clicked()信号的槽就是
voidon_button1_clicked();
创建一个发射对象信号与接收信号方方法的连接。如果连接成功返回真。反之,则返回假。
那么问题出来了,
btn1的信号与槽是怎么连接的?
源码是
QObject::connect(btn1,SIGNAL(clicked()),MainWindow,SLOT(btn1 Click()));*
。
。
QMetaObject::connectSlotsByName(MainWindow); #
通过前面介绍的定义可知connectSlotsByName不应该处理btn1Click()槽,注释掉#行代码
重新运行调试信息如下图
没有报出QMetaObject::connectSlotsByName的错误。
单击各个按钮可以发现btn1、btn3功能正常,btn2因为未显式连接无法捕获clicked()信号而失效。
btn2的信号与槽是怎么连接的?
因为在MainWindow对象中声明了on_btn2_clicked()槽,符合
QMetaObject::connectSlotsByName()
接口通过名称连接槽与信号的形式,所以btn2是通过QMetaObject::connectSlotsByName实现信号与对应槽的连接。
btn3的信号与槽是怎么连接的?
这就要回到前面了,按照QMetaObject::connectSlotsByName()
接口所规定的形式btn3的槽是不应该通过这个接口进行信号与槽的连接,但是为什么在前面的图片中出现了QMetaObject::connectSlotByName : no matching signal for on_clicked_btn3()这个错误呢?
那么QMetaObject::connectSlotByName是如何器作用的呢?
假设1:通过前缀on判断
将btn3的槽更改为xx_clicked_btn3(),重新编译
运行结果为
后台不在报出QMetaObject::connectSlotByName : no matching signal for on_clicked_btn3错误
假设1成立
假设2:与声明分段数有关
将btn3的槽更改为on_btn3();
编译后运行结果为
后台报出QMetaObject::connectSlotByName : no matching signal for on_btn3
结论:假设2不成立。
终结测试:
将btn3的槽修改为on_btn3_clicked()
编译运行的结果为:
后台未报出QMetaObject::connectSlotByName : no matching signal for XXXXX错误。
单击btn3按钮,槽函数响应两次。
终极总结
1、Qt中信号与槽的隐式连接通过connectSlotsByName实现,
且槽必须满足接口规定的格式。
2、隐式连接接口connectSlotsByName接口通过槽函数声明
的前缀判断槽是否进行隐式连接。
3、通过ui边界器进行信号与槽连接是进行显式连接。