【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升级完善。

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

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

相关推荐
凭君语未可4 小时前
从静态代理走向动态代理:理解 JDK 动态代理的本质
java·开发语言
小碗羊肉4 小时前
【从零开始学Java | 第三十八篇】序列化流(Object Stream)
java·开发语言
百锦再4 小时前
使用JavaScript获取和解析页面内容的完整指南
开发语言·前端·javascript·python·flask·fastapi
iCxhust4 小时前
C#如何实现textbox文本多行输出 且自动换行输出
开发语言·c#
想带你从多云到转晴4 小时前
02、JAVAEE--多线程(二)
java·开发语言·javaee
实在智能RPA4 小时前
Agent 如何处理流程中的异常情况?——2026企业级智能体稳定性架构深度拆解
开发语言·人工智能·ai·架构·php
一只大袋鼠4 小时前
Java JDBC 封装:从原生写法到工具类封装 + 增删改查
java·开发语言·数据库·mysql
txxzjmzlh4 小时前
Java 线程的几种状态
java·开发语言
lly2024064 小时前
JavaScript 对象
开发语言