如何在使用QQmlApplicationEngine时从C ++访问我的Window对象属性?

时间:2014-04-20 02:38:01

标签: c++ qt user-interface qml qtquick2

我一直在尝试学习QtQuick用于GUI创建,但我一直很难理解如何与我的测试程序的C ++部分中的QML对象进行交互。

这是我简单的QML文件:

import QtQuick 2.2
import QtQuick.Window 2.1

Window {
    id: mainWindow
    visible: true
    width: 800
    height: 800
    color: "#FFFF0000"

    MouseArea {
        anchors.fill: parent
        onClicked: Qt.quit()
    }

    Rectangle {
        id: testRect
        width: 100
        height: 100
        anchors.centerIn: parent
        color: "#FF0000FF"
    }
}

这是随附的基本C ++文件(由QtCreator自动生成):

#include <QGuiApplication>
#include <QQmlApplicationEngine>

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

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    return app.exec();
}

我的问题是我不知道如何访问我的&#39; Window&#39; QML对象,因此,我无法改变其任何属性或其子项的属性! QtQuick文档的这一部分显示了从C ++代码中访问QML对象的两种方法,但它们似乎都不适用于这个&#39; QQmlApplicationEngine&#39;加载计划..我也看到人们使用像QApplicationViewer&#39;和&#39; QDeclaritiveView&#39;,但我似乎无法在官方文档中找到它们。

我对QtQuick感到非常沮丧;简单&#39; QML似乎在大量冲突的文档和C ++与QML之间错综复杂的界面中丢失。无论如何我在使用QQmlApplicationEngine方法时访问我的QML对象?我尝试使用&#39; QuickView&#39;,但它似乎不能很好地与Window QML对象配合使用..? QQmlApplicationEngine仅对单个文件中的QML应用程序有用吗?到目前为止,我阅读的每一篇文档和教程都显示了不同的内容......

任何帮助或澄清将不胜感激。 理想情况下,我想知道如何通过我的C ++代码访问和修改QML对象(例如&#39; mainWindow&#39;,&#39; testRect&#39;以及其他文件中的其他对象)

1 个答案:

答案 0 :(得分:45)

将我的评论转化为正确的答案:这通常通过两种方法完成:

  • 如果您使用QQuickView或直接使用QQmlApplicationEngine,请通过视图获取QML场景的根对象。

  • 对于根对象,可以省略下一步,但对于“qml对象”,通常需要设置objectName property,然后您可以使用以下方法找到任何子对象:< / p>

  

QList QObject::findChildren(const QString & name = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const

C ++方

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QDebug>

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

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    // Step 1: get access to the root object
    QObject *rootObject = engine.rootObjects().first();
    QObject *qmlObject = rootObject->findChild<QObject*>("mainWindow");

    // Step 2a: set or get the desired property value for the root object
    rootObject->setProperty("visible", true);
    qDebug() << rootObject->property("visible");

    // Step 2b: set or get the desired property value for any qml object
    qmlObject->setProperty("visible", true);
    qDebug() << qmlObject->property("visible");

    return app.exec();
}

请参阅属性集的文档并获取官方文档:

  

bool QObject::setProperty(const char * name, const QVariant & value)

  

QVariant QObject::property(const char * name) const

很好,我们现在或多或少都是在C ++方面完成的。

QML Side

如果您希望访问的不仅仅是根项目,还需要设置qml对象的objectName属性,如下所示:

import QtQuick 2.2
import QtQuick.Window 2.1

Window {
    id: mainWindow
    objectName: "mainWindow"
    ...
}

对于任何QML对象,都可以这样做。关键是这里的“objectName”。您可以省略对于根对象,因为C ++端直接获取根对象,但由于您在问题中引用了QML对象,我认为您通常希望解决它。如果您希望对任何QML对象(包括儿童)执行相同操作,则需要使用objectName property