QT入门(二)信号与槽机制
QT入门(二)信号与槽机制信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的
QT入门(二)信号与槽机制
信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。
4.1 系统自带的信号与槽
下面我们完成一个小功能,上面我们已经学习了按钮的创建,但是还没有体现出按钮的功能,按钮最大的功能也就是点击后触发一些事情,比如我们点击按钮,就把当前的窗口给关闭掉,那么在Qt中,这样的功能如何实现呢?
其实无法两行代码就可以搞定了,我们看下面的代码
QPushButton * quitBtn = new QPushButton("关闭窗口",this);
connect(quitBtn,&QPushButton::clicked,this,&MyWidget::close);
connect()函数最常用的一般形式:
connect(sender, signal, receiver, slot);
参数解释:
- sender:发出信号的对象
- signal:发送对象发出的信号
- receiver:接收信号的对象
- slot:接收对象在接收到信号之后所需要调用的函数(槽函数)
那么系统自带的信号和槽通常如何查找呢,这个就需要利用帮助文档了,在帮助文档中比如我们上面的按钮的点击信号,在帮助文档中输入QPushButton,首先我们可以在Contents中寻找关键字 signals,信号的意思,但是我们发现并没有找到,这时候我们应该想到也许这个信号的被父类继承下来的,因此我们去他的父类QAbstractButton中就可以找到该关键字,点击signals索引到系统自带的信号有如下几个
小例子:按下按钮改变另一个按钮上的数字
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
#include <QDebug>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
void change_number();
QPushButton btn,b1,b2;
int count=0;
};
#endif // WIDGET_H
widget.cpp:
#include "widget.h"
Widget::Widget(QWidget *parent) //构造函数
: QWidget(parent)
{
btn.setParent(this); //如果要是btn依附与窗口,则需要给它指定父类
btn.setText("exit"); //设置文字
btn.move(200,200); //设置位置
btn.setWindowTitle("project_1"); //设置应用程序标题
//connect(b1,发出的信号,this,处理信号的槽函数)
//b1,信号的发出者,此参数为指针
//&QPushButton::clicked,&+信号发出类的名字+::+信号的名字
//this,信号接收者,此参数是一个指针
//&Widget::close,信号的处理函数,属于this
connect(&btn,&QPushButton::clicked,this,&Widget::close);
b1.setParent(this);
b2.setParent(this);
b1.setText("change_num");
b2.setText("0");
b1.move(100,50);
b2.move(100,100);
//按下b1,改变b2的数字,b2的数字在0,1二者切换
connect(&b1,&QPushButton::clicked,this,&Widget::change_number);
}
Widget::~Widget() //析构函数
{
qDebug()<<"析构完成"; //需要包含头文件QDebug
}
void Widget::change_number()
{
if(count==0)
{
count=1;
b2.setText("1");
}
else
{
count=0;
b2.setText("0");
}
}
4.2自定义信号和槽
并不仅仅是使用系统提供的那部分,还会允许我们自己设计自己的信号和槽。
下面我们看看使用 Qt 的信号槽:
自定义信号槽需要注意的事项:
- 发送者和接收者都需要是QObject的子类(当然,槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);
- 信号和槽函数返回值是 void
- 信号只需要声明,不需要实现
- 槽函数需要声明也需要实现
- 槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;
- 使用 emit 在恰当的位置发送信号;
- 使用connect()函数连接信号和槽。
- 任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数
- 信号槽要求信号和槽的参数一致,所谓一致,是参数类型一致。
- 如果信号和槽的参数不一致,允许的情况是,槽函数的参数可以比信号的少,即便如此,槽函数存在的那些参数的顺序也必须和信号的前面几个一致起来。这是因为,你可以在槽函数中选择忽略信号传来的数据(也就是槽函数的参数比信号的少)。
例子:实现按钮操作1窗口跳转2窗口,2窗口回到1窗口


mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QDebug>
#include <subwidget.h>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
QPushButton b1;
SubWidget subwin; //窗口2
void win_hide();
void win_show();
};
#endif // MAINWINDOW_H
subwidget.h
#ifndef SUBWIDGET_H
#define SUBWIDGET_H
#include <QWidget>
#include <QPushButton>
class SubWidget : public QWidget
{
Q_OBJECT
public:
explicit SubWidget(QWidget *parent = 0);
QPushButton* b2 = new QPushButton;
QPushButton* b3 = new QPushButton;
void myslot();
signals:
// 自定义信号, 必须使用signals 声明
void sigSub();
//void sigSub(int , QString);
/*
* 1. 可以有参数
* 2. 可以重载
* 3. 返回值为void
* 4. 发送信号: emit + 信号名;
* emit sigsub();
*/
public slots:
};
#endif // SUBWIDGET_H
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
b1.setParent(this);
b1.setText("下一步");
b1.resize(70,35);
b1.move(100,100);
this->resize(600,400);
//由mainwin到subwin
connect(&b1,&QPushButton::clicked,this,&MainWindow::win_hide); //点击下一步到下一个窗口
//由subwin回到mainwin
//void (SubWidget::*MySigSub)() = &SubWidget::sigSub; //sigSub若有函数重载需要加上这句话指定是哪个函数,比如现在这句指定无参的那个函数
connect(&subwin,&SubWidget::sigSub,this,&MainWindow::win_show); //收到sigSub信号,则执行win_show函数
setWindowTitle("step_1");
}
MainWindow::~MainWindow()
{
}
void MainWindow::win_hide()
{
// 隐藏自己
hide();
// 显示下一个窗口
subwin.show();
}
void MainWindow::win_show()
{
// 显示自己
show();
// 隐藏上一个窗口
subwin.hide();
}
subwidget.cpp
#include "subwidget.h"
SubWidget::SubWidget(QWidget *parent) : QWidget(parent)
{
b2->setParent(this);
b2->setText("上一步");
b2->move(100,100);
this->resize(600,400);
connect(b2,&QPushButton::clicked,this,&SubWidget::myslot); //按下“上一步按键则执行myslot函数,发送信号
b3->setParent(this);
b3->setText("退出");
b3->move(200,100);
connect(b3,&QPushButton::clicked,this,&SubWidget::close);
setWindowTitle("step_2");
}
void SubWidget::myslot()
{
emit sigSub(); //发送信号
}
更多推荐


所有评论(0)