集成 QML 和 C++

QML 应用程序通常需要在 C++ 中处理更高级和性能密集型的任务。最常见和最快的方法是将 C++ 类公开给 QML 运行时,前提是 C++ 实现是从 QObject 派生的。假设你已经安装了 Qt 5.7 或更高版本,下面将逐步引导你在 QML 应用程序中使用 C++ 类 BackEnd:

  1. 在 Qt Creator 中使用“Qt Quick Application”模板创建一个新项目

    注意:New Project WizardDefine Project Details 部分取消勾选 With ui.qml 选项。

  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 
     #include 
     #include 
    
     class BackEnd : public QObject
     {
         Q_OBJECT
         Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged)
         QML_ELEMENT
    
     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. The QML_ELEMENT macro makes the BackEnd class available in QML.

  3. Add the following lines to your project file:
     CONFIG += qmltypes
     QML_IMPORT_NAME = io.qt.examples.backend
     QML_IMPORT_MAJOR_VERSION = 1
    

    The BackEnd class is automatically registered as a type, which is accessible from QML by importing the URL, “io.qt.examples.backend 1.0”.

  4. Replace the contents of backend.cpp 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.

  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
    
             onEditingFinished: 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.

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.