首页 文章

如何从C访问嵌套的QML对象?

提问于
浏览
13

这是一个可重复的例子:

main.qml


import QtQuick 2.0

Item {
    id : root
    width: 360
    height: 360

    Text {
        id : t1
        text: qsTr("Hello World")
        property int someNumber: 1000
        anchors.centerIn: parent
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            Qt.quit();
        }
    }
}

main.cpp


#include <QtGui/QGuiApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QQmlProperty>
#include <QDebug>

#include "qtquick2applicationviewer.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile(QStringLiteral("qml/untitled/main.qml"));
    viewer.showExpanded();

    QQmlEngine engine;
    QQmlComponent component(&engine, "qml/untitled/main.qml");
    QObject *object = component.create();

    qDebug() << "Property value:" << QQmlProperty::read(object, "root.t1.someNumber").toInt();

    return app.exec();
}

我想访问 property 的QML Itemtext 的一些数字 . 上述方法没有产生所需的结果 .

怎么做?

3 回答

  • 0

    根据您的个人喜好,您有两种方式(至少)可以实现此目的 .

    QML代码扩展

    您可以向根项目添加属性别名,如下所示:

    import QtQuick 2.0
    
    Item {
        id : root
        width: 360
        height: 360
    
        property alias mySomeNumber: t1.someNumber // This is the addition
    
        Text {
            id : t1
            text: qsTr("Hello World")
            property int someNumber: 1000
            anchors.centerIn: parent
        }
        MouseArea {
            anchors.fill: parent
            onClicked: {
                Qt.quit();
            }
        }
    }
    

    C代码扩展

    由于QML项目是 QObject ,您可以显式查找子项,就像在C QObject 层次结构中一样 . 代码将是这样的:

    #include <QtGui/QGuiApplication>
    #include <QQmlEngine>
    #include <QQmlComponent>
    #include <QQmlProperty>
    #include <QDebug>
    
    #include "qtquick2applicationviewer.h"
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        QtQuick2ApplicationViewer viewer;
        viewer.setMainQmlFile(QStringLiteral("qml/untitled/main.qml"));
        viewer.showExpanded();
    
        QQmlEngine engine;
        QQmlComponent component(&engine, "qml/untitled/main.qml");
        QObject *object = component.create();
    
        // This line is added
    
        QObject *childObject = object->findChild<QObject*>("SomeNumberText");
    
        // The following line is modified respectively
    
        qDebug() << "Property value:" << QQmlProperty::read(childObject, "someNumber").toInt();
    
        return app.exec();
    }
    

    但是,这意味着您需要将 objectName: "SomeNumberText" 行添加到qml文件中的Text子项 .

  • 11

    在这里,您可以找到一个递归方法,通过 objectName 查找QML项目并从 QQmlApplicationEngine::rootObjects() 开始:

    ////
    static QQuickItem* FindItemByName(QList<QObject*> nodes, const QString& name)
    {
        for(int i = 0; i < nodes.size(); i++){
            // search for node
            if (nodes.at(i) && nodes.at(i)->objectName() == name){
                return dynamic_cast<QQuickItem*>(nodes.at(i));
            }
            // search in children
            else if (nodes.at(i) && nodes.at(i)->children().size() > 0){
                QQuickItem* item = FindItemByName(nodes.at(i)->children(), name);
                if (item)
                    return item;
            }
        }
        // not found
        return NULL;
    }
    
    ///
    static QQuickItem* FindItemByName(QQmlApplicationEngine* engine, const QString& name)
    {
        return FindItemByName(engine->rootObjects(), name);
    }
    
  • 0

    这有什么用例?将[text,someNumber]结构或对象视为模型可能更好 . 然后你只需要找到模型对象 . 或者您可以在C端创建模型对象并在QML上下文中设置它 . 您可以在QML中访问模型及其嵌套属性:

    Text {
            text: model.text
            property int someNumber: model.someNumber
        }
    

相关问题