随笔 - 67,  文章 - 1,  评论 - 2,  阅读 - 56291
前言

在实际中的开发中,我们总是不希望自己的代码能被用户看到,但是使用QML文件封装的组件进行界面开发时,我们的QML源代码是会被编译器直接编译到.exe 或者 .elf 可执行文件中的,最过分的是,我们在QML中写的注释都会被原封不动的被编译到可执行文件中,供QML动态编译类去动态的执行编译或其他处理。
简直是叔叔能忍,嫂嫂不能忍,于是我就想着能把QML封装成动态库就好了,要想知道Qt Quick能不能搞,最直接的、最快速的方法就是看它的库结构或目录及源代码,毕竟别个开源了,不能浪费别个的一片苦心撒,于是我们发现在Qt Quick模块中,QML组件被普遍的编译成动态库的形式供开发者使用,为什么我们不这样弄呢?

注意
  • 你需要知道在Qt Quick中的动态库封装效果:
/*最终的封装组件库目录 > 
 * plugins.qmltypes   >> 让Qt的IDE能高亮我们自定义的组件
 * qmldir             >> 说明当前封装的组件信息,如[模块名],[插件名],[类型说明文件]
 * plugin.dll         >> release 版本的动态库
 * plugind.dll        >> debug 版本的动态库
 */
  • 你需要认真阅读与红色相似颜色的内容

  • 因为我在操作的过程中遇到一些问题,所以这篇随笔将详细的记录所有步骤。我也会将自己的理解标注在随笔中。

文章目录
0x01 创建Qt Quick Extension Plugin项目
  0x01-1 新建项目选择 Library --Qt Quick 2 Extension Plugin

  0x01-2 输入项目属性值

  [input] -项目名称 QmlAssembly
  [input] -项目路径 随意填写,与我们最终想要的效果没有关系

  0x01-3 配置项目细节

  [input] -Object class-name 随便填
  [input] -URL com.mycompany.qmlcomponents

  0x01-3 配置项目工具箱

  [select] 勾选 MinGW-32
  [select] 勾选 MinGW-64

0x02 配置自定义的组件参数
  0x02-1 添加自定义.qml组件 MyRect.qml MyRect2.qml
// MyRect.qml
import QtQuick 2.0

Rectangle {

    border.color: "red"
}

-------------------------------------------------------------------------

// MyRect2.qml
import QtQuick 2.0

Rectangle {

    border.color: "blue"
}
  0x02-2 删除自动生成的Object class-name名 .h .cpp 文件

  我这里是默认Object class-name名,所以我这里是删除 myitem.h myitem.cpp 文件

  0x02-3 添加注册的自定义QML组件
// void registerTypes(const char *uri) override
// 重写这个方法,并把自定义的QML组件注册到 URL 中
void QmlAssemblyPlugin::registerTypes(const char *uri)
{
    // @uri com.mycompany.qmlcomponents
    // param QUrl("qrc:/xxxx.qml") 是自定义组件的.qml文件地址
    // param 注册到URL
    // param 主版本号
    // param 次版本号
    // param 外部使用的类型名
    qmlRegisterType(QUrl("qrc:/MyRect.qml"), uri, 1, 0, "MyRect");
    qmlRegisterType(QUrl("qrc:/MyRect2.qml"), uri, 2, 0, "MyRect");
}
  0x02-4 编译并创建最终库目录
// 我们的自定义的组件动态库如果存放地址为 F:/Library/QmlAssembly
// Step 1 >> 在 F:/Library/QmlAssembly 目录下创建 com/mycompany/qmlcomponents/ 多级目录
// Step 2 >> 将编译后的 `debug` `release` `qmldir` 文件复制到 F:/Library/QmlAssembly/com/mycompany/qmlcomponents/ 目录下
  0x02-5 自动生成 .qmltype 文件

  qmlplugindump >> 自动生成 .qmltype 文件
  我们编译后,如果是 MinGW-32 编译的就打开 mingw73_32控制台,如果是 MinGW-64 编译的就打开 mingw73_64控制台

// param 项目中的 url
// param 版本号
// param 导出 `debug` `release` `qmldir` 文件的url路径
// param 导出的 `qmltype` 文件的存储路径
cmd >> `qmlplugindump com.mycompany.qmlcomponents 1.0 F:/Library/Qt/QmlAssembly > F:/Library/Qt/QmlAssembly/com/mycompany/qmlcomponents/mymodule.qmltype`

/*
// mymodule.qmltype
import QtQuick.tooling 1.2

// This file describes the plugin-supplied types contained in the library.
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
// 'qmlplugindump com.mycompany.qmlcomponents 1.0 F:/Library/Qt/QmlAssembly'

Module {
    dependencies: ["QtQuick 2.12"]
    Component {
        prototype: "QQuickRectangle"
        name: "MyRect 2.0"
        exports: ["MyRect 2.0"]
        exportMetaObjectRevisions: [0]
        isComposite: true
        defaultProperty: "data"
    }
    Component {
        prototype: "QQuickRectangle"
        name: "MyRect 1.0"
        exports: ["MyRect 1.0"]
        exportMetaObjectRevisions: [0]
        isComposite: true
        defaultProperty: "data"
    }
}

*/
  0x02-6 将自动生成的 .qmltype 文件信息链接到 qmldir 文件内
// 添加 >> typeinfo mymodule.qmltype
0x03 测试QML动态库
/*
Step 1 >> 创建一个纯净的QML的App项目
Step 2 >> 在 main.cpp 12 行添加 --engine.addImportPath("F:/Library/Qt/QmlAssembly/");
Step 3 >> 在main.qml中导入自定义QML组件库 --import com.mycompany.qmlcomponents 1.0
Step 4 >> 添加自定义的组件 MyRect
*/

main.qml 代码截图

com.mycompany.qmlcomponents 1.0 运行效果图

com.mycompany.qmlcomponents 2.0 运行效果图

总结
  • QML组件库封装的 URL 项必须在文件系统中展开,如 URL >> com.mycompany.qmlcomponents 在文件系统中就是 com/mycompany/qmlcomponents
  • 在QML的App项目中使用自定义QML库封装组件,必须通过 QQmlApplicationEngine::addImportPath() QML_IMPORT_PATH 导入到该项目才能使用
  • 如果你不能正常的自动生成 .qmltype 文件,那么你的关注点应该在 0x02-3 0x02-4 0x02-5,因为这几个点都可能会影响 .qmltype 文件能否正常的被生成
posted on   怪小子  阅读(3515)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
              
点击右上角即可分享
微信分享提示