Подтвердить что ты не робот

Как я могу получить доступ к своим свойствам объекта Window из С++ при использовании QQmlApplicationEngine?

Я пытался изучить QtQuick для создания графического интерфейса, но мне было трудно понять, как взаимодействовать с объектами 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"
    }
}

Вот базовый файл С++, который пришел с ним (автоматически сгенерированный 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();
}

Моя проблема в том, что я понятия не имею, как получить доступ к моему QML-объекту Window, и в результате я не могу изменить какие-либо его свойства или свойства своих детей! Эта часть документации QtQuick показывает два метода доступа к объектам QML из кода С++, но ни один из них, похоже, не применяется к этой схеме загрузки "QQmlApplicationEngine". Я также видел, что люди используют такие вещи, как "QApplicationViewer" и "QDeclaritiveView", но я не могу найти их в официальной документации вообще.

Меня сильно расстраивает QtQuick; "простота" QML кажется утраченной в море противоречивой документации и запутанном интерфейсе между С++ и QML. Есть ли в любом случае для меня доступ к моим объектам QML при использовании метода QQmlApplicationEngine? Я попытался использовать "QuickView", но, похоже, он не работает с объектами Window QML.? Является ли QQmlApplicationEngine полезным только для приложений только для QML в одном файле? До сих пор каждый фрагмент документации и учебника, который я прочитал, показал что-то другое.

Любая помощь или разъяснение будут оценены. В идеале я хотел бы узнать, как получить доступ и изменить объекты QML (например, "mainWindow", "testRect" и другие объекты в других файлах) через мой код на С++.

4b9b3361

Ответ 1

Превращение моего комментария в правильный ответ: обычно это делается двумя способами:

  • Получите корневой объект вашей сцены QML через представление, если вы используете непосредственно QQuickView или просто QQmlApplicationEngine.

  • Этот следующий шаг может быть опущен для корневых объектов, но для "объектов qml" в общем случае вам нужно будет objectName property, а затем вы можете найти любых детей со следующим методом:

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

сторона С++

#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 и значение)

и

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

Хорошо, теперь мы более или менее выполняем действия на стороне С++.

Сторона QML

Вам также нужно будет иметь свойство objectName для ваших объектов qml, если вы хотите получить доступ к более чем одному корневому элементу следующим образом:

import QtQuick 2.2
import QtQuick.Window 2.1

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

Это может быть сделано аналогичным образом для любого объекта QML. Ключ здесь "objectName". Вы можете опустить это для корневого объекта, так как сторона С++ получает объект root напрямую, но поскольку вы ссылаетесь на объекты QML в своем вопросе, я предполагаю, что вы хотели бы его решить в целом. Как только вы захотите сделать то же самое для любого объекта QML, то есть включая детей, вам нужно будет использовать свойство objectName.