Integrating QML and C++
QML applications often need to handle more advanced and performance-intensive tasks in C++. The most common and quickest way to do this is to expose the C++ class to the QML runtime, provided the C++ implementation is derived from QObject. Assuming that you have Qt 5.7 or later installed, the following step-by-step instructions guide you through the process of using the C++ class, BackEnd, in a QML application:
- Create a new project using the "Qt Quick Application" template in Qt Creator
Note: Uncheck the With ui.qml file option in the Define Project Details section of New Project Wizard.
- Add a new C++ class called
BackEnd
to the project and replace its header file contents with:#ifndef BACKEND_H #define BACKEND_H #include <QObject> #include <QString> class BackEnd : public QObject { Q_OBJECT Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged) public: explicit BackEnd(QObject *parent = nullptr); QString userName(); void setUserName(const QString &userName); signals: void userNameChanged(); private: QString m_userName; }; #endif // BACKEND_H
The
Q_PROPERTY
macro declares a property that could be accessed from QML. - Replace its C++ file contents with:
#include "backend.h" BackEnd::BackEnd(QObject *parent) : QObject(parent) { } QString BackEnd::userName() { return m_userName; } void BackEnd::setUserName(const QString &userName) { if (userName == m_userName) return; m_userName = userName; emit userNameChanged(); }
The
setUserName
function emits theuserNameChanged
signal every timem_userName
value changes. The signal can be handled from QML using theonUserNameChanged
handler. - Include
"backend.h"
inmain.cpp
and register the class as a QML type under a import URL as shown below:#include <QGuiApplication> #include <QQmlApplicationEngine> #include "backend.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); qmlRegisterType<BackEnd>("io.qt.examples.backend", 1, 0, "BackEnd"); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); }
The BackEnd class is registered as a type, which is accessible from QML by importing the URL, "
io.qt.examples.backend 1.0
". - Replace the contents of
main.qml
with the following code:import QtQuick 2.6 import QtQuick.Controls 2.0 import io.qt.examples.backend 1.0 ApplicationWindow { id: root width: 300 height: 480 visible: true BackEnd { id: backend } TextField { text: backend.userName placeholderText: qsTr("User name") anchors.centerIn: parent onTextChanged: backend.userName = text } }
The
BackEnd
instance lets you access theuserName
property, which is updated when the TextField'stext
property changes.
Now the application can be run.
cppintegration-ex.png
Application running on Ubuntu
Qt offers several methods to integrate C++ with QML, and the method discussed in this tutorial is just one of them. For more details about these methods, refer to Overview - QML and C++ Integration.