【qml-5.1】qml与c++交互(QML_ELEMENT/QML_SINGLETON)

背景:

之前学习qml特意总结了几种qml与c++交互的模式,先提炼一下我认为重要的。

【qml-4】qml与c++交互(类型多例)

【qml-5】qml与c++交互(类型单例)

【qml-5.1】qml与c++交互(QML_ELEMENT/QML_SINGLETON)(本文)

由于项目中多次用到,真心觉得,"类型单例"模式是最适合全局使用的,"类型多例"目前也就分页组件用过。我认为这两种方式目前为止最好用。所谓好用是指:代码量不大,qml中可以自动补全提示。

但是,在不断学习过程中,对一个词比较敏感和青睐,那就是"更现代的"。所以就想再次尝试总结使用宏的方式实现交互。亦即:QML_ELEMENT/QML_SINGLETON。

下面就是实验过程,直接说主要步骤。

环境:

能选就选最新的,我这目前不是最新,是qt6.9.3。

新建了一个compat类型的工程,亦即使用qrc资源模式。

个人推荐这种模式,ui可以用qds做好,选择生成qrc文件,或者不用也行,我的习惯永远是最小侵入或最小污染原则。所以qds好些自动功能一律不用,只要它生成的qml文件,和那个images图片文件目录。然后用creator新建工程,把那个qml目录content和qrc文件复制过去。

类定义:

直接在qt creator中选择添加c++类,过程中会让你选择,我选择了继承自QObject亦即添加宏。

于是生成了:

cpp 复制代码
#ifndef CPP_H
#define CPP_H

#include <QObject>
#include <QQmlEngine>
#include <QDebug>//I added

class Cpp : public QObject
{
    Q_OBJECT
    QML_ELEMENT
public:
    explicit Cpp(QObject *parent = nullptr);
    Q_INVOKABLE void f() { qDebug() << __FUNCTION__; }//I added

signals:
};

#endif // CPP_H

我加了个函数,输出函数名,不用多说了。想要qml能调用,记着加Q_INVOKABLE。

Cmake:

CMakeLists中添加一段:

cpp 复制代码
qt_policy(SET QTP0001 NEW)
qt6_add_qml_module(${PROJECT_NAME}
    URI CppType
    VERSION 1.0
    SOURCES
        cpp.cpp cpp.h
)

URI对应的是qml中import那个名字,亦即模块。比如按照我的习惯,所有单例注册到CppSingleton,多例注册到CppType,就这个意思。

版本号不用说了。然后就没然后了。

Qml:

各位看这个德行,我就贼不喜欢这样!运行一下看看:

看,成功了是吧?

这是多例模式的体现。

类型单例:

如果要单例模式,就要定义类的时候加个宏:

cpp 复制代码
#ifndef CPP_H
#define CPP_H

#include <QObject>
#include <QQmlEngine>
#include <QDebug>

class Cpp : public QObject
{
    Q_OBJECT
    QML_ELEMENT
    QML_SINGLETON//就是这里!
public:
    explicit Cpp(QObject *parent = nullptr);
    Q_INVOKABLE void f() { qDebug() << __FUNCTION__; }

signals:
};

#endif // CPP_H

然后就啥也不用动,还是上面那样。只不过qml中需要改一下调用方法:

javascript 复制代码
import QtQuick 2.15
import QtQuick.Window 2.15
import CppType 1.0

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    // Cpp { id: cpp }

    // Component.onCompleted: cpp.f()

    Component.onCompleted: Cpp.f()//注意这里!

}

然后就没然后了。简单吧?当然按照我的习惯,cmake那里添加模块时,我会让URI是CppSingleton,然后qml的import那里也要改。只不过这里我沿用了上文的,就为说明问题而已,就不较真了。

都不用工厂函数之类的,具体参考之前的博客"类型单例"模式。

总结:

各位说这事简单不?按理说确实挺现代的,非常简练。

但是我不爽啊,qml里那个报错,试过很多次了,只能重启creator,还不保证一定能行。等于非要自己记着没错才可以。反正目前我没试出好办法,AI也胡说八道,没个正经法。最后逼急了它说等着qt升级完善。

总之别忘了咱的原则:最小污染,最小侵入,简洁简练稳定。

各位老少爷们,有好办法说一声。

相关推荐
imatt11 分钟前
Qt Creator 在Windows下编译信息乱码
windows·qt
JaneConan16 分钟前
鸿蒙 ArkUI 深水区:@Watch 和 @Observed,状态变了「自动跑」+ 嵌套对象「深层重绘」
开发语言·后端·ui·harmonyos
赤水无泪20 分钟前
qt中图标、名称的设置方式
开发语言·qt
王莎莎-MinerU26 分钟前
MCP 解决的是工具接入,科研 Agent 还缺的是科学证据接口标准化
开发语言·网络·人工智能·深度学习·pdf·c#·php
橘子海全栈攻城狮1 小时前
【最新源码】基于SpringBoot + Vue的超市管理系统的设计与实现D002
java·开发语言·vue.js·spring boot·后端·spring
在水一缸1 小时前
深入浅出 Catch2:现代 C++ 测试框架的优雅实践
开发语言·c++·单元测试·log4j·测试框架·catch2
-银雾鸢尾-1 小时前
C#中Object类内的方法
开发语言·c#
2401_841495641 小时前
【数据结构】B*树
数据结构·c++·b树·算法·删除·插入·三分分裂
浮江雾1 小时前
Flutter第十节-----Flutter布局与组件全解析
android·开发语言·前端·学习·flutter·入门
爱喝水的鱼丶1 小时前
SAP-ABAP:ALV跨版本兼容指南——适配ECC与S4 HANA系统的ALV开发注意事项
开发语言·性能优化·sap·abap·经验交流