信号与槽及示例程序
1. 综述
Qt的窗口部件可以通过发射信号(signal)来表明一个用户动作已经发生或者一个状态已经改变。
槽(slot)与信号相连。每当发射信号时,会自动调用槽。一个信号可以连接多个槽,一个槽可以与多个信号相连,一个信号可以连接另一个信号(当一个信号发射时,相连的另一个信号也发射)。
2. connect() 语句
connect(senderPointer,SIGNAL( signalFunction ), receiverPointer, SLOT( slotFunction ) );
其中senderPointer和receiverPointer分别是信号发生对象和槽响应对象的指针。signalFunction和slotFunction是不带参数的函数名,可以将前者视为 监测是否有指定信号发生的 监测函数的函数名,后者视为 信号发射后 槽所响应的动作对应的 响应函数的函数名。
当senderPointer指向的对象发生了signalFunction函数指定的动作(即信号)时,receiverPointer所指向的对象就执行slotFunction函数所要求的动作。
例如,connect(button,SIGNAL(clicked()),&app,SLOT(quit()));
当button所指向的对象(一个按钮)发生了被点击(也就是clicked())操作时,&app这个指针所指向的应用程序(app是一个QApplication的名称,详见下述例程)就执行退出(也就是quit())操作。 也就是,当按钮被点击了,应用程序就退出。
3. 两个小例程
例1,点击按钮后退出程序。首先看看怎样直接编写程序来创建按钮。具体过程如下:
首先,创建一个空的项目或工程如图1所示,<文件> - “新建文件或工程” - “其他项目” - “空的Qt项目” - 。。。
图1. 创建一个空的项目或工程
然后再添加新的源文件如图2所示,选中下图2中所示的工程quitB(图中左边话红线处),然后右键选择 “添加新文件” - “C++” - “C++源文件” - 。。。
注意:文件的保存路径不能有中文!!
图2. 添加新的源文件
再在添加的源文件中编写程序,如下图3所示。其中左边圈出来的是运行结果。
备注:选中项目quitB,然后点击软件左下角倒数第三个绿色图标(像音乐播放图标一样的)就是一键运行,这应该就不用再多说啦。
图3. 运行结果
具体的程序如下:
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[]){
//创建一个QApplication
QApplication app(argc, argv);
//创建一个QPushButton
QPushButton *button = new QPushButton("Quit");
//信号与槽connect()语句
QObject::connect(button, SIGNAL(clicked()), &app, SLOT(quit()));
button -> show();
//程序进入消息循环,等待可能输入进行响应
return app.exec();
}
例2,点击按钮更改窗口标题或退出应用程序。这次使用ui文件方式来创建按钮。具体过程如下:
首先,创建一个空的项目或工程,如图4所示,这次选的是“Qt控件 项目” - “Qt Gui应用”。
图4. 创建工程
然后,进入ui编辑界面,如下图5所示。
图5. 进入ui编辑界面
接下来是编辑ui文件,如下图6所示,先点开左边的 “Buttons” 栏,点住 “Push Button” 拖拽到中间的编辑框中,连续操作两次。先选中需要编辑的元件(这里指的是按钮),然后双击右边红色圈起来的地方,就可以编辑新的元件名称,注意,起英文名字。本例中的程序是更改了名字的,两个按钮的名字分别改为“changeBtn”和“quitBtn”,因为更改名字后比较方便以后查看或者更改自己写过的程序。
图6. 编辑ui文件
再进行程序编写。如图7所示,先点软件最左边的从上往下第二个图标即可进入编辑程序的界面;然后双击 “头文件” 下的 mainwindow.h; 接下来就是在原有程序(创建工程时自动添加的)的基础上增加一些语句。
图7. 编辑头文件
然后还需要编辑 .cpp文件,如下图8所示。双击 “源文件” 下的mainwindow.cpp, 增加一些语句。
图8. 编辑 .cpp文件
最后,运行程序。运行结果如下图9所示。
图9. 运行结果
具体程序如下:
mainwindow.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();
//添加以下内容
private slots:
//声明槽
void changeTitleSlot();
//添加以上内容
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp程序
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//添加以下内容1
//一个connect()
//当前ui界面上的叫changBtn的按钮发送一个点击信号(也就是这个按钮被点击了)时,要求当前类执行changTitleSlot函数定义的操作
QObject::connect(ui->changeBtn, SIGNAL(clicked()),this, SLOT(changeTitleSlot()) );
//另一个connect()
//当前ui界面上的叫quitBtn的按钮发送一个点击信号(也就是这个按钮被点击了)时,要求当前类执行退出操作
QObject::connect(ui->quitBtn, SIGNAL(clicked()), this, SLOT(close()));
//添加以上内容1
}
MainWindow::~MainWindow()
{
delete ui;
}
//添加以下内容2
void MainWindow::changeTitleSlot(){
//更改窗口名
this -> setWindowTitle("new title");
}
//添加以上内容2