2017-10-06 1 views
2

私のアプリをQt 5.9に移植する際、私はいくつかの奇妙な動作に直面しました。問題を記述したコードは以下の通りです:QMLの予期しないバインディング

import QtQuick 2.9 
import QtQuick.Window 2.2 
import QtQuick.Controls 2.2 

Window { 
    visible: true 
    width: 600 
    height: 800 
    title: qsTr("Test") 

    Row { 
     id: base 
     property var arr: [] 
     property color currentColor: "red" 
     anchors.centerIn: parent 
     spacing: 5 
     Repeater { 
      model: 10 
      delegate: Rectangle { 
       width: 50 
       height: 50 
       border.width: 1 
       border.color: "grey" 
       color: base.arr[index] === undefined ? "white" : base.arr[index] 
       MouseArea { 
        anchors.fill: parent 
        onClicked: { 
         base.currentColor = Qt.rgba(Math.random(),Math.random(),Math.random(),1); 
         base.arr[index] = base.currentColor; 
         base.arr = base.arr; // trick to fire changing event 
         console.log(base.arr) 
        } 
       } 
      } 
     } 
    } 
} 

だから長方形の配列であり、そのうちの一つを押しながら、私はランダムな色を取得し、アイテムの一つとして、いくつかの指標で配列base.arrに配置します。現在の色を維持するプロパティbase.currentColorがあります。しかし問題は、アイテムに新しい色を割り当てると、以前のすべてのアイテムも色が変わるということです。

私はこの問題は、それがこの行は、いくつかの予期しない結合または参照を作成することや、私が表示されていないものは何でも見えるラインに

base.arr[index] = base.currentColor; 

だと思います。 Jsでバインディングを作成する唯一の方法はQt.bindingですが、ここでは使用しません。この動作を破る

この問題を回避するには、次のようなものです:

base.arr[index] = Qt.rgba(base.currentColor.r, base.currentColor.g, base.currentColor.b, base.currentColor.a); 

が、それはオーバーヘッドと汚いソリューションを探します。

誰かがこの奇妙な行動を説明することができたらうれしいです。

答えて

1

QML colorは実際にはobjectです。

JavaScriptオブジェクトでは、オブジェクトは参照によってコピーされるため、QML color変数は実際にはポインタのように動作します。このラインで

base.arr[index] = base.currentColor; 

配列要素は、currentColorオブジェクトへ参照として設定されています。

各配列要素が設定されると、同じcurrentColorオブジェクトへの参照として設定されます。したがって、currentColorを変更すると、配列内のすべての要素が変更されます。これに代えて

property color currentColor: "red" 

使用この:QMLで

property string currentColor: "red" 

文字列は常に値によってコピーされますので、あなたは、もはや問題はありません。

全コード:私は理解できない何

import QtQuick 2.9 
import QtQuick.Window 2.2 
import QtQuick.Controls 2.2 

Window { 
    visible: true 
    width: 600 
    height: 800 
    title: qsTr("Test") 

    Row { 
     id: base 
     property var arr: [] 
     property string currentColor: "red" 
     anchors.centerIn: parent 
     spacing: 5 
     Repeater { 
      model: 10 
      delegate: Rectangle { 
       width: 50 
       height: 50 
       border.width: 1 
       border.color: "grey" 
       color: base.arr[index] === undefined ? "white" : base.arr[index] 
       MouseArea { 
        anchors.fill: parent 
        onClicked: { 
         base.currentColor = Qt.rgba(Math.random(),Math.random(),Math.random(),1); 
         base.arr[index] = base.currentColor; 
         base.arr = base.arr; // trick to fire changing event 
         console.log(base.arr) 
        } 
       } 
      } 
     } 
    } 
} 

がある - あなたはQtの5.9にアプリを移植していると述べた...あなたはQtの以前のバージョンからの移植された場合、私は以前のバージョンではコードが同じように動作しないことに驚いた。

+0

お返事ありがとうございます@マークチャネル。あなたが言ったことはすべて正しいですが、別の問題が心配です。その値をコピーするのではなく、オブジェクトへの参照を割り当てることは、私が推測するところでは予想される動作ではありません。あなたの提案によれば、単純なオブジェクトの動作は異なりますか?それらの一部は参照( 'color'など)を割り当て、部分はその値(' string'など)をコピーします。 – folibis

+0

私はあなたが懸念するのが正しいと思う、それは私のバグのようだ。 5.9では、この動作が以前のバージョンと異なっていますか? –

関連する問題