QML与C++交互的简单例子

开发环境:ubuntu-16.04 + Qt5.14

参考链接:

1、QML如何与C++交互 - 青衣守旧人 - 博客园
QML与C++交互:在qml中使用QSqlQueryModel显示数据库数据_jdh99的专栏-CSDN博客
 

创建一个名为 qml_call_cpp 的Qt Quick Application-Empty 工程:

uploading.4e448015.gif

正在上传…重新上传取消

uploading.4e448015.gif

正在上传…重新上传取消

uploading.4e448015.gif

正在上传…重新上传取消

然后右键点击下图中的 Sources ,在弹出的选项中选择 Add New…,选择创建一个新的C++ Class,

新的类名设置为 MxlQmlExposeCppAttr ,选择基类为 QObject,因为如果函数想要在QML中被调用,那么此类必须继承于QObject,另外需要在函数的开头添加Q_INVOKABLE关键字。

在网址Exposing Attributes of C++ Types to QML | Qt QML 5.15.7 中说到 QML engine 是继承自类QObject的:

QML can easily be extended with functionality defined in C++ code. Due to the tight integration of the QML engine with the Qt meta-object system, any functionality that is appropriately exposed by a QObject-derived class is accessible from QML code. This enables C++ data and functions to be accessible directly from QML, often with little or no modification.

且 QML code 可以获取 QObject 的派生类的属性、方法和信号:

The QML engine has the ability to introspect QObject instances through the meta-object system. This means any QML code can access the following members of an instance of a QObject-derived class:

    Properties         //由宏 Q_PROPERTY 定义的属性,可以与类的成员变量关联起来

    Methods (providing they are public slots or flagged with Q_INVOKABLE) #也就是类成员函数,函数前面需要加上宏 Q_INVOKABLE

    Signals    //类里的信号

以上步骤完成后工程目录如下:

下面的内容复制到头文件  mxlqmlexposecppattr.h 中:

#ifndef MXLQMLEXPOSECPPATTR_H

#define MXLQMLEXPOSECPPATTR_H

#include <QObject>

class MxlQmlExposeCppAttr : public QObject

{

    Q_OBJECT

public:

    explicit MxlQmlExposeCppAttr(QObject *parent = nullptr);

Q_INVOKABLE QString showInfo();           //函数想要在QML中被调用,那么此类必须继承于QObject,另外需要在函数的开头添加Q_INVOKABLE关键字。

                                                              // providing they are public slots or flagged with Q_INVOKABLE,参见Exposing Attributes of C++ Types to QML | Qt QML 5.15.7

signals:

};

#endif // MXLQMLEXPOSECPPATTR_H

下面的内容复制到文件  mxlqmlexposecppattr.cpp 中:

#include "mxlqmlexposecppattr.h"

#include <QDebug>

MxlQmlExposeCppAttr::MxlQmlExposeCppAttr(QObject *parent) : QObject(parent)

{

qDebug("i am here.");

}

QString MxlQmlExposeCppAttr::showInfo()

{

    qDebug("i am here.");

    return tr("cpp and qml interaction!");

}

https://doc.qt.io/qt-5/qtqml-cppintegration-exposecppattributes.html

顾名思义,使用函数 qmlRegisterType() 将C++ 类注册到 QML 系统中,相当于注册了一种 QML type。

QML type 的种类参见网址:All QML Types | Qt 5.15

例如常见的 Window QML Type 可以参见网址:https://doc.qt.io/qt-5/qml-qtquick-window-window.html

例如常见的 InputPanel QML Type 可以参见网址: https://doc.qt.io/qt-5/qml-qtquick-virtualkeyboard-inputpanel.html

QML type 函数qmlRegisterType() 在qt 源码文件 qt-everywhere-src-5.14.2\qtdeclarative\src\qml\qml\qqml.h 中定义:

template<typename T>

int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);这个模板函数,它是在QML系统中注册名为qmlName的C++类型文件

入口参数意义:

uri:这个参数类似于C++中的命名空间,在qml 文件中使用 import 导入

versionMajor:主版本号。

                  versionMinor:次版本号。

                  qmlName:C++类在QML中的类名,与 InputPanel、Button 等QML Type 的使用方法相同,需要注意的是这个类名首字母必须要大写,不然会报错。

例如    qmlRegisterType<MxlQmlExposeCppAttr>("com.mxl.QmlType", 1, 0, "MxlQmlType");

那么就可以在qml 文件中使用 import com.mxl.QmlType 1.0 导入类型,然后在qml 文件中使用MxlQmlType:

import com.mxl.QmlType 1.0

Window {

    id: window

    visible: true

    width: 640

    height: 480

title: qsTr("Hello World")

MxlQmlType{

         id: mxl_qml_type

//也可以像原生QML对象一样操作,增加属性之类的

property int counts: 0

}

}

文件 main.cpp 的内容如下:

#include <QGuiApplication>

#include <QQmlApplicationEngine>

#include "mxlqmlexposecppattr.h"

#include <QQmlContext>

//#include <QtQml>

int main(int argc, char *argv[])

{

    qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));

    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    qmlRegisterType<MxlQmlExposeCppAttr>("com.mxl.QmlType", 1, 0, "MxlQmlType");

    /*

    QML type 函数qmlRegisterType() 在qt 源码文件 qt-everywhere-src-5.14.2\qtdeclarative\src\qml\qml\qqml.h 中定义:

    template<typename T>

    int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);这个模板函数,它是在QML系统中注册名为qmlName的C++类型文件

    入口参数意义:

    uri:这个参数类似于C++中的命名空间,在qml 文件中使用 import 导入

    versionMajor:主版本号。

        versionMinor:次版本号。

        qmlName:C++类在QML中的类名,与 InputPanel、Button 等QML Type 的使用方法相同,需要注意的是这个类名首字母必须要大写,不然会报错。

    例如 qmlRegisterType<MxlQmlExposeCppAttr>("com.mxl.QmlType", 1, 0, "MxlQmlType");

    那么就可以在qml 文件中使用 import com.mxl.QmlType 1.0 导入类型,然后在qml 文件中使用MxlQmlType:

    import com.mxl.QmlType 1.0

    Window {

        id: window

        visible: true

        width: 640

        height: 480

    title: qsTr("Hello World")

    MxlQmlType{

        id: mxl_qml_type

    //也可以像原生QML对象一样操作,增加属性之类的

    property int counts: 0

    }

    }

    */

    MxlQmlExposeCppAttr mxlQmlType;

    QQmlApplicationEngine engine;

    const QUrl url(QStringLiteral("qrc:/main.qml"));

    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,

                     &app, [url](QObject *obj, const QUrl &objUrl) {

        if (!obj && url == objUrl)

            QCoreApplication::exit(-1);

    }, Qt::QueuedConnection);

    /* 使用 qml engine 的setContextProperty 设置类对象 MxlQmlExposeCppAttr  mxlQmlType 在qml 文件中的名字为 mxlQmlTypeTest */

    engine.rootContext()->setContextProperty("mxlQmlTypeTest", &mxlQmlType);

    engine.load(url);

    return app.exec();

}

文件 main.qml 的内容如下:

import QtQuick 2.9

import QtQuick.Window 2.2

import QtQuick.VirtualKeyboard 2.2

import com.mxl.QmlType 1.0

import QtQuick.Controls 1.4

Window {

    id: window

    visible: true

    width: 640

    height: 480

    title: qsTr("Hello World")

    Row{

        spacing: 10

        x:200

        y:200

        Button{

            width: 100

            height: 30

            text: qsTr("点击")

            onClicked: {

                 textName.text =  mxlQmlTypeTest.showInfo();

            }

        }

        TextField{

            width: 300

            height: 30

            textColor: "#ff00ff"

            font.weight: Font.Bold

            id:textName

        }

    }

}

文件 main.qml 也可以通过设计器来调用整:

执行效果如下:

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值