• 【无标题】qml与c++数据交互的一种方式


    迫于无奈开始写android的程序,以前使用QWidget的方式试过,虽然界面可以实现,但是最后调用摄像头时,未能成功,再没有继续。这几天开始使用qml进行尝试,在使用的过程中,其中的一个难点,就是在qml与c++中数据的交互。

    我所使用的方式,是通过C++调用远端的webservice,再次数据送到qml端,不说原理了,直接上代码的实现过程。需要明白一点:qml不接受QList的类方式,所以使用了QList。大致分为四步,按需要看:

    一、定义可交互的类,可以IDE生成中选择基类为QObject完成即可,基本代码自动生成。

    image-20220905155941061

    h:

    #ifndef TEST_H
    #define TEST_H
    
    #include 
    
    class test : public QObject
    {
        Q_OBJECT
    public:
        explicit test(QObject *parent = nullptr);
    
    signals:
    
    public slots:
    };
    
    #endif // TEST_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    cpp:

    #include "test.h"
    
    test::test(QObject *parent) : QObject(parent)
    {
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    以上文件中,最重要的两点:继承自QObject以及包含Q_OBJECT均完成。

    定义属性时,需要写在Q_OBJECT下面,没有分号,可以使用快捷键对相关的代码进行自动生成,演示一个字段属性,完成后的代码如下,字段名为name:

    image-20220905160919877

    #ifndef TEST_H
    #define TEST_H
    
    #include 
    
    class test : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QString name READ name WRITE setName)
    public:
        explicit test(QObject *parent = nullptr);
        
        QString name() const
        {
            return m_name;
        }
        
    signals:
    
    public slots:
        void setName(QString name)
        {
            m_name = name;
        }
        
    private:
        QString m_name;
    };
    
    #endif // TEST_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
    • 27
    • 28
    • 29
    • 30
    • 31

    在自动生成数据时,最好先写入一个private节,这个自动生成的时候没有,定义后,使用的私有变量会放在这里,否则会跟在public slots下,反正是最下面了。

    二、数据操作类

    数据操作类的生成方法与上步类似,不同的是需要定义操作的方法,以返回数据的为数据集为例,在public中定义一个方法,类名定义为c_test:

    Q_INVOKABLE QList getData() const;
    
    • 1

    如果返回的只是一个单值,则这样:

    Q_INVOKABLE QString getData() const;
    
    • 1

    赋值:

    QList c_test::getData() const
    {
        QList r_list;
        ...
        test *t1 = new test;
        t1.setName("...");
        r_list.append(t1);
        ...
        return r_list;
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    三、注册

    注册是指将C++的类注册到qml中供调用,貌似有两种方式,我使用的是setContextProperty。在main中,connect前:

        engine.rootContext()->setContextProperty("c_test", new c_test);
    
    • 1

    经测试,在1中所定义的类,不需要注册。

    四、qml调用

    将值给ListMode时,需要进行一次迭代。

    var data = c_test.getData()
    _model.clear()
    for(var i=0;i
    • 1
    • 2
    • 3
    • 4
    • 5

    如上代码中的c_test.getData()就是使用注册的类进行的操作。

    此处迭代是必须的,不能直接给model。

    在qml中显示:

    Text{
    	text: name
    	}
    
    • 1
    • 2
    • 3

    这里所使用的name,就是在一的类里所定义的属性。

    这个一直做为拦路虎的东西,在实现后发现也并不是很麻烦。以上方式测试通过,熟练了一种之后,如果需要可以再看其它,应该就简单了吧。

  • 相关阅读:
    Spring整合MyBatis导致一级缓存失效问题
    如何借助cpolar内网穿透连接本地树莓派(1)
    CSRF漏洞利用与防御
    常用的linux命令简要说明以及命令全名理解
    Python学习之Pytorch
    【推荐系统】推荐基础算法-基于稀疏自编码的推荐方法
    golang convert json string to map
    【Linux常用命令15】shell脚本
    SpringBoot的测试方案
    Linux 服务器运维管理面板1Panel体验
  • 原文地址:https://blog.csdn.net/wjhx/article/details/126708542