Qt 5.9 | Qt QML | Integrating QML and C++

Qt 5.9.9 Reference Documentation

# 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:

1. 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.

2. 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.

3. 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 the `userNameChanged` signal every time `m_userName` value changes. The signal can be handled from QML using the `onUserNameChanged` handler.

4. Include `"backend.h"` in `main.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`".

5. 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 the `userName` property, which is updated when the TextField's `text` 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.