前言
剛接觸 QML
語言的時候,感覺很新鮮,上手及其簡單,但是用着用着才發現在 QML
中創建靜態的組件很簡單,但是動
態組件應該怎么創建呢?
知識點
效果展示
目錄
目標需求說明
/**
* 測試 QML 動態創建組件程序實例
*
* 需求
* 1. 可以通過人機交互的方式動態創建測試子窗口
* 2. 可以通過人機交互的方式動態刪除最后一個測試子窗口實例對象
* 3. 可以通過人機交互的方式動態改變並復原測試子窗口實例對象的風格
*/
Loader 組件
剛開始的時候,在網上查找的資料里面是用 Loader 來實現動態創建組件,它的 Demo 類似於瀏覽器,但是它的每一行是
可以刪除的,它是使用 QML 的綁定機制實現的動態效果,Loader 只是延時加載了類似瀏覽器的組件而已, 導致我誤以為
QML中的動態創建組件是通過 Loader 實現的,走了不少彎路,搞心態,最后都懷疑自己是不是理解能力有問題...
Loader 在QML中不是用來動態創建組件的,它只是延時創建組件而已,且一個 Loader 對應一個組件,不能一對多的情況,
Loader 是通過 source
屬性來指定加載哪一個組件,同時也可以通過 sourceComponent
屬性來延時加載自定義組
件
Qt.createQmlObject()
引用自 Qt Help
object createQmlObject(string qml, object parent, string filepath)返回從給定的qml字符串創建的新對象,該字符串將具有指定的父對象,如果創建對象時出錯,則返回
null
如果指定了filepath,則它將用於所創建對象的錯誤報告
這個方法能實現我們想要的目標效果,在程序運行后動態的創建、刪除 QML
組件,只是參數有點多,emm~~ 一下枚舉出
Qt.createQmlObject() 的使用方法吧
var var_arg01 = String('import QtQuick 2.0; Rectangle {color: "%1"; width: 640; height: 50; y: %2 * 50}').arg(widgetSize % 2? "red": "blue").arg(widgetSize)
var newObject = Qt.createQmlObject(var_arg01,
id_rootWindow,
"");
可以看到創建一個 Rectangle
組件就需要寫這么多代碼,非常的麻煩,而且我嘗試這使用 Qt.createQmlObject()
創建自定義組件,各種報錯,但是外部導入的模塊就不會有那么多的曲折,目前我把這個接口定義為創建外部擴展模塊的組
件方法
好的,既然有不爽,就有爽的方法,安排
Qt.createComponent()
引用自 Qt Help
object createComponent(url, mode, parent)返回使用QML文件在指定的url處創建的組件對象,如果給定空字符串,則返回null。
返回的組件的
component::status
屬性指示組件是否已成功創建。如果狀態是組件。
有關錯誤說明,請參見Component::errorString()
。如果可選模式參數設置為組件。異步,組件將加載到后台線程中。
Component::status
屬性將是組件。加載在裝貨的時
候。狀態將更改為組件。
准備好了嗎如果組件加載成功,或組件。錯誤如果加載失敗。此參數默認為組件.首選同步如果省略。如果模式設置為組件.首選同步,Qt將嘗試同步加載組件,但可能會在必要時異步加載。可能導致異步加載的情況包括但不
限於以下情況:URL引用網絡資源
由於正在異步加載另一個組件,因此正在創建該組件
如果給定了可選的parent參數,它應該引用將成為所創建組件對象的父對象的對象。如果沒有傳遞任何模式,這可以是第二
個參數。呼叫組件.createObject在返回的組件上創建該組件的對象實例。
這個方法能更好的實現我們想要的效果,因為在實際中我們需要動態創建的組件一般都是自定義封裝的,當然視情況而定,
程序是死的,人是活的嘛,反正 Qt 給我們提供了 Qt.createQmlObject()
和 object createComponent()
方法