• QRunnable与外界互传对象


    1.概述

    QRunnable与外界互通讯是有两种方法的

    • 使用多继承。让我们的自定义线程类同时继承于QRunnable和QObject,这样就可以使用信号和槽,但是多线程使用比较麻烦,特别是继承于自定义的类时,容易出现接口混乱,所以在项目中尽量少用多继承。
    //使用多继承
    class runnable : public QObject,  public QRunnable
    {
        Q_OBJECT
    public:
        explicit runnable (QObject *parent = nullptr)
        {
            setAutoDelete(true);
        }
        void run() override{
        	emit sig_finish();
        }
    signals:
        void sig_finish();
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 使用QMetaObject::invokeMethod

    2.QMetaObject::invokeMethod的介绍

    • QMetaObject::invokeMethod()的创建方法 :
    QMetaObject::invokeMethod(QObject *obj, //使用的类const char
     *member, //调用函数名Qt::ConnectionType type,//调用类型
     QGenericReturnArgument ret,//用来存储返回值的类型
     QGenericArgument val0 = QGenericArgument(nullptr),
     QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(),QGenericArgument val4 = QGenericArgument(),QGenericArgument val5 = QGenericArgument(),QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(), QGenericArgument val8 = QGenericArgument(),QGenericArgument val9 = QGenericArgument())//最多有10个参数
    
    • 1
    • 2
    • 3
    • 4
    • 5

    *obj:需要把使用类传进去
    member:函数的名称
    type:调用类型:

    Qt::DirectConnnect 立即调用该成员函数
    Qt::QueuedConnection 一旦应用程序进入主事件循环,就会发送QEvent 并调用成员。
    Qt::BlockQueuedConnection当前线程将阻塞,直到事件被传递。使用此连接类型在同一线程中的对象之间进行通信将导致死锁
    Qt::AutoConnection 如果 obj与调用方位于同一线程中,则同步调用成员;否则,它将异步调用该成员。
    val0-val9:最多可以有10个参数

    传参的方式:使用宏传参

    Q_ARG(type,const Type&value)
    Q_RETURN_ARG(type, Type&value)

    3.QMetaObject::invokeMethod的使用

    实现QRunnable与外界互传对象

    • 假如我们在主界面中定一个函数Update_Result,用于接收QRunnable::run()发送来的值,并且返回结果给QRunnable::run()。
    //继承QRunnable
    class runnable : public QRunnable
    {
    public:
        explicit runnable(QObject *obj):obj(obj)
        {
            setAutoDelete(true);
        }
        void run() override{
            int value = 123;
            QString ret = "";//接收主线程函数的返回值
            QMetaObject::invokeMethod(obj, "Update_Result", Qt::BlockingQueuedConnection,//当前线程将阻塞,直到事件被传递。使用此连接类型在同一线程中的对象之间进行通信将导致死锁。
                                          Q_RETURN_ARG( QString, ret),//返回
                                          Q_ARG(int,value));//传参
    
             qDebug()<<"run返回值:"<<ret;
        }
        
        QObject *obj;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    	//Q_INVOKABLE 用于更新界面内容的作用是用来修饰成员函数,让被修饰的成员函数能够被元对象系统所唤起
        Q_INVOKABLE  QString Update_Result(int value){
          QString  ret =  QString("abc%1").arg(value);
          qDebug()<<"Update_Result:"<<ret;
           return ret;
        }
    	
    private slots:
         void on_pushButton_clicked(){
            IAPrunnable  *runnable= new IAPrunnable(this);
            QThreadPool::globalInstance()->start(runnable);
        }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    运行结果:

    Update_Result: “abc123”
    run返回值: “abc123”

  • 相关阅读:
    14. UE5 RPG使用曲线表格设置回复血量值
    PMP课程笔记:第13章 项目相关方管理
    C++ 哈希桶模拟实现(补充)
    4G网关BL100链接私有云平台教程
    【智能优化算法】从蚁群到动物园
    TSN中流的路由与调度的研究
    Java-02对象传递和返回
    为什么你辛苦肝的博客没人看?搭框架、排版、画图技巧这些你真的懂么?
    JavaScript 全局污染 回调函数
    【数仓设计】企业数仓为什么要进行分层?(六大好处)
  • 原文地址:https://blog.csdn.net/qq_41622002/article/details/133168112