<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

在JavaScript中動態的創建QML對象

工程師鄧生 ? 來源:嵌入式小生 ? 作者:iriczhao ? 2022-09-01 10:42 ? 次閱讀

在實際QML應用開發中,我們可以在JavaScript中動態的創建QML對象。這樣做可以延遲對象的實例化,當我們在需要創建對象的時候才在JavaScript代碼中創建,則可以縮短應用程序的啟動時間,還可以動態創建可視對象,有助于提高應用程序性能。

創建動態對象

有兩種方法可以在JavaScript代碼中動態的創建對象。

第一種是:調用Qt.createComponent()來動態創建一個Component對象;

第二種是:使用Qt.createQmlObject()函數,以QML字符串的方式創建一個對象。

如果我們已經在QML文檔中定義了一個現有組件,并希望可以動態地創建該組件實例,那么可選擇第一種方法。當我們需要在運行時創建QML對象,應選擇第二種方法。

下文將分別介紹這兩種方法。

動態創建組件

要動態加載定義在QML文件中的組件,需調用Qt對象中的Qt.createcomponent()函數。這個函數將接收QML文件的URL參數,并根據這個URL創建一個Component對象。

一旦創建了組件,則可以調用createObject()方法來創建該組件的一個實例。createObject()函數可以接收兩個參數:

(1)參數一:第一個是新對象的父對象。父對象可以是圖形對象(即Item類型)或非圖形對象(即QtObject或C++ QObject類型)。只有帶有圖形父對象的圖形對象才會呈現到Qt Quick視覺畫布中。如果想在后續設置父函數,我們可以將null傳遞給這個函數。

(2)參數二:第二個是可選參數,是<屬性-值>的映射,用于定義對象的初始屬性值。在創建對象之前,將此參數指定的屬性值應用于對象,可以避免綁定錯誤。當然與在創建對象后定義屬性值和屬性綁定相比,這種方式在性能上有一些小的影響。

例如,這里有一個qml文件,名為MyComponent.qml,代表一個QML組件:

importQtQuick2.0

Rectangle{width:80;height:50;color:"red"}

然后創建一個JavaScript腳本文件:componentCreation.js。用于檢測在調用createObject()之前組件是否被創建好(如果QML文件是通過網絡加載的,則不可能立即就準備好,故此處需要判斷處理),如下代碼:

varcomponent;
varsprite;

functioncreateSpriteObjects(){
component=Qt.createComponent("MyComponent.qml");
if(component.status==Component.Ready)
finishCreation();
else
component.statusChanged.connect(finishCreation);
}

functionfinishCreation(){
if(component.status==Component.Ready){
sprite=component.createObject(appWindow,{x:100,y:100});
if(sprite==null){
//ErrorHandling
console.log("Errorcreatingobject");
}
}elseif(component.status==Component.Error){
//ErrorHandling
console.log("Errorloadingcomponent:",component.errorString());
}
}

在實際的開發中,基本上都是從本地加載qml文件,這時候則可以省略finishCreation()函數,立即調用createObject(),例如下例代碼:

functioncreateSpriteObjects(){
component=Qt.createComponent("Sprite.qml");
sprite=component.createObject(appWindow,{x:100,y:100});

if(sprite==null){
//ErrorHandling
console.log("Errorcreatingobject");
}
}

注意,上面例子中,createObject()都是在appWindow作為父參數傳遞的情況下調用的,因為動態創建的對象是一個可視化對象。創建的對象將成為main.qml中的appWindow對象的子對象,并出現在界面中。

接著我們在main.qml文件中使用import "componentCreation.js" as MyScript語句導入componentcreate.js文件,用于創建MyComponent對象:

importQtQuick2.0
import"componentCreation.js"asMyScript

Rectangle{
id:appWindow
width:300;height:300

Component.onCompleted:MyScript.createSpriteObjects();
}

如果需要將信號連接到動態創建對象的信號處理函數,需使用信號的connect()方法。

以QML字符串形式創建對象

在QML開發中,很多時候都會在運行時定義QML對象,這時候則可以使用Qt.createQmlObject()函數來實現,在函數中指定QML字符串來創建一個QML對象,如下代碼:

varnewObject=Qt.createQmlObject('importQtQuick2.0;Rectangle{color:"red";width:20;height:20}',parentItem,"dynamicSnippet1");

Qt.createQmlObject()函數需要三個參數:

(1)第一個參數是要創建的QML字符串。其中的QML字符串就像在新qml文件中創建組件的編寫方式一樣。

(2)第二個參數是新對象的父對象。

(3)第三個參數是與新對象相關聯的文件路徑,用于報告錯誤信息。

【特別注意(一)】

如果QML字符串使用相對路徑方式導入文件,則該路徑應該相對于父對象(方法的第二個參數)所在的文件。

【特別注意(二)】

在構建靜態QML應用程序時,QML引擎會掃描QML文件來檢測導入依賴項。這樣,所有必需的插件和資源都在編譯時解析。但是,只考慮顯式的import語句(在QML文件頂部找到的那些),而不會考慮包含在字符串文本中的import語句。因此,為了支持靜態構建,我們需要在使用Qt.createQmlObject()的QML文件中,還需要在文件頂部顯式地包含所有的導入信息。

管理動態創建的對象

在管理動態創建的對象時,必須確保創建上下文的生命周期比創建的對象長。否則,如果創建上下文先被銷毀,動態對象中的綁定和信號處理程序將會“罷工”。

實際的創建上下文取決于對象是如何創建的:

(1)如果使用了Qt.createComponent(),創建上下文就是在其中調用此方法的QQmlContext。

(2)如果調用Qt.createQmlObject(),創建上下文是傳遞給該方法的父對象的上下文。

(3)如果定義了一個Component{}對象,并且在該對象上調用了createObject()或incubateObject(),那么創建上下文就是組件定義的上下文。

備注:雖然動態創建的對象可以像其他對象一樣使用,但它們在QML中是沒有id屬性的。

刪除動態對象

在大多數用戶界面開發中,將可視對象的不透明度設置為0或將可視對象移出屏幕,則可以滿足許多的開發需求了。但是,如果應用界面中有多個動態創建的對象,那么刪除不使用的對象可能會獲得較好性能。

但注意不要手動刪除由QML對象工廠(如Loader和Repeater)動態創建的對象。另外還應該避免刪除不是自己動態創建的對象。

我們可以使用destroy()方法刪除Item。該方法有一個可選參數(默認為0),用于指定對象被銷毀前的延遲時間。

這里有一個例子:我們在application.qml文件中創建了SelfDestroyingRect的五個實例組件。每個實例運行一個NumberAnimation,當animation完成時,調用它的根對象的destroy()來銷毀,代碼如下:

//application.qml

importQtQuick2.0

Item{
id:container
width:500;height:100

Component.onCompleted:{
varcomponent=Qt.createComponent("SelfDestroyingRect.qml");
for(vari=0;i<5;?i++)?{
????????????var?object?=?component.createObject(container);
????????????object.x?=?(object.width?+?10)?*?i;
????????}
????}
}

//SelfDestroyingRect.qml

importQtQuick2.0

Rectangle{
id:rect
width:80;height:80
color:"red"

NumberAnimationonopacity{
to:0
duration:1000

onRunningChanged:{
if(!running){
console.log("Destroying...")
rect.destroy();
}
}
}
}

另外,application.qml可以調用object.destroy()來銷毀已創建的對象。

備注:上述代碼中,調用對象的destroy()是安全的。因為對象不會在調用destroy()的瞬間被銷毀,而是在腳本塊結束后的某個時刻被清除(非零延遲除外)。

在銷毀對象時,需要注意對象只有在動態創建的情況下才能動態銷毀。

對于使用Qt.createQmlObject()創建的對象也可以使用destroy()銷毀,例如下例JavaScript代碼:

varnewObject=Qt.createQmlObject('importQtQuick2.0;Rectangle{color:"red";width:20;height:20}',
parentItem,
"dynamicSnippet1");
newObject.destroy(1000);



審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • URL
    URL
    +關注

    關注

    0

    文章

    135

    瀏覽量

    14890
  • JAVA語言
    +關注

    關注

    0

    文章

    138

    瀏覽量

    19956
  • javascript
    +關注

    關注

    0

    文章

    512

    瀏覽量

    53450

原文標題:“神級”般的QML開發技巧,學會了

文章出處:【微信號:嵌入式小生,微信公眾號:嵌入式小生】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    vb運行時錯誤429不能創建對象

    VB運行時錯誤429代表不能創建對象的錯誤。這個錯誤可能會發生在使用CreateObject函數或New關鍵字創建對象時。 這種錯誤通常發生在以下情況下: 缺少所需的組件或庫:
    的頭像 發表于 01-09 11:07 ?852次閱讀

    javascript屬于前端嗎

    JavaScript是一種高級編程語言,通常用于網頁開發。它是一種腳本語言,可用于在網頁上動態交互,提供更好的用戶體驗。JavaScript是一種廣泛使用的技術,幾乎所有現代網頁都使用它來實現交互性
    的頭像 發表于 12-03 11:43 ?804次閱讀

    javascript的文件擴展名

    JavaScript的文件擴展名是.js。它是一種廣泛使用的腳本語言,用于為網頁添加交互性和動態功能。在本文中,我將詳細介紹JavaScript的文件擴展名.js,包括其起源、用途、特點以及
    的頭像 發表于 12-03 11:42 ?790次閱讀

    javascript的內置對象有哪些

    你全面了解JavaScript的能力和應用場景。 一、基本數據類型對象: String(字符串對象):用于處理和操作文本數據。 Number(數字對象):用于處理和操作數字數據。 Bo
    的頭像 發表于 12-03 11:39 ?822次閱讀

    javascript規定了幾種語言類型

    JavaScript是一種強大的編程語言,主要用于在網頁上實現動態的交互效果和功能。它不僅可以與HTML和CSS配合使用來構建網頁,還可以用于開發各種類型的應用程序,包括網絡應用程序、桌面應用程序
    的頭像 發表于 12-03 11:37 ?494次閱讀

    javascript的基本數據類型有哪些

    JavaScript 是一種動態的、面向對象的編程語言,廣泛應用于 Web 開發中。在 JavaScript 中,有七種基本數據類型(Primitive Types),它們分別是 Un
    的頭像 發表于 12-03 11:17 ?389次閱讀

    JavaScript的語法和基本功能

    的語法和基本功能。JavaScript可以在網頁中實現交互和動態效果,為用戶提供更好的使用體驗。 JavaScript最早由網景公司(Netscape)的布蘭登·艾奇(Brendan Eich
    的頭像 發表于 12-03 11:15 ?340次閱讀

    JavaScript的用途和功能

    JavaScript是一種廣泛使用的腳本語言,用于為網站添加動態功能和交互性。從創建簡單的交互式表單到設計復雜的網頁游戲,JavaScript為開發者提供了豐富的功能和靈活的創作能力。
    的頭像 發表于 12-03 11:12 ?485次閱讀

    javascript指什么

    JavaScript是一種高級編程語言,通常用于為網頁添加交互功能。它是一種面向對象的語言,旨在通過編寫代碼來控制網頁的行為,使用戶能夠與網頁進行動態交互。JavaScript能夠與H
    的頭像 發表于 12-03 11:11 ?439次閱讀

    javascript深入淺出介紹

    語法、數據類型、函數、對象、DOM等等。 首先,我們來看一下JavaScript的語法。JavaScript是一種弱類型語言,這意味著變量可以保存不同類型的值。它也是一種動態語言,這意
    的頭像 發表于 12-03 11:09 ?2.8w次閱讀

    javascript:;怎么解決

    javascript:” 是一個JavaScript偽協議,它通常出現在URL地址欄或鏈接中,用于執行JavaScript代碼。然而,有時它可能會導致一些問題,特別是在一些不支持
    的頭像 發表于 11-26 14:39 ?2569次閱讀

    javascript深入淺出

    JavaScript是一種廣泛使用的編程語言,常用于Web開發。下面是對JavaScript的深入淺出的解釋: JavaScript簡介 JavaScript是一種解釋型、
    的頭像 發表于 11-16 10:34 ?369次閱讀

    javascript的成熟分類

    類型語言:JavaScript動態類型的語言,這意味著它不需要在聲明變量時指定數據類型。 面向對象語言:JavaScript是一種基于原型的面向
    的頭像 發表于 11-16 10:30 ?20.9w次閱讀

    javascript有什么用

    JavaScript是一種廣泛使用的編程語言,主要用于增強網頁和創建動態網頁內容。以下是JavaScript的一些主要用途: 交互性:JavaScr
    的頭像 發表于 11-16 10:19 ?445次閱讀

    python創建文件對象

    2.1. 創建文件對象 **open() 函數用于創建文件對象,基本語法格式如下:** open(文件名[,打開方式]) 注意: 如果只是文件名,代表在當前目錄下的文件. 文件名可以錄
    的頭像 發表于 06-21 17:19 ?1148次閱讀
    python<b class='flag-5'>創建</b>文件<b class='flag-5'>對象</b>
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>