前言
在實際中的開發中,我們總是不希望自己的代碼能被用戶看到,但是使用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
文件能否正常的被生成