2017-08-05 10 views
2

Edit2:接受的答案演示了警告如何避免造成太大的問題。我已經改變了這個問題的主題,以更好地反映實際上在那裏回答的問題。它沒有解決在Edit1中提到的Binding問題,但是由於警告不再擔心我使用Binding的主要原因不再相關。在JavaScript中動態創建的QML對象的綁定屬性時發出警告

編輯:根據Praveen Kumar的建議,我創建了一個MVCE來說明問題。但是,代碼現在似乎按預期工作!但是,因爲所使用的方法在文檔中有明確的警告,所以我已經爲解決方案必須涉及綁定QML類型的問題添加了條件,這仍然是我不瞭解如何執行的操作。

修改了原始問題:我有一些在QML中動態創建的對象,我想將這些對象的一些屬性綁定到靜態對象的屬性上。

我已經使用ListModel來管理動態創建的對象,建議爲here

使用此ListModel我沒有問題循環所有對象並訪問它們。

相同的網站建議使用the Binding component的綁定屬性,但我不明白如何使用它。

我能夠使這項工作不綁定類型如下面的代碼演示:

main.qml

import QtQuick 2.6 
import QtQuick.Window 2.2 
import QtQuick.Controls 2.1 

Window { 
    visible: true 
    width: 640 
    height: 480 

    ListModel 
    { 
     id: listModel 
    } 

    Column 
    { 
     id: mainCol 
     anchors.centerIn: parent 
     spacing: 10 

     Button 
     { 
      text: "Click to create object" 

      onClicked: 
      { 
       var component = Qt.createComponent("Box.qml"); 
       var obj = component.createObject(mainCol); 

       listModel.append({"obj": obj}) 
      } 
     } 

     TextField 
     { 
      id: inputTxt 
     } 

     Button 
     { 
      text: "Click to bind properties" 

      onClicked: 
      { 
       for (var i = 0; i < listModel.count; ++i) 
       { 
        var dynObj = listModel.get(i).obj; 
        dynObj.boxTxt = Qt.binding(function() {return inputTxt.text}); 
       } 
      } 
     } 
    } 
} 

Box.qml

import QtQuick 2.0 

Rectangle 
{ 
    property alias boxTxt: txt.text 

    width: 100 
    height: 100 
    color: "lightblue" 

    Text 
    { 
     id: txt 
     text: "Dynamic object" 
    } 
} 

這正是我想要的,但文檔塔季翁有大約ListModel.get(此警告):

警告:返回的對象不保證仍然有效。它不應該用於屬性綁定。

這就是我正在做的。

我不能用綁定包裹我的頭。我不需要爲每個Box組件動態創建一個新的Binding組件嗎?這難道不會讓我走得更遠嗎?

如果綁定不是這樣做的,那也是一個有趣的答案!

(另外,如果編輯的問題,這種方式是不是在這裏做事情的方式,請讓我知道在評論)

+0

你能提供[MVCE](https://stackoverflow.com/help/mcve)嗎? –

+0

@PraveenKumar謝謝!我創建了一個MVCE,代碼以intendend的形式工作。工作中的代碼中必須有其他內容。然而,我使用的方法我認爲不夠健壯,所以我相應地改變了這個問題。 –

+0

如果下面提到的描述回答了您的問題/疑問,請接受答案,以便其他人可以在將來參考。它非常好描述。 –

回答

0

我很抱歉,我有那麼一點時間想想你嘗試什麼。 ..我真的不明白,爲什麼你應該添加視覺對象到ListModel,但可能有一些原因......

至於我的理解是你的問題與警告:

警告:返回的對象不保證仍然有效。它不應該用於屬性綁定。

所以我想告訴你,因爲這個警告你不應該遇到太多的問題。

讓我們看看爲什麼(你在做什麼)

onClicked: { 
    var component = Qt.createComponent("Box.qml"); 
    var obj = component.createObject(mainCol); 

    listModel.append({"obj": obj}) 
} 

在這裏,您創建對象與mainCol因爲它的父。要銷燬它,您需要明確銷燬mainCol或在對象上調用destroy()
只要你不這樣做,你不必擔心創建對象變得無效。

現在您將一個新的JSObject添加到ListModel,該保存對新創建的項目的引用。

然後,你必須:

 onClicked: 
     { 
      for (var i = 0; i < listModel.count; ++i) 
      { 
       var dynObj = listModel.get(i).obj; 
       dynObj.boxTxt = Qt.binding(function() {return inputTxt.text}); 
      } 
     } 

現在:listModel.get(i)將返回這是由JS垃圾收集處理,這意味着一個對象,一旦有什麼引用它了和GC有一個運行,該對象將被丟棄。 (理想情況下,有時候GC有點貪婪!)
如果現在,你有一個綁定到所述對象,綁定將失去連接(因爲這可能不是一個引用,由GC值),所以它會沒有好主意有這樣的事情:

var dObj = listModel.get(i) 
property var x = Qt.binding(function() { return dObj }) 

但你不這樣做。實際上,您正在使用之前創建的物品的參考,您填入ListModel以綁定此物品Item。爲此,您讀的行中的參考一次

var dynObj = listModel.get(i).obj; 

現在你不必費心爲有告訴你參考(由listModel.get(i)返回)的只是工作的對象的生命時間了,因爲你有你想要的(.obj)分配(不是綁定)。它可以死了,如果它想要的話,你繼續綁定你想

沒有遵循確切的用例,ObjectModel可能(至少是一樣多)適合您的需求。我在容器中理解這個來存儲對Items的引用。

+1

謝謝!很有意思!我不確定我是否完全遵循,但根據你的意思,我明白get()會向對象返回_reference_,並且此引用可能會被GC拾取。但是,我只是簡單地使用這個引用來訪問_actual_對象的屬性(可以這麼說,在引用「後面」,所以這不是問題? –

+0

是的,你說得對。 – derM