Подобно тому, как в коде QML можно обращаться к коду C++, также и в коде C++ можно обращаться к функциональности QML, в частности, к элементам, определенным в QML.
Например, у нас есть следующий интерфейс в main.qml:
import QtQuick Window { width: 250 height: 200 visible: true title: "METANIT.COM" Text { anchors.centerIn: parent objectName: "header" // устанавливаем имя компонента font.pixelSize: 22 text: "Hello" } }
Здесь определен элемент Text, который выводит некоторый текст. И что важно, у этого элемента определено свойство objectName, которое хранит имя элемента в виде строки. Через это имя мы сможем найти данный элемент в коде C++.
В главном файле программы - в main.cpp определим следующий код:
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <iostream> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; const QUrl url("qrc:/path/main.qml"); // путь к main.qml engine.load(url); // получаем корневой объект - окно приложения QObject* window = engine.rootObjects().first(); // получаем в окне элемент с именем "header" QObject* object = window->findChild<QObject*>("header"); if(object) { // логируем значение свойства text на консоль std::cout << object->property("text").toString().toStdString() << std::endl; // изменяем значение свойства "text" object->setProperty("text", QVariant("Clicked!")); } else std::cout << "Not Found" << std::endl; return app.exec(); }
У объекта QQmlApplicationEngine
есть метод rootObjects(), который возвращает список корневых компонентов в виде объекта QList<QObject*>
.
Это те объекты, который загружаются из файла qml с помощью метода load(). В нашем случае корневой объект один - объект Window, который представляет окно. И чтобы
взять этот первый и единственный компонент в списке, применяется метод first():
QObject* window = engine.rootObjects().first();
Получив окно, мы можем получить любой объект внутри этого окна, в том числе наш объект Text. Для этого у объекта QObject применяется метод findChild(), в который передается имя компонента и который возвращает найденный компонент опять же в виде указателя QObject.
QObject* object = window->findChild<QObject*>("header");
Поскольку метод findChild()
определен для типа QObject, то мы можем применять его для любого компонента интерфейса, чтобы найти вложенные в него элементы.
Может сложиться ситуация, что компонент с указанным именем будет не найден. В этом случае мы можем проверить результат на null.
Если компонент с указанным именем найден, то мы можем обращаться к его свойствам - получать и изменять их. Так, с помощью метода property() можно получить значение определенного свойства. В данном случае получаем свойство "text", то есть текст компонента. Стоит учитывать, что возвращаемый результат представляет тип QVariant - некоторый универсальный тип, который выступает объединением для большинства стандартных типов Qt. Соответственно, чтобы получить непосредственно значение свойства в нужном виде (в нашем случае в виде строки), необходимо выполнить ряд преобразований:
object->property("text").toString().toStdString()
С помощью метода setProperty() можно присвоить свойству определенное значение. Первый параметр метода - имя свойства, а второй параметр - новое значение, обернутое в тип QVariant
object->setProperty("text", QVariant("Clicked!"));
В итоге при запуске приложения элемент Text будет содержать текст, установленный в коде C++: