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.