• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C++通过函数访问QML

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

一、基本使用

1、QML

function setValue(value)
{
    if(value>1 || value<0)
    {
        return;
    }
    pen.score = value;
    pen.requestPaint();
}

2、C++

#include <QMetaObject>
QObject *root = ui->quickWidget->rootObject();
QMetaObject::invokeMethod(root, "setValue", Q_ARG(QVariant, QVariant(0.8)));

Q_ARG是入参,如果需要接收返回值用Q_RETURN_ARG(QVariant, returnedValue)

 

二、访问QML里的函数

如qml里有多个方块,每个方块有多个属性,怎么在c++里设置这些属性呢?可以通过:

①、动态绑定每一个参数【很麻烦,工作量也大】;

②、把每个方块的信息存入json里,再通过objectname获取到每一个方块,再通过function传入json字符串,由qml在function内部完成json解析获取对应参数;

③、。。

这里使用第二种方式

1、封装每个方块,主要由两个参数:nodeid和name

MyNode.qml

import QtQuick 2.0

Rectangle {
    id:rect;
    width: 50;
    height: 50;
    radius: 10;
    color: "green";
    property string node_id: "";
    property string name: "";
    function setColor(color)
    {
        rect.color = color;
    }
    function setNodeInfo(info)//传入json
    {
//        var json = '{"nodeId":"123", "name":"雷达主机"}';
        var obj = JSON.parse(info);
        console.log(obj.nodeId);
        console.log(obj.name);
        console.log(obj);
        node_id = obj.nodeId;
        name = obj.name;
    }
    MouseArea {
        anchors.fill: parent;
        onClicked: {
            console.log(node_id,name);
        }
    }
}

2、主qml

import QtQuick 2.7

Rectangle {
    width: 600;
    height: 400;
    color: "gray";
    Row {
        anchors.fill: parent;
        spacing: 10;
        MyNode {
            id: rect1;
            objectName: "rect1";
        }
        MyNode {
            id: rect2;
            objectName: "rect2";
        }
        MyNode {
            id: rect3;
            objectName: "rect3";
        }
    }
}

3、main.cpp

QUrl source("qrc:/qml/qml/Test.qml");
ui->quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView );
ui->quickWidget->setSource(source);
ui->quickWidget->setClearColor(QColor(Qt::transparent));
QObject *root = ui->quickWidget->rootObject();//根qml
QObject *pRect = root->findChild<QObject *>("rect1");//第一个方块
QMetaObject::invokeMethod(pRect, "setColor", Q_ARG(QVariant, QVariant("red")));//设置颜色
QMetaObject::invokeMethod(pRect, "setNodeInfo", Q_ARG(QVariant, QVariant("{\"nodeId\":\"123\", \"name\":\"雷达主机\"}")));//设置值,注意双引号需要转义

核心就是获取到方块指针,然后invoke函数,传入json,在qml里解析,这种方式应该效率不太高,因为我们希望所有解析都在c++里做

  

三、设置组件基本属性

如果QML里有一个Rectangle,Rectangle是有很多属性的,如大小、位置、颜色等,我们可以在C++里直接设置这些属性,通过setProperty函数:

 例子:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlComponent>
#include <QQuickWindow>
#include <QQuickView>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    // 1. 使用 QQmlApplicationEngine
//    QQmlApplicationEngine engine;
//    const QUrl url(QStringLiteral("qrc:/main.qml"));
//    engine.load(url);

//    QObject *rect = engine.rootObjects().at(0)->findChild<QObject*>("rect");
//    if (rect)
//        rect->setProperty("color", "red");



    // 2. 使用 QQmlEngine + QQmlComponent
//    QQmlEngine engine;
//    QQmlComponent *component = new QQmlComponent(&engine);
//    component->loadUrl(QUrl("qrc:/main.qml"));
//    QObject *topLevel = component->create();
//    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
//    window->show();

//    QObject *rect = topLevel->findChild<QObject*>("rect");
//      if (rect)
//          rect->setProperty("color", "red");



    // 3. 使用 QQuickView
    QQuickView *view = new QQuickView;
    view->setSource(QUrl("qrc:/main.qml"));
    view->show();

    QObject *rect = view->findChild<QObject*>("rect");
    if (rect)
        rect->setProperty("color", "red");

    //4.使用QQucikWidget
  //QObject *root = ui->quickWidget->rootObject();//根qml
  //QObject *pRect = root->findChild<QObject *>("rect1");//第一个方块
  //if (rect){
   //    rect->setProperty("color", "red");
  //}

    return app.exec();
}


import QtQuick 2.12
import QtQuick.Window 2.12

Item {
    visible: true
    width: 640
    height: 480

    Rectangle {
        objectName: "rect"
        anchors.fill: parent
        color: "yellow"
    }
}    

主要原理就是先获取这个QML对象,转成C++里的QObject*,然后通过setProperty函数进行属性设置,代码参考:https://blog.csdn.net/qq_34139994/article/details/105195447

 

 

 

PS:

例子1:

QVariant invokeRet;                                                     //qml函数返回值
bool ret = QMetaObject::invokeMethod(m_parent, "createOneMarkLine",
                                                 Qt::AutoConnection,
                                                 Q_RETURN_ARG(QVariant, invokeRet),
                                                 Q_ARG(QVariant, QVariant(o)),
                                                 Q_ARG(QVariant, QVariant(i*10)));
if(ret){
    QQuickItem* markLine = (QQuickItem*)invokeRet.value<QQuickItem*>();//创建成功的对象
}
else{
  qDebug()<<"err";
}

createOneMarkLine是qml里封装的函数,输入两个int,返回一个Item也就是对应Qt里的QQuickItem*对象。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C++基础--获取部分系统信息发布时间:2022-07-14
下一篇:
C#运算符&amp;|&amp;&amp;||发布时间:2022-07-14
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap