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++.
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:
#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
Bon, nous avons maintenant plus ou moins terminé du côté C++.
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 .