• qt5 断开 lambad槽


    项目中使用lambda表达式绑定槽非常方便,但是在断开槽的时候遇到了问题,通过查遍资料没有解决最后找到原因,在此记录。

    复现问题

    lambda绑定槽

    QObjectDemo有一个sigNum信号, 通过lambda绑定:

    signals:
        void sigNum();

    MainWindow.cpp:

    通过connect绑定sigNum信号,槽为lambda表达式,在发送信号前调用disconnect()函数断开MainWindow实例相关所有信号槽:

    QObjectDemo *demo = new QObjectDemo;
    QObject::connect(demo, &QObjectDemo::sigNum, []() {
         qDebug() << "abc";
    });
    this.disconnect(demo, nullptr, this, nullptr);//断开MainWindow示例和*demo实例关联的所有信号槽
    emit demo->sigNum();;//发送信号

    正常情况下, 不会输入abc, 但执行后发现, 在发送信号后, 仍然输出了 abc ,也就是说this.disconnect()并没有断开成功!

    问题解决

    在使用lambda当做槽时,如果考虑后期需要断开槽, 需要提供接受者, 如果不考虑后期断开槽,可以不提供接受者。

    把例子中connect参数中,添加接受者,信号槽正常断开:

    QObjectDemo *demo = new QObjectDemo;
    QObject::connect(demo, &QObjectDemo::sigNum, this, []() {
         qDebug() << "abc";
    });
    disconnect(demo, nullptr, this, nullptr);//断开MainWindow示例和*demo实例关联的所有信号槽
    emit demo->sigNum();;//发送信号

    注意在调用disconnect断开的时候,接受者是那个引用, disconnect参数中接受者也需要传那个引用,例如此处connect中接受者是this,所以在断开的时候接受者也是this: 

    disconnect(demo, nullptr, this, nullptr);

    此处接受者不一定是this(MainWindow引用),也可以是任何集成QObject的引用,例如接受者为  *demo2  :

    QObjectDemo *demo2 = new QObjectDemo;
    QObjectDemo *demo = new QObjectDemo;
    connect(demo, &QObjectDemo::sigNum, demo2, [](){
        qDebug() <<"hello ...";
    });
    disconnect(demo, nullptr, demo2, nullptr);
    emit demo->sigNum();;//发送信号

    发现不会输出"hello...", 信号槽也能正常断开!

    在Qt 官方文档中也提到了没有接收者引用的connect信号槽实例,是没有办法断开的。

    connect 没有receiver实例: https://doc.qt.io/qt-5.15/qobject.html#connect-4

     

    对于没有接受者的信号槽, 文档也作了说明,没有receiver(接收者),是没法断开槽的...:

  • 相关阅读:
    使用xfire
    db2 存储过程编写定义
    mac下使用eclipse的svn报错问题

    nsis打包过程
    mac快捷键以及增加桌面
    struts2 无法访问static目录下的内容的解决办法
    linux下安装db2
    ORACLE01034错误解决
    cannot restore segment prot after reloc: Permission denied
  • 原文地址:https://www.cnblogs.com/GengMingYan/p/16416383.html
Copyright © 2020-2023  润新知