Qt之信号与槽

目录

信号和槽的使用

自动生成槽函数

自定义信号和槽

带参数的信号和槽

信号与槽的连接方式

一对一

一对多

多对一

信号与槽的断开

使用lambda定义槽函数


槽的本质:对信号响应的函数。

信号函数和槽函数通常位于某个类中,和普通的成员函数相⽐,它们的特别之处在于:
信号函数⽤ signals 关键字修饰,槽函数⽤ public slots、protected slots 或者 private slots 修饰。signals 和 slots 是 Qt 在 C++ 的基础上扩展的关键字,专⻔⽤来指明信号函数和槽数;
信号函数只需要声明,不需要定义(实现),⽽槽函数需要定义(实现)。
信号和槽的使用
在 Qt 中,QObject 类提供了⼀个静态成员函数 connect() ,该函数专⻔⽤来关联指定的信号函数和槽函数。

connect函数原型:

connect (const QObject *sender,
        const char * signal ,
        const QObject * receiver ,
        const char * method ,
        Qt::ConnectionType type = Qt::AutoConnection )
参数说明:
sender:信号的发送者;
signal:发送的信号(信号函数);
receiver:信号的接收者;
method:接收信号的槽函数;
type:⽤于指定关联⽅式,默认的关联⽅式为 Qt::AutoConnection,通常不需要⼿动设定。
自动生成槽函数

通过在UI中创建控件,鼠标右键(找到   【转到槽】-> 【选择对应的信号】)来快速生成槽函数。

该方法对应的操作如下:

(1)  在 "widget.h" 头⽂件中⾃动添加槽函数的声明;
说明:
⾃动⽣成槽函数的名称有⼀定的规则。槽函数的命名规则为:on_XXX_SSS,其中:
1、以 " on " 开头,中间使⽤下划线连接起来;
2、" XXX " 表⽰的是对象名(控件的 objectName 属性)。
3、" SSS " 表⽰的是对应的信号。
如:" on_pushButton_clicked() " ,pushButton 代表的是对象名,clicked 是对应的信号。

(2)  在 "widget.cpp" 中⾃动⽣成槽函数定义.  

自定义信号和槽
1、⾃定义信号函数书写规范
(1)⾃定义信号函数必须写到 "signals" 下;
(2)返回值为 void,只需要声明,不需要实现;
(3)可以有参数,也可以发⽣重载;
2、⾃定义槽函数书写规范
(1)早期的 Qt 版本要求槽函数必须写到 "public slots" 下,但是现在⾼级版本的 Qt 允许写到类的 "public" 作⽤域中或者全局下;
(2)返回值为 void,需要声明,也需要实现;
(3)可以有参数,可以发⽣重载;
带参数的信号和槽
Qt 的信号和槽也⽀持带有参数, 同时也可以⽀持重载.
此处我们要求, 信号函数的参数列表要和对应连接的槽函数参数列表⼀致.
此时信号触发, 调⽤到槽函数的时候, 信号函数中的实参就能够被传递到槽函数的形参当中.
代码示例
widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

signals:
    void mySignal(const QString& text,const QString& text2);

public:
    void handleSignal(const QString& text);

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    connect(this,&Widget::mySignal,this,&Widget::handleSignal);

//    // 发射出自定义的信号
//    //发送信号的操作,也可以在任意合适的代码中,不一定非得在构造函数里
//    emit mySignal();
}

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

void Widget::handleSignal(const QString& text)
{
//    this->setWindowTitle("处理自定义信号");
    this->setWindowTitle(text);
}


void Widget::on_pushButton_clicked()
{
    // 发射出自定义的信号
    //发送信号的操作,也可以在任意合适的代码中,不一定非得在构造函数里
//    emit mySignal();
    emit mySignal("把标题设置为标题1","");
}

void Widget::on_pushButton_2_clicked()
{
    emit mySignal("把标题设置为标题2","");
}

结果演示:

信号与槽的连接方式
一对一

一对多

多对一

代码演示(一对多,多对一)

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

signals:
    void mySignal1();
    void mySignal2();
    void mySignal3();

public slots:
    void mySlot1();
    void mySlot2();
    void mySlot3();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    connect(this,&Widget::mySignal1,this,&Widget::mySlot1);
    connect(this,&Widget::mySignal1,this,&Widget::mySlot2);
    connect(this,&Widget::mySignal2,this,&Widget::mySlot1);
    connect(this,&Widget::mySignal2,this,&Widget::mySlot3);
}

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

void Widget::mySlot1()
{
    qDebug()<<"mySlot1";
}

void Widget::mySlot2()
{
    qDebug()<<"mySlot2";
}

void Widget::mySlot3()
{
    qDebug()<<"mySlot3";
}
信号与槽的断开
使⽤ disconnect 即可完成断开.
disconnect 的⽤法和 connect 基本⼀致
代码演示
widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void handleClick();
    void handleClick2();

//private slots:
//    void on_pushButton_clicked();

private slots:
    void on_pushButton_2_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.hpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    connect(ui->pushButton,&QPushButton::clicked,this,&Widget::handleClick);
}

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

void Widget::handleClick()
{
    this->setWindowTitle("修改窗口的标题");
    qDebug()<<"handleClick";
}

void Widget::handleClick2()
{
    this->setWindowTitle("修改窗口的标题2");
    qDebug()<<"handleClick2";
}


//void Widget::on_pushButton_clicked()
//{

//}

void Widget::on_pushButton_2_clicked()
{
    //先断开 pushButton 原来的信号槽
    disconnect(ui->pushButton,&QPushButton::clicked,this,&Widget::handleClick);
//    connect(ui->pushButton,&QPushButton::clicked,this,&Widget::handleClick2);
}
使用lambda定义槽函数

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QPushButton* button=new QPushButton(this);
    button->setText("按钮");
    button->move(200,200);

    connect(button,&QPushButton::clicked,this,[=](){
        qDebug()<<"lambda 被执行了!";
        button->move(300,300);
        this->move(100,100);
    });
}

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

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新绿MEHO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值