Qt的信号与槽可以让程序吧一些互不相干的对象绑定在一块,槽和普通的C++成员函数差不多,可以是虚函数或被重载,也可以共有、保护、或者是私有,且可以被其他C++成员直接调用,唯一不同的是经过signals和slots连接到一起,每当发射signals信号的时候可以自动调用绑定的槽。
Connect()的语法:
connect(sender,SIGNAL(signal),receiver,SLOT(slots));
sender,receiver必须是一个QObject的指针,signal和slot是根据声明的信号或槽的函数来决定参数的。例如:
- signals:
- void setvalue(int value);
- private slots:
- void changevalue(int value);
注意参数的一致性。
如果带参数那么connect应该是这个样子的。
connect(sender,SIGNAL(setvalue(int)),receiver,SLOT(changevalue(int)));
下面我们来看一个程序界面。
程序功能是当拖动QSlider时,界面的四个控件会同时获取并同步QSlider的值。
我们来看一下程序代码:
- #ifndef DIALOG_H
- #define DIALOG_H
- #include <QDialog>
- #include <QSpinBox>
- #include <QSlider>
- #include <QProgressBar>
- #include <QHBoxLayout>
- #include <QVBoxLayout>
- namespace Ui {
- class Dialog;
- }
- class Dialog : public QDialog
- {
- Q_OBJECT
-
- public:
- explicit Dialog(QWidget *parent = 0);
- ~Dialog();
- signals:
- void setvalue(int value);
- private:
- Ui::Dialog *ui;
- private slots:
- void changevalue(int value);
- };
- #endif // DIALOG_H
- #include "dialog.h"
- #include "ui_dialog.h"
- Dialog::Dialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::Dialog)
- {
- ui->setupUi(this);
- connect(ui->hslider,SIGNAL(valueChanged(int)),this,SIGNAL(setvalue(int)));
- connect(ui->sbox,SIGNAL(valueChanged(int)),this,SIGNAL(setvalue(int)));
- //disconnect(ui->sbox,SIGNAL(valueChanged(int)),this,SIGNAL(setvalue(int)));
- connect(this,SIGNAL(setvalue(int)),SLOT(changevalue(int)));
- }
- Dialog::~Dialog()
- {
- delete ui;
- }
- void Dialog::changevalue(int value)
- {
- ui->lcd->display(value);
- ui->probar->setValue(value);
- ui->sbox->setValue(value);
- ui->hslider->setValue(value);
- }
connect(ui->hslider,SIGNAL(valueChanged(int)),this,SIGNAL(setvalue(int)));//将QSlider的valueChanged信号绑定槽setvalue;
connect(ui->sbox,SIGNAL(valueChanged(int)),this,SIGNAL(setvalue(int)));//将QSpinBox的valueChanged信号绑定槽setvalue;
//disconnect(ui->sbox,SIGNAL(valueChanged(int)),this,SIGNAL(setvalue(int)));//代码演示如何动态断开槽链接
connect(this,SIGNAL(setvalue(int)),SLOT(changevalue(int)));//将setvalue信号绑定槽setvalue;
一个信号可以链接到多个槽。
多个信号可以链接到同一个槽
一个信号可以与另外一个信号链接(这里第一行与第二行已经演示了)。
动态连接移除功能很少被用到,因为除特别功能上的需要,当Qt删除对象时会自动移除与这个对象有关的所有链接。
Qt一个最大的特点就是他用特殊的机制来扩展c++。利用这个机制创建的软件组件是独立的,这些组件可以和其他的组件绑定在一起,而不需要知道他要绑定的组件的太多的信息。
这个机制就叫做元对象系统,它提供了两个重要的服务:signal-slot和内省。内省的功能对于实现signal-slots是很重要的,它允许应用程序员程序运行期间来获得关于子对象的“元信息”,包括对象和他的名字所支持的signal和slot列表。这个机制支持properties(Qt设计器广泛的使用)和文本转换(为了国际化)它也为QtScrpt单元打下了基础。从Qt4.2开始,properties可以动态的添加。
标准C++不支持Qt的元对象系统所需要的动态元信息。Qt利用分开的工具,moc,解析Q_OBJECT类的定义来解决这个问题,通过C++函数来使它有效。因为moc所有功能都是通过纯粹的C++来实现的,所以Qt的元对象系统可以再有如下工作:
1)Q_OBJECT宏声明了一些内省函数,这些函数必须在QOBJECT的子类(metaObject(),tr(),qt_metacall()等)中实现;
2)Qt的moc实现Q_OBJECT和所有signals声明的函数
3)QOBJECT的成员函数利用内省的功能来做完成他们的工作,像connection(),disconnect();
所有的这些工作都是依靠qmake,moc和QOBJECT来自动处理的,我们不需要去考虑他们的细节。