Rectangle.color的行为类似于对象而不是字符串

时间:2017-07-24 17:57:05

标签: qt qml qtquick2

我尝试制作一个能顺时针改变按钮颜色的功能。 当我分配property var acolor: buttons.itemAt(0).color时,变量acolor会随着buttons.itemAt(0).color的更改而更改值。为什么会这样?

这是 main.qml 文件:

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls.Styles 1.4
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3

Window {
    id: root
    visible: true
    width: 600
    height: 400
    title: qsTr("My Window")
    property int numberOfButtons: 9

    GridLayout{
        id: grid
        columns: 3
        anchors.fill: parent

        Repeater {
            id: buttons
            model: root.numberOfButtons;
            delegate: Mybutton {id: butt; color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1); number: index}
        }
    }
}

这是 Mybutton.qml

Rectangle {
    id: rectangle
    width: 50; height: 100
    color: "red"
    property int number: 0

    MouseArea {
        id: mouse
        anchors.fill: parent
        property var acolor: buttons.itemAt(0).color
        onClicked: {
            function rotate()
            {
                acolor = buttons.itemAt(0).color
                console.log(acolor)//heare is #11754c
                buttons.itemAt(0).color = buttons.itemAt(3).color
                console.log(acolor)// but heare is #6c2c3d
                buttons.itemAt(3).color = buttons.itemAt(6).color
                buttons.itemAt(6).color = buttons.itemAt(7).color
                buttons.itemAt(7).color = buttons.itemAt(8).color
                buttons.itemAt(8).color = buttons.itemAt(5).color
                buttons.itemAt(5).color = buttons.itemAt(2).color
                buttons.itemAt(2).color = buttons.itemAt(1).color
                buttons.itemAt(1).color = acolor
            }
            rotate()
        }
    }
}

1 个答案:

答案 0 :(得分:1)

首先,你的设计是错误的。从概念上讲,当它作用于网格布局时,将旋转功能放在按钮中。 rotate()函数应该是网格布局的成员,您只需调用它onClicked

其次,根据typeof(buttons.itemAt(0).color)color的类型为object。这意味着acolor是对该特定对象的引用,这解释了为什么一旦您更改索引0处项目的颜色,该引用指向另一个值。

欺骗它将颜色隐式转换为字符串的一种方法是使用它:

  var acolor = ""
  acolor += buttons.itemAt(0).color
  console.log(acolor)
  buttons.itemAt(0).color = buttons.itemAt(3).color
  console.log(acolor) // the same!!!

现在它将被保留,因为acolor现在是一个字符串而不是一个对象引用。

此外,您并不真正需要property var acolor: buttons.itemAt(0).color部分。

您还可以将颜色显式转换为字符串:

var acolor = buttons.itemAt(0).color.toString()

此外,通过将旋转功能移动到它所属的位置,您可以大大简化按钮中的鼠标区域:

  MouseArea {
    anchors.fill: parent
    onClicked:  grid.rotate()
  }

更新

请注意,如果我们这样做:

property color acolor

function rotate() {
  acolor = buttons.itemAt(0).color
  console.log(acolor)
  buttons.itemAt(0).color = buttons.itemAt(3).color
  console.log(acolor) // still the same
}

它可以按逻辑预期工作。现在acolor的类型为object,但是您有一个对象赋值对象,它将值传递给另一个对象,而对于var,它的行为类似于对象引用。