Using objectName to find QML elements from Qt
Article Metadata
Tested with
Compatibility
Maemo
Article
Contents |
Overview
This code shows how to find QML element from Qt code by using the objectName property. This is done by first retrieving the root object of the QML document and then recursively iterating through the object hierarchy until the desired object is found. By this way the signals, properties and functions of a QML element can be accessed from Qt code more easily and they don't need to exist in the root element of the Qt Quick application. This leads to better modularity and reusability of the QML code.
This technique was used in the Nokia Developer example Dj Turntable to simplify the QML code.
Preconditions
- Qt 4.7 or higher is installed on your platform.
Sources
findqml.pro
QT += core gui declarative
TARGET = FindQML
TEMPLATE = app
SOURCES += main.cpp
HEADERS += myclass.h
OTHER_FILES += FindQML.qml
RESOURCES += resources.qrc
unix:!symbian {
maemo5 {
target.path = /opt/usr/bin
} else {
target.path = /usr/local/bin
}
INSTALLS += target
}
resources.qrc
<RCC>
<qresource prefix="/">
<file>FindQML.qml</file>
</qresource>
</RCC>
myclass.h
MyClass is used to interact with the QML element given in constructor. The handleClick slot receives the button press signal from QML code and sets the QML elements property label to the string "Qt was here".
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
#include <QVariant>
class MyClass : public QObject
{
Q_OBJECT
public:
MyClass(QObject *QMLObject) : m_QMLObject(QMLObject) {}
public slots:
void handleClick() {
m_QMLObject->setProperty("label", "Qt was here");
}
protected:
QObject *m_QMLObject;
};
#endif // MYCLASS_H
main.cpp
In the main function the instance of button element is searched from the QML namespace by using the rootObject of the QDeclarativeView and the findChild member function. After finding out the desired QML element, we connect the signal clicked to the Qt slot handleClick.
#include <QApplication>
#include <QDeclarativeView>
#include <QGraphicsObject>
#include <QMessageBox>
#include "myclass.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QDeclarativeView view;
view.setResizeMode(QDeclarativeView::SizeRootObjectToView);
view.setSource(QUrl("qrc:/FindQML.qml"));
QObject *buttonQML = view.rootObject()->findChild<QObject*>("button"); //button is the object name, which needs to be define in qml for the component.e.g. objectName: "button"
if(buttonQML == NULL) {
QMessageBox::warning(NULL, "Warning", "Failed to resolve button QML element");
return 1;
}
MyClass myClass(buttonQML);
QObject::connect(buttonQML, SIGNAL(clicked()), &myClass, SLOT(handleClick()));
#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) || defined(Q_WS_SIMULATOR)
view.showMaximized();
#else
view.setGeometry(100, 100, 640, 360);
view.show();
#endif
return app.exec();
}
FindQML.qml
In the QML code we must define instance of the QML element with distinctive objectName property in order to find it from Qt code.
import Qt 4.7
Rectangle {
width: 640; height: 480
color: "black"
Rectangle {
id: button
objectName: "button"
signal clicked()
property alias label: buttonLabel.text
anchors.centerIn: parent
width: 200; height: 60; color: "gray"; radius: 10
Behavior on scale { NumberAnimation { duration: 50 } }
Text {
id: buttonLabel
anchors.centerIn: parent
font { bold: true; pixelSize: 20 }
text: "Press me"
color: "white"
}
MouseArea {
anchors.fill: parent
onPressed: button.scale = 0.9
onReleased: button.scale = 1.0
onClicked: button.clicked()
}
}
}
Postconditions
This code snippet demonstrated a way to retrieve specific QML elements in Qt code to interact with them directly.


(no comments yet)