• C++Qt——信号与槽


    Qt信号与槽——建立信号与槽

    平常我们所见到的界面,鼠标点击一下指定的按钮,就会产生一定的效果。C++ Qt框架中的信号与槽机制是Qt进行对象间通信的一种方法,非常核心且有别于传统的回调函数或者消息传递机制。通过信号与槽,Qt能够在不同的对象之间安全地传递信息,而且这种机制是类型安全的。
    信号 (Signals):信号是由对象发出的消息,告知程序发生了某个事件(如用户点击按钮)。信号仅有声明,没有定义,它们被定义在QObject或其任何子类中。当特定事件发生时,相应的信号就会被发射(emit)。例如,QPushButton类有一个clicked()信号,当用户点击按钮时,这个信号被发射。
    槽 (Slots):”槽是用来响应信号的函数。当与信号相连的槽收到信号时,它就会被调用。和信号一样,槽也是QObject或其子类的成员。槽可以是普通的成员函数,也可以是lambda表达式或其他可调用的对象。
    信号与槽的连接 (Connecting Signals and Slots):要使信号和槽一起工作,需要将它们连接起来。Qt提供了QObject::connect函数(静态函数)来实现这一点。当连接建立后,如果信号被发射,对应的槽就会被调用。
    在这里插入图片描述

    一、 简单界面

    方法一 :演示新建一个QT项目。在ui设计界面,拖动一个button,下面有发送者、信号、接受者、槽,+ - 表示添加和删除。手动设置,如下的功能是点击窗口的按钮,窗口自动关闭。
    在这里插入图片描述
    方法二:了解即可。在下图的配置框中设置即可。

    在这里插入图片描述

    二、复杂事件设置信号与槽

    方法一:自动连接(使用UI文件),通过命名约定自动连接信号与槽。

    拖拽一个按钮,右键选择“转到槽”,选择相应的信号。
    在这里插入图片描述
    然后就可以在相应的函数进行操作。
    在这里插入图片描述
    运行点击按钮,生成结果。
    在这里插入图片描述

    void Widget::on_pushButton_clicked()
    {
        std::cout << "方法一btnuiClicked" << std::endl;
    }
    //on_pushButton_clicked()命名的槽会自动连接到相应的信号。
    //原型是on_objectName_signalName
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    方法二:使用QObject::connect

    拖拽一个按钮
    在这里插入图片描述

    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
        ui->setupUi(this);
        //方法二:在构造函数中进行信号与槽的绑定           这里信号是个宏
        //QObject::connect(const QObject *sender, SIGNAL(signal()), const QObject *receiver, SLOT(slot()))   这里信号是个宏
    
        QObject::connect(ui->btnCon,SIGNAL(clicked()),this,SLOT(no_btnCon_clicked()));
        //no_btnCon_clicked() 自己命名,头文件中需要声明
    }
    
    
    //方法二
    void Widget::no_btnCon_clicked()
    {
        std::cout << "方法二btnConClicked" << std::endl;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    //头文件
    private slots:
        void on_btnUi_clicked();//方法一
        void no_btnCon_clicked();//自己声明,方法二
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    方法三:使用c++11Lambda表达式

    拖拽按钮

    在这里插入图片描述

    /* 方法三:lambda表达式:
        QObject::connect(const QObject *sender, &Sender::signal,[=](){lambda body} )*/
        //lambda匿名函数,不需要头文件声明
        QObject::connect(ui->btnLambda,&QPushButton::clicked,[=](){
            
            std::cout << "方法三btnLambda" << std::endl;
        });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    方法四:使用函数指针

    直接连接信号与槽,可以利用ide的代码补全和检查错误。
    在这里插入图片描述

     /*方法四:函数指针
        QObject::connect(const QObject *sender, &Sender::signal, receiver, &Recive::slot);
            */
        QObject::connect(ui->btnPointer,&QPushButton::clicked,this,&Widget::on_btnPointer_clicked);
    
    //头文件
    private slots:
        void on_btnUi_clicked();
        void no_btnCon_clicked();
        void on_btnPointer_clicked();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述
    完整代码
    头文件

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include 
    #include 
    QT_BEGIN_NAMESPACE
    namespace Ui { class Widget; }
    QT_END_NAMESPACE
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = nullptr);
        ~Widget();
    
    private slots:
        void on_btnUi_clicked();
        void no_btnCon_clicked();
        void on_btnPointer_clicked();
    
    private:
        Ui::Widget *ui;
    };
    #endif // WIDGET_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    .cpp文件

    #include "widget.h"
    #include "ui_widget.h"
    
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
        ui->setupUi(this);
        /*方法二:在构造函数中进行信号与槽的绑定           这里信号是个宏
        QObject::connect(const QObject *sender, SIGNAL(signal()), const QObject *receiver, SLOT(slot()))   这里信号是个宏
        */
        QObject::connect(ui->btnCon,SIGNAL(clicked()),this,SLOT(no_btnCon_clicked()));
        //no_btnCon_clicked() 自己命名,头文件中需要声明
    
        //===============================
        /* 方法三:lambda表达式:
        QObject::connect(const QObject *sender, &Sender::signal,[=](){lambda body} )*/
        //lambda匿名函数,不需要头文件声明
        QObject::connect(ui->btnLambda,&QPushButton::clicked,[=](){
    
            std::cout << "方法三btnLambda" << std::endl;
        });
    
         //===============================
        /*方法四:函数指针
        QObject::connect(const QObject *sender, &Sender::signal, receiver, &Recive::slot);
            */
        QObject::connect(ui->btnPointer,&QPushButton::clicked,this,&Widget::on_btnPointer_clicked);
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    
    //方法一
    void Widget::on_btnUi_clicked()
    {
        std::cout << "方法一btnuiClicked" << std::endl;
    }
    
    
    //方法二
    void Widget::no_btnCon_clicked()
    {
        std::cout << "方法二btnConClicked" << std::endl;
    
    }
    
    //方法四
    void Widget::on_btnPointer_clicked()
    {
        std::cout << "方法四btnConClicked" << std::endl;
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
  • 相关阅读:
    每日一练 | 华为认证真题练习Day220
    【哈佛公开课】积极心理学笔记-06乐观主义(下)
    cpu常用命令
    Selenium-介绍下其他骚操作
    目标检测(6)—— YOLO系列V2
    C++之typeid的介绍
    Vue(模板语法 2)
    算法通关村第二关|青铜|链表反转
    Jacoco+git生成差异代码覆盖率测试报告
    同步复位,异步复位,异步释放同步复位
  • 原文地址:https://blog.csdn.net/qq_48335434/article/details/136173190