Qt 默认静态槽函数 connectSlotsByName浅析
Qt中生成槽函数的方式
在Qt中有3种生成槽函数的方式:
-
第一种就是手动写
connect
连接函数,函数原型如下://connect(信号的发送者,信号的具体信息,信号的接受者,信号的处理[槽]) [static] QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
-
第二种就是在qt设计师界面,下方手动点击绿色的+按钮添加信号和槽函数,其生成的
connect
连接函数生成在ui_widget.h
的setupUi()
末尾。如:QObject::connect(btnClose, SIGNAL(clicked()), Widget, SLOT(close()));
-
第三种就是在qt设计师界面,右键控件,点击转到槽/Go to slot,系统会自动生成
on_xxx
函数,该函数会自动在.h文件和.cpp文件中声明和实现(函数体当然是自己写)。
本文针对第三种自动生成的槽函数进行分析。
QMetaObject::connectSlotsByName()
上文提到的第二种方式并不会在普通的项目文件中生成signal
和slot
的连接,而是生成在ui_widget.h
文件里。
在ui_widget.h文件中的setupUi()
函数末尾有这么一句:
QMetaObject::connectSlotsByName(MainWindow/Widget/Dialog);
Qt助手中给出的函数原型是:
[static] void QMetaObject::connectSlotsByName(QObject *object)
功能:递归搜索给定对象的所有子对象,并将来自这些子对象的匹配信号连接到以下形式的对象插槽:
void on_<object name>_<signal name>(<signal parameters>);
如果对象本身具有正确设置的对象名称,则其自身的信号也将连接到其各自的插槽。
举例:
假设我们的对象有一个类型为QPushButton
的子对象,对象名为button1
。捕捉按钮的clicked()
信号的槽是:
void on_button1_clicked();
总结
综上所述,只要槽函数名规则是这样的:on_子对象名_信号名
,如:
public slots:
void on_actionNew_triggered();
就可以不用手写connect
函数来连接信号和槽了!
但很明显,这种方式的局限性是只能绑定出信号和槽的一对一关系,如果要实现一个信号可以有多种槽函数响应则无法用这种方法,还是得手写connect()
。
如果一定要用这种自动生成的与名字绑定的槽函数实现多个槽函数响应1个信号,可以直接复制写好的函数体,或者在函数体内调用写好的槽函数。
需要注意:
- 尽量不要让QObject出现相同的objectName
- 对于自定义的槽函数进行手动连接时,不要以
on_
开头,养成良好的习惯 - 如果同名,
connectSlotsByName()
只会给其中一个建立缺省的信号槽的连接