• 【QT小记】QT中信号和槽的基本使用


    QObject::connect

    QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, 
    const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
    
    • 1
    • 2

    sender: 信号发送者
    signal: 信号
    receiver: 信号接收者
    mrthod: 槽函数
    type: 连接类型

    自定义信号

    • 使用宏signals
    signals:
        // 未带参数
        void signal_doSomething1();
        // 带参数
        void signal_doSomething2(int value);
        // 带自定义参数
        void signal_doSomething3(const Person &person);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    槽函数

    • 使用宏slots
    • 正常的函数也可以作为槽函数使用(QT5之后)
    public slots:
        void slot_doSomething1();
        void slot_doSomething2(int value);
        void slot_doSomething3(const Person &person);
    
    • 1
    • 2
    • 3
    • 4

    信号槽连接

        // QT4写法
        connect(this, SIGNAL(signal_doSomething1()), this, SLOT(slot_doSomething1()));
        connect(this, SIGNAL(signal_doSomething2(int)), this, SLOT(slot_doSomething2(int)));
        connect(this, SIGNAL(signal_doSomething3(const Person &)), this, SLOT(slot_doSomething3(const Person &)));
    
        // QT5写法
        connect(this, &Widget::signal_doSomething1, this, &Widget::slot_doSomething1);
        connect(this, &Widget::signal_doSomething2, this, &Widget::slot_doSomething2);
        connect(this, &Widget::signal_doSomething3, this, &Widget::slot_doSomething3);
    
        // 使用lambda表达式
        connect(this, &Widget::signal_doSomething1, this, [=] {
            slot_doSomething1();
        });
        connect(this, &Widget::signal_doSomething2, this, [=](int value) {
            slot_doSomething2(value);
        });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    注意点

    // 在使用lambda表达式来写槽函数的情况下
    // 如果指定了接收者对象,则槽函数是在接收者所在的线程执行的
    connect(this, &Widget::signal_doSomething1, this, [=] {
          slot_doSomething1();
    });
    // 如果没有指定接收者对象,则槽函数是在发送者所在的线程执行的
    connect(this, &Widget::signal_doSomething1, [=] {
           slot_doSomething1();
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    自定义参数跨线程使用

    • 非QT数据类型在跨线程信号槽使用时需先注册数据类型
    • 在同一线程使用则无需注册数据类型
    #include 
    qRegisterMetaType("Person");
    
    • 1
    • 2

    信号和槽重载

    • 使用QT4的写法则没有信号和槽重载的问题
    • 使用QT5的写法则会报错,需使用 QOverload::of 进行改写
    signals:
        // 信号重载
        void signal_doWork();
        void signal_doWork(int value);
    
    public slots:
        // 槽函数重载
        void slot_doWork();
        void slot_doWork(int value);
    
        // 信号槽连接
        // QT4写法
        connect(this, SIGNAL(signal_doWork()), this, SLOT(slot_doWork()));
        connect(this, SIGNAL(signal_doWork(int)), this, SLOT(slot_doWork(int)));
    
        // QT5写法
        connect(this, QOverload<>::of(&Widget::signal_doWork), this, QOverload<>::of(&Widget::slot_doWork));
        connect(this, QOverload::of(&Widget::signal_doWork), this, QOverload::of(&Widget::slot_doWork));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    第五个参数Qt::ConnectionType

    • 一般第五个参数都不用写,使用默认值Qt::AutoConnection
    类型描述
    Qt::AutoConnection(默认值)如果接收者位于发出信号的线程中,则使用Qt::DirectConnection。否则,使用Qt::QueuedConnection。在发出信号时确定连接类型。
    Qt::DirectConnection当信号发出时,槽函数将立即被调用。槽在信号线程中执行。
    Qt::QueuedConnection当控制返回到接收线程的事件循环时,将调用槽。槽在接收者的线程中执行。
    Qt::BlockingQueuedConnection与Qt::QueuedConnection相同,不同的是信号线程阻塞直到槽返回。如果接收方位于发出信号的线程中,则不能使用此连接,否则应用程序将死锁。
    Qt::UniqueConnection这是一个可以使用位或与上面任何一种连接类型组合的标志。当Qt::UniqueConnection被设置时,如果连接已经存在,QObject::connect()将会失败(例如,如果相同的信号已经连接到同一对对象的同一槽函数)。该标志是在Qt 4.6中引入的。

    解除连接

    • disconnect

    解除具体的一个信号与槽之间的连接

    QObject::disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
    
    • 1
    • blockSignals

    阻塞一对象发出的所有信号

    QObject::blockSignals(bool block)
    
    • 1
  • 相关阅读:
    回到街头 - 数字时尚嘉年华:Web3的时尚未来,4月香港兰桂坊盛大启幕
    保险项目中的一些名词解释
    [动态规划简单题] LeetCode 53. 最大子数组和
    Spring Cloud CLI简介
    淘宝/天猫 添加购物车API接口教程
    Python tkinter - 第9章 多选按钮控件(Checkbutton)方法
    【Elasticsearch 学习笔记 ES安装及使用】
    Redis(一)入门:五大数据类型的学习和理解①
    springmvc实现增删改查(创建一个BookStore数据库)完整开源代码
    Vue3源码reactive和readonly对象嵌套转换,及实现shallowReadonly
  • 原文地址:https://blog.csdn.net/lin786063594/article/details/126131678