现在,在将我的应用程序移植到Qt 5.9时,我遇到了一些奇怪的行为。描述该问题的代码如下:
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);
但它看起来是开销和肮脏的解决方案。
如果有人能解释这种奇怪的行为,我会很高兴。
答案 0 :(得分:1)
QML color
实际上是一种颜色object
。
在JavaScript中,对象是通过引用复制的,因此QML color
变量实际上更像是指针。
在这一行:
base.arr[index] = base.currentColor;
将数组元素设置为currentColor
对象的引用。
设置每个数组元素后,它将被设置为对同一个currentColor
对象的引用!因此,更改currentColor
会更改数组中的每个元素。
而不是:
property color currentColor: "red"
使用它:
property string currentColor: "red"
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 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移植,那么我很惊讶代码在前一版本中的行为方式不同。