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

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

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

相关推荐
用户805533698031 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner1 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
BadBadBad__AK2 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
卷无止境2 天前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
卷无止境2 天前
OpenMPI、MPICH 与 OpenMP:关系、核心概念与架构全解
c++·后端
郝学胜_神的一滴3 天前
CMake 30:循环语法全解|foreach_while双循环精讲、迭代技巧与实战避坑指南
c++·cmake
卷无止境5 天前
C++ 的Eigen 库全解析
c++
卷无止境5 天前
现代 C++特性大盘点:一门脱胎换骨的老语言
c++·后端
郝学胜_神的一滴5 天前
CMake 27:缓存变量的特性、语法、类型与实操全解
c++·cmake
Quz6 天前
QML Hello World 入门示例
qt