信号和槽机制
1. 概念
信号和槽是Qt自行定义的一种通信机制,实现不同对象之间的数据交互。
其本质就是函数的调用,一个对象发出信号,连接到该信号的对象,则会执行指定的动作(槽Slots )。
2. 定义
"信号 Signal "
class QPushButton {
Q_OBJECT // 元对象编译器 。
signals :
void clicked (); // 信号函数声明,注意信号函数不能自己写定义
};
"槽 Slot "
class QLabel {
Q_OBJECT // 元对象编译器
public slots :
void close (); // 槽函数,可以连接到某一个对象的信号上,也可以当做普通的成员函数用
};
《案例》创建一个按钮和一个标签两个组件,点击按钮时关闭标签。
"槽函数" connect
+--------+ +-----------+
| Button | | Lablel |
+--------+ "connect" +-----------+
| clicked| -----------> | close() |
| 信号 | | |
+--------+ +-----------+
3. 建立信号和槽的连接 "connect 成员函数"
QMetaObject::Connection QObject ::connect (
const QObject * sender,
const char * signal,
const QObject * receiver,
const char * method);
功能:建立信号和槽的连接
参数:
@sender :信号的发送对象指针(QObject的子类对象指针)
@signal :信号函数(eg:clicked () )
SIGNAL (clicked ()); // 将信号函数转换成 const char* 数据类型
@receiver :信号接收对象
@method :槽函数(eg:close () )
SLOT (close ()); // 将槽函数转换成 const char* 数据类型
【注】connect是QObject类中的静态成员函数,QObject类是Qt中绝大多数类的基类。
eg:
button对象和label对象连接
QObject::connect (&button, SIGNAL (clicked ()), &label, SLOT (close ()));
/** 代码演示 - button对象和label对象连接 **/
#include <QApplication>
#include <QPushButton>
#include <QLabel>
int main (int argc, char** argv) {
QApplication app (argc, argv);
QPushButton button ("关闭标签");
QLabel label ("Qt day02!");
button.show ();
label.show ();
// 信号和槽的连接
QObject::connect (&button, SIGNAL (clicked ()),
&label, SLOT (close ()));
return app.exec ();
}
练习:点击按钮,关闭整个应用程序(QApplication 的 Public Slots)
$ assistant
void closeAllWindows (); // 自己的共有槽函数
void quit (); // 继承QCoreApplication来的
4. 信号和槽连接语法规则
1 )大多数情况下,信号函数参数个数、顺序、类型和槽函数相同
QObject::connect (&A, SIGNAL (sig_func (int)),
&B, SLOT (slot_func (int))); // ok
QObject::connect (&A, SIGNAL (int, QString),
&B, SLOT (QString, int)); // error! ! !
2 )可以带有缺省参数
QObject::connect (&A, SIGNAL (sig_func (int)),
&B, SLOT (slot_func (int, int = 10))); // ok
3 )信号函数的函数参数可以多于槽函数,多余的将被忽略,反之不行
QObject::connect (&A, SIGNAL (sig_func (int, QString)),
&B, SLOT (slot_func (int))); // ok
4 ) 一个信号可以连接到多个槽函数
QObject::connect (&A, SIGNAL (sig_func (int)),
&B1, SLOT (slot_func1 (int))); // ok
QObject::connect (&A, SIGNAL (sig_func (int)),
&B2, SLOT (slot_func2 (int))); // ok
【注】当A对象发送信号sig_func,B1和B2的槽函数都会被执行,执行顺序不确定。
5 )多个信号可以连接到同一个槽函数
QObject::connect (&A1, SIGNAL (sig_func1 (int)),
&B, SLOT (slot_func (int))); // ok
QObject::connect (&A2, SIGNAL (sig_func2 (int)),
&B, SLOT (slot_func (int))); // ok
【注】无论是A1还是A2发送信号,B的槽函数都将会被执行