QML之基於QML封裝動態庫組件


前言

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM