信号和槽

设置信号和槽

本章我们将学习QtGUI项目的信号和槽机制

首先通过Qt Creator新建一个项目File->New File or Project...然后Applications->Qt Gui Application->Choose...这里我们使用缺省的MainWindowNext->Finish然后打开mainwindow.ui
ch2_01 然后我们从左侧的挂件中拖入Horizontal SliderProgress Bar到中央区域
ch2_02
接着
ch2_03
然后
ch2_04
最后编译运行

ch2_05

以上是通过使用GUI操作完成的,同样,我们也可以用代码实现: 在拖入Horizontal SliderProgress Bar并保存后,我们编辑mainwindow.cpp修改代码如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 新增加的代码
    connect(ui->horizontalSlider,
            SIGNAL(valueChanged(int)),
            ui->progressBar,
            SLOT(setValue(int)));
}

MainWindow::~MainWindow()
{
    delete ui;
}

然后编译,会得到相同的效果!

信号和槽

信号和槽用于对象间的通信.信号和槽机制是Qt的核心特性,这一特性和其他框架所提供的特性有很大的不同.

在GUI编程中,当我们改变一个部件时,我们通常希望通知其他的部件,更普遍的是,我们希望对象之间能够相互交流.例如,如果用户点击了关闭按钮,我们希望是关闭窗口的close()函数被调用.旧一点的工具包是通过回调实现的通信.通过传递函数指针到另一个函数来通知事件的,处理函数会在适当的时机调用回调函数.然而,回调这种方式有两个更本的缺陷:首先,不是类型安全的.我们无法确定处理函数会使用正确的参数来调用回调函数;其次,回调是强耦合的,因为处理函数必须知道要调用回调是哪个.

信号和槽机制是类型安全的:信号签名必须和槽签名匹配.(事实上一个槽的签名可能会比它接收的信号的签名要短些,因为槽可以忽略额外的参数)因此,编译器会帮助我们发现不匹配的错误.
信号和槽是松耦合的:一个发射信号的类可以不知道也不用关心是那个槽接收这个信号.
Qt的信号的槽机制确保当你将一个信号连接到一个槽时,槽会正确的使用信号的参数被调用.信号和槽可以接受任意数量和任何类型的参数,它们完全是类型安全的.

所有继承自QObject或者其子类(例如QWidget)都包含了信号和槽.当一个类的状态改变对其他类感兴趣时信号将会被这个类发射.这就是对象交流要做的全部!不需要知道有没有什么会接收这个发出的信号.

槽是用来接收信号的,同时它也是普通的成员函数.就像一个对象不知道什么东西会收到它的信号一样,槽也不知道有什么信号连接到了它.这就确保了可以用Qt创建真正独立的组件.你可以将多个信号连接到单个槽,你也可以将单个信号连接到多个槽,你甚至可以之将将一个信号连接到另一个信号!

Signals and Slots