C++通过函数访问QML

一、基本使用

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++里做

C++通过函数访问QML

  

三、设置组件基本属性

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

C++通过函数访问QML

 例子:

#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*对象。

原文链接: https://www.cnblogs.com/judes/p/12939000.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++通过函数访问QML

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/350085

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午6:05
下一篇 2023年3月2日 上午6:05

相关推荐