web-dev-qa-db-fra.com

Comment puis-je accéder à mes propriétés d'objet Window à partir de C ++ tout en utilisant QQmlApplicationEngine?

J'ai essayé d'apprendre QtQuick pour la création d'interface graphique, mais j'ai eu du mal à comprendre comment interagir avec les objets QML à partir de la partie C++ de mon programme de test.

Voici mon simple fichier 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"
    }
}

Voici le fichier C++ de base qui l'accompagne (généré automatiquement par 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();
}

Mon problème est que je n'ai aucune idée comment accéder à mon objet QML 'Window', et par conséquent, je ne peux pas modifier de ses propriétés ou des propriétés de ses enfants! Cette partie de la documentation QtQuick montre deux méthodes d'accès aux objets QML à partir du code C++, mais aucune d'entre elles ne semble s'appliquer à ce schéma de chargement 'QQmlApplicationEngine'. J'ai également vu des gens utiliser des choses comme 'QApplicationViewer' et 'QDeclaritiveView' , mais je n'arrive pas du tout à trouver ceux-ci dans la documentation officielle ..

Je suis vraiment frustré par QtQuick; la "simplicité" de QML semble être perdue dans un océan de documentation conflictuelle et d'interface alambiquée entre C++ et QML. Est-il possible pour moi d'accéder à mes objets QML tout en utilisant la méthode QQmlApplicationEngine? J'ai essayé d'utiliser 'QuickView', mais cela ne semble pas bien fonctionner avec les objets Window QML ..? QQmlApplicationEngine est-il utile uniquement pour les applications QML uniquement dans un seul fichier? Jusqu'à présent, chaque document et tutoriel que j'ai lu a montré quelque chose de différent.

Toute aide ou clarification serait appréciée. Idéalement, j'aimerais savoir comment accéder et modifier des objets QML (comme 'mainWindow', 'testRect' et d'autres objets dans d'autres fichiers) via mon code C++.

39
MrKatSwordfish

Transformer mon commentaire en une bonne réponse: cela se fait généralement par deux méthodes:

  • Obtenez l'objet racine de votre scène QML via une vue si vous utilisez QQuickView ou simplement le QQmlApplicationEngine directement.

  • Cette étape suivante peut être omise pour les objets racine, mais pour les "objets qml" en général, vous devrez avoir la propriété objectName définie, puis vous pouvez trouver tous les enfants avec la méthode suivante:

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

Côté 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();
}

Consultez la documentation de l'ensemble de propriétés et accédez à la documentation officielle:

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

et

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

Bon, nous avons maintenant plus ou moins terminé du côté C++.

Côté QML

Vous devrez également définir la propriété objectName de vos objets qml si vous souhaitez accéder à plus que l'élément racine comme suit:

import QtQuick 2.2
import QtQuick.Window 2.1

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

Cela peut être fait de manière similaire pour n'importe quel objet QML. La clé est "objectName" ici. Vous pouvez omettre cela pour l'objet racine car le côté C++ obtient directement l'objet racine, mais puisque vous faites référence aux objets QML dans votre question, je suppose que vous souhaitez le résoudre en général. Une fois que vous souhaitez faire de même pour tout objet QML, c'est-à-dire y compris les enfants, vous devrez utiliser la propriété objectName .

47
lpapp