Почему QML Model-View-Delegate ведет себя так?

Я пытаюсь сделать ListView из n CheckBox элементов, где верхний элемент является элементом «выбрать/отменить выбор всех». При проверке выбора/отмены выбора всех CheckBoxes при запуске программы он выбирает/отменяет выбор всех n CheckBoxes, но как только я проверяю/снимаю отметку с любого из n CheckBoxes, а затем возвращаюсь к нажатию выбора/отмены всех, ранее отмеченные/неотмеченные 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

person uniquenamehere    schedule 13.08.2015    source источник


Ответы (1)


Свойство QML может иметь значение, назначенное через статическое назначение (назначение JavaScript) или через привязку, но не в то же время, поскольку статическое присвоение удаляет привязки.

В вашем случае при запуске программы все Checkboxes используют привязки свойств. Но когда вы нажимаете CheckBox, статическое назначение удаляет эти привязки. Это означает, что теперь свойству checked присваивается статическое значение ( true или false). Возможный обходной путь — использовать Qt.binding для создания привязки свойства в JS, т. е. сохранить исходную привязку. Подробнее об этом можно прочитать здесь. .

person folibis    schedule 13.08.2015
comment
Ты совершенно прав! Привязка была нарушена. Я использовал Qt.binding() для восстановления привязок, и теперь он отлично работает! Спасибо! - person uniquenamehere; 13.08.2015