为什么 QML Model-View-Delegate 的行为是这样的?
Why does QML Model-View-Delegate behave like this?
我正在尝试制作一个 ListView
的 n CheckBox
项,其中最上面的一项是 "select/deselect all" 项。在程序启动时检查 select/deselect 所有 CheckBox
es 时,它 selects/deselects 所有 n CheckBox
es,但是一旦我 check/uncheck n [=] 15=]es 然后返回按 select/deselect 全部,之前的 checked/unchecked CheckBox
不再切换。我不明白为什么它不能按预期工作。下面提供了代码和调试输出:
查看:
import QtQuick 2.0
import QtQuick.Controls 1.2
Rectangle {
id: view
ScrollView {
id: scrollView
anchors.fill: parent
ListView {
id: listView
anchors.fill: parent
model: myModel
delegate: Delegate { }
}
}
Model {
id: myModel
Component.onCompleted: {
add("C", "Orange", false)
add("D", "Red", false)
}
}
function add(name, color, check)
{
myModel.append({"name":name, "color":color, "check":check})
}
function edit(index, attribute, value)
{
myModel.setProperty(index, attribute, value)
}
function editMultiple(offset, length, attribute, value)
{
for (var i = offset; i < length; i++)
{
edit(i, attribute, value)
}
}
function length()
{
return myModel.count
}
}
代表:
import QtQuick 2.0
import QtQuick.Controls 1.2
Item {
id: delegate
height: 40
width: 100
property bool allCheckBoxChecked: false
CheckBox {
id: checkBox
text: name
anchors {
fill: parent
leftMargin: 20
rightMargin: 20
}
checked: check
onCheckedChanged: {
if (index === 0)
{
allCheckBoxChecked = checkBox.checked
}
else
{
edit(index, "check", checkBox.checked)
}
console.log("Name: " + name + " Color: " + color + " Check: " + check)
}
}
onAllCheckBoxCheckedChanged: {
console.log("All: " + allCheckBoxChecked)
if (allCheckBoxChecked)
{
editMultiple(0, length(), "check", true)
}
else
{
editMultiple(0, length(), "check", false)
}
}
}
型号:
import QtQuick 2.0
ListModel {
id: listModel
ListElement {
name: "All"
color: "Black"
check: false
}
ListElement {
name: "A"
color: "Blue"
check: false
}
ListElement {
name: "B"
color: "Green"
check: false
}
}
调试输出:
//Pressing "All".
qml: All: true
qml: Name: A Color: Blue Check: true
qml: Name: B Color: Green Check: true
qml: Name: C Color: Orange Check: true
qml: Name: D Color: Red Check: true
qml: Name: All Color: Black Check: true
//Pressing "All".
qml: All: false
qml: Name: A Color: Blue Check: false
qml: Name: B Color: Green Check: false
qml: Name: C Color: Orange Check: false
qml: Name: D Color: Red Check: false
qml: Name: All Color: Black Check: false
//Pressing "A".
qml: Name: A Color: Blue Check: true
//Pressing "All".
qml: All: true
//A does not get assigned anymore...
qml: Name: B Color: Green Check: true
qml: Name: C Color: Orange Check: true
qml: Name: D Color: Red Check: true
qml: Name: All Color: Black Check: true
//Pressing "All".
qml: All: false
//A does not get assigned anymore...
qml: Name: B Color: Green Check: false
qml: Name: C Color: Orange Check: false
qml: Name: D Color: Red Check: false
qml: Name: All Color: Black Check: false
QML 属性 可以通过静态赋值(javascript 赋值)或通过绑定赋值,但不能同时 因为静态赋值 擦除 绑定。
在您的情况下,当程序启动时,所有 Checkbox
es 使用 属性 绑定。但是当您单击 CheckBox
时,静态分配会删除这些绑定。这意味着现在将静态值分配给 属性 checked
(true
或 false
)。可能的解决方法是使用 Qt.binding
在 JS 中生成 属性 绑定,即保留原始绑定。您可以阅读更多相关信息 here。
我正在尝试制作一个 ListView
的 n CheckBox
项,其中最上面的一项是 "select/deselect all" 项。在程序启动时检查 select/deselect 所有 CheckBox
es 时,它 selects/deselects 所有 n CheckBox
es,但是一旦我 check/uncheck n [=] 15=]es 然后返回按 select/deselect 全部,之前的 checked/unchecked CheckBox
不再切换。我不明白为什么它不能按预期工作。下面提供了代码和调试输出:
查看:
import QtQuick 2.0
import QtQuick.Controls 1.2
Rectangle {
id: view
ScrollView {
id: scrollView
anchors.fill: parent
ListView {
id: listView
anchors.fill: parent
model: myModel
delegate: Delegate { }
}
}
Model {
id: myModel
Component.onCompleted: {
add("C", "Orange", false)
add("D", "Red", false)
}
}
function add(name, color, check)
{
myModel.append({"name":name, "color":color, "check":check})
}
function edit(index, attribute, value)
{
myModel.setProperty(index, attribute, value)
}
function editMultiple(offset, length, attribute, value)
{
for (var i = offset; i < length; i++)
{
edit(i, attribute, value)
}
}
function length()
{
return myModel.count
}
}
代表:
import QtQuick 2.0
import QtQuick.Controls 1.2
Item {
id: delegate
height: 40
width: 100
property bool allCheckBoxChecked: false
CheckBox {
id: checkBox
text: name
anchors {
fill: parent
leftMargin: 20
rightMargin: 20
}
checked: check
onCheckedChanged: {
if (index === 0)
{
allCheckBoxChecked = checkBox.checked
}
else
{
edit(index, "check", checkBox.checked)
}
console.log("Name: " + name + " Color: " + color + " Check: " + check)
}
}
onAllCheckBoxCheckedChanged: {
console.log("All: " + allCheckBoxChecked)
if (allCheckBoxChecked)
{
editMultiple(0, length(), "check", true)
}
else
{
editMultiple(0, length(), "check", false)
}
}
}
型号:
import QtQuick 2.0
ListModel {
id: listModel
ListElement {
name: "All"
color: "Black"
check: false
}
ListElement {
name: "A"
color: "Blue"
check: false
}
ListElement {
name: "B"
color: "Green"
check: false
}
}
调试输出:
//Pressing "All".
qml: All: true
qml: Name: A Color: Blue Check: true
qml: Name: B Color: Green Check: true
qml: Name: C Color: Orange Check: true
qml: Name: D Color: Red Check: true
qml: Name: All Color: Black Check: true
//Pressing "All".
qml: All: false
qml: Name: A Color: Blue Check: false
qml: Name: B Color: Green Check: false
qml: Name: C Color: Orange Check: false
qml: Name: D Color: Red Check: false
qml: Name: All Color: Black Check: false
//Pressing "A".
qml: Name: A Color: Blue Check: true
//Pressing "All".
qml: All: true
//A does not get assigned anymore...
qml: Name: B Color: Green Check: true
qml: Name: C Color: Orange Check: true
qml: Name: D Color: Red Check: true
qml: Name: All Color: Black Check: true
//Pressing "All".
qml: All: false
//A does not get assigned anymore...
qml: Name: B Color: Green Check: false
qml: Name: C Color: Orange Check: false
qml: Name: D Color: Red Check: false
qml: Name: All Color: Black Check: false
QML 属性 可以通过静态赋值(javascript 赋值)或通过绑定赋值,但不能同时 因为静态赋值 擦除 绑定。
在您的情况下,当程序启动时,所有 Checkbox
es 使用 属性 绑定。但是当您单击 CheckBox
时,静态分配会删除这些绑定。这意味着现在将静态值分配给 属性 checked
(true
或 false
)。可能的解决方法是使用 Qt.binding
在 JS 中生成 属性 绑定,即保留原始绑定。您可以阅读更多相关信息 here。