第一:QT中信号与槽简介
在学习Qt的过程中,信号与槽是必不可少的部分,也是QT编程的基础。后面进行QT信号与槽开发的时候,统一采用代码绘制界面,可以锻炼我们的布局能力,和代码逻辑能力。
信号与槽是QT的编程基础,因为有了信号与槽的编程机制,在QT中处理界面各个组件交互操作时变得更加直观和简单。
信号就是在特定情况下被发射的事件,例如PushButton最常见的信号就是鼠标点击时发射的clicked()信号等。
GUI程序设计的主要内容就是对界面上各组件的信号的响应,只需要知道什么情况下发射哪些信号,合理地去响应和处理这些信号就可以了。
槽(Slot)就是对信号响应的函数。槽函数是一个函数,与一般的C++函数是一样的,可以定义在类的任何部分(public\private或protected),可以具有任何参数,也可以直接被调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。
信号与槽关联是用QObject::connect()函数实现的,基本格式是:
QObject::connect(sender,SIGNAL(signal()),receiver,SLOT(slot));
connect()是QObject类的一个静态函数,而QObject是所有QT类的基类,在实际调用时可以忽略前面的限定符,所以可以直接写成:
connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
其中,sender是发射信号的对象的名称,signal()是信号名称。信号可以看做是特殊的函数,需要带括号,有参数时还需要指明参数。receiver是接收信号的对象名称,slot()是槽函数的名称,需要带括号,有参数时还需要指明参数。
第二:如何在项目里创建信号
由于信号只需声明,无需定义。所以我们只需要在 mianwindow.h 里声明信号即可。代码如 下,如下图黑色加粗部分代码就是创建的信号。
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); signals: //声明一个信号,只需要声明,无需定义 void pushButtonTextChanged(); private slots: void on_pushButton_clicked(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
第三:如何在项目中创建槽
创建槽的方法也很简单,也是直接在 mianwindow.h 里直接声明槽,在 mianwindow.cpp 里 实现槽的定义,声明槽必须写槽的定义(定义指函数体的实现),否则编译器编译时将会报错。
槽有以下特点:
1. 槽可以是任何成员函数、普通全局函数、静态函数
2. 槽函数和信号的参数和返回值要一致
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QPushButton> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); signals: //声明一个信号,只需要声明,无需定义 void pushButtonTextChanged(); private slots: void on_pushButton_clicked(); //声明一个槽函数 void changeButtonText(); //声明按钮点击的槽函数 void pushButtonClicked(); private: Ui::MainWindow *ui; //声明一个对象pushButton QPushButton *pushButton; }; #endif // MAINWINDOW_H
第四:项目中连接信号与槽
派生类::派生类构造函数(总参数列表):基类构造函数(参数列表) //基类构造函数的参数列表是实参。
{
派生类中的数据成员初始化;
}
信号槽连接的代码如下。
connect(pushButton, SIGNAL(clicked()), this, SLOT(pushButtonClicked()));
connect(this, SIGNAL(pushButtonTextChanged()), this, SLOT(changeButtonText()));
具体代码实现如下:
#include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { /* 设置窗体的宽为 800,高为 480 */ this->resize(800,480); /* 实例化 pushButton 对象 */ pushButton = new QPushButton(this); /* 调用 setText()方法设定按钮的文本 */ pushButton->setText("我是一个按钮"); /* 信号与槽连接 */ connect(pushButton, SIGNAL(clicked()), this,SLOT(pushButtonClicked())); connect(this, SIGNAL(pushButtonTextChanged()), this,SLOT(changeButtonText())); } MainWindow::~MainWindow() { } /* 实现按钮点击槽函数 */ void MainWindow::pushButtonClicked() { /* 使用 emit 发送信号 */ emit pushButtonTextChanged(); } /* 实现按钮文本改变的槽函数 */ void MainWindow::changeButtonText() { /* 在槽函数里改变按钮的文本 */ pushButton->setText("被点击了!"); }
分析:连接信号与槽,整个流程就是当点击了按钮,然后触发了 pushButtonClicked(),pushButtonClicked()槽里发送 pushButtonTextChanged()信号,changeButtonText()槽响应 pushButtonTextChanged()信号,我们在 changeButtonText()槽实现响应的动作(事件)。最终的实现效果是按钮的文本由“我是一个按钮”被点击时变成“被点击 了!”