webentwicklung-frage-antwort-db.com.de

Wie kann ich mit QQmlApplicationEngine von C ++ aus auf meine Window-Objekteigenschaften zugreifen?

Ich habe versucht, QtQuick für die GUI-Erstellung zu erlernen, aber es fällt mir schwer, die Interaktion mit QML-Objekten aus dem C++ - Teil meines Testprogramms zu verstehen.

Hier ist meine einfache QML-Datei:

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"
    }
}

Hier ist die grundlegende C++ - Datei, die mitgeliefert wurde (von QtCreator automatisch generiert):

#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();
}

Mein Problem ist, dass ich keine Ahnung habe , wie ich auf mein 'Window'-QML-Objekt zugreifen kann, und daher keine Änderung vornehmen kann seiner Eigenschaften oder die Eigenschaften seiner Kinder! Dieser Teil der QtQuick-Dokumentation zeigt zwei Methoden für den Zugriff auf QML-Objekte aus C++ - Code heraus, aber keine davon scheint auf dieses Ladeschema von "QQmlApplicationEngine" zuzutreffen. , aber ich kann die in der offiziellen Dokumentation anscheinend überhaupt nicht finden.

Ich bin sehr frustriert über QtQuick. Die 'Einfachheit' von QML scheint in einem Meer widersprüchlicher Dokumentation und verschlungener Schnittstellen zwischen C++ und QML verloren zu gehen. Kann ich mit der QQmlApplicationEngine-Methode trotzdem auf meine QML-Objekte zugreifen? Ich habe versucht, 'QuickView' zu verwenden, aber es scheint nicht gut mit Windows QML-Objekten zu funktionieren. Ist QQmlApplicationEngine nur für QML-reine Anwendungen in einer einzelnen Datei nützlich? Bisher hat jede Dokumentation und jedes Tutorial, die ich gelesen habe, etwas anderes gezeigt.

Jede Hilfe oder Klärung wäre dankbar. Idealerweise würde ich gerne wissen, wie man auf QML-Objekte (wie 'mainWindow', 'testRect' und andere Objekte in anderen Dateien) über meinen C++ - Code zugreift und diese ändert.

39
MrKatSwordfish

Aus meinem Kommentar eine richtige Antwort machen: Dies geschieht normalerweise auf zwei Arten:

  • Rufen Sie das Stammobjekt Ihrer QML-Szene über eine Ansicht ab, wenn Sie QQuickView oder nur QQmlApplicationEngine direkt verwenden.

  • Dieser nächste Schritt kann für Root-Objekte weggelassen werden. Für "qml-Objekte" muss jedoch im Allgemeinen objectName-Eigenschaft gesetzt sein. Anschließend können Sie alle untergeordneten Objekte mit der folgenden Methode suchen:

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

C++ Seite

#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();
}

Lesen Sie die Dokumentation zum Eigenschaftensatz und lesen Sie die offizielle Dokumentation:

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

und

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

Gut, wir sind jetzt mehr oder weniger auf der C++ Seite fertig.

QML-Seite

Sie müssen auch die Eigenschaft objectName Ihrer qml-Objekte festlegen, wenn Sie wie folgt auf mehr als nur das Stammelement zugreifen möchten:

import QtQuick 2.2
import QtQuick.Window 2.1

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

Dies kann auf ähnliche Weise für jedes QML-Objekt erfolgen. Der Schlüssel ist hier "objectName". Sie könnten das für das Root-Objekt weglassen, da die C++ - Seite das Root-Objekt direkt abruft, aber da Sie in Ihrer Frage auf QML-Objekte verweisen, gehe ich davon aus, dass Sie es allgemein lösen möchten. Wenn Sie dasselbe für ein QML-Objekt, d. H. Einschließlich untergeordneter Objekte, tun möchten, müssen Sie die objectName-Eigenschaft verwenden.

47
lpapp