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)));


下面我们来看一个程序界面。


qt深度学习算法 qt基础入门_qt


 

程序功能是当拖动QSlider时,界面的四个控件会同时获取并同步QSlider的值。

我们来看一下程序代码:

h文件

#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的元对象系统可以再任何的c++编译器下工作。

这个机制有如下工作:
1)Q_OBJECT宏声明了一些内省函数,这些函数必须在QOBJECT的子类(metaObject(),tr(),qt_metacall()等)中实现;
2)Qt的moc实现Q_OBJECT和所有signals声明的函数
3)QOBJECT的成员函数利用内省的功能来做完成他们的工作,像connection(),disconnect();

所有的这些工作都是依靠qmake,moc和QOBJECT来自动处理的,我们不需要去考虑他们的细节。