qml: DelegateModel + Package временно заставляет делегата иметь нулевого родителя - PullRequest
0 голосов
/ 05 мая 2020

При использовании Package , State и ParentChange для переназначения делегата одному из нескольких представлений, у делегата на мгновение появляется нулевой родительский элемент. в то время как привязки переоцениваются. Это вызывает ошибки, если у делегата есть привязки к parent .width или аналогичному.

Это беспокоит, потому что пример опубликованного Qt Package отображает то же самое. проблема, если начальное состояние изменено на другое альтернативное

(Чтобы воспроизвести: скопируйте .... / Qt / examples / Qt-5.14.1 / quick / views / package / {view.qml, Delegate. qml} и измените начальное значение upTo с 0 на 7 в view.qml, а затем запустите «qmlscene view.qml».).

Ниже приведено упрощение примера Qt с константой состояние . Активное Состояние использует ParentChange , которое определяет ширину ; это каким-то образом приводит к тому, что делегат на мгновение имеет нулевого родителя, и привязка для width: parent.width получает ошибку:

test.qml строка 26: TypeError: невозможно прочитать свойство 'width', равное null

Что вызывает это, а точнее как этого избежать? И как мог вообще работать механизм Package, учитывая, что в примере Qt есть та же проблема, что и отмеченная выше?

import QtQuick 2.0
import QtQml.Models 2.1

Rectangle {
    width: 300; height: 400

    ListModel {
        id: myModel
        ListElement { display: "One" }
        ListElement { display: "Two" }
        ListElement { display: "Three" }
    }
    DelegateModel {
        id: visualModel
        model: myModel
        delegate:
          Package {
            Rectangle { id: rectA;
              width: 40; height: 25; Package.name: 'pkgA'
            }
            Rectangle { id: rectB;
              width: 40; height: 25; Package.name: 'pkgB'
            }
            Rectangle {
                id: wrapper
                width: parent.width; // ERROR HERE: parent is sometimes null!
                height: 25
                color: 'lightsteelblue'
                state: 'state1'
                states: [
                    State {
                        name: 'state1'
                        ParentChange {
                            target: wrapper; parent: rectB
                            width: rectB.width; height: rectB.height // **CAUSES ERROR**
                        }
                    }
                ]
                Component.onCompleted: {
                  console.log("wrapper onCompleted: parent is",parent);
                }
                onParentChanged: {
                  console.log("wrapper parent changed to",parent);
                }
            }
          }
    }
    ListView {
        width: 300; height: 200
        model: visualModel.parts.pkgA
    }
    ListView {
        width: 300; height: 200
        model: visualModel.parts.pkgB
    }
}

1 Ответ

0 голосов
/ 07 мая 2020

Хорошо, наконец-то разобрался. Вы начинаете с этого:

width: parent.width

, которое является выражением привязки Qt. Он будет обновляться при изменении parent или parent.width. И когда сначала создается wrapper Rectangle, parent начинается правильно как null - у него еще нет визуального родителя.

Но затем вы выполняете ParentChange следующим образом:

    ParentChange {
        target: wrapper; parent: rectB
        width: rectB.width; height: rectB.height // **CAUSES ERROR**
    }

Назначение width в ParentChange удаляет вашу предыдущую привязку и помещает на нее новую ширину rectB.width. Вот почему консольный вход в исходную привязку перестает срабатывать на этом этапе. Эта привязка была удалена.

Итак, в итоге, вы неправильно интерпретируете то, что происходит. Родитель - это null для начала с и устанавливается через начальное значение state перед срабатыванием Component.onCompleted. Затем, когда вы выполняете ParentChange, вы стираете исходную привязку, поэтому отладка, через которую вы прошли, вводила в заблуждение.

Итак, вернемся к исходному вопросу, чтобы остановить ошибку, просто удалите width и height привязок в целом из wrapper и пусть ParentChange применяет те из них, которые не будут вызывать ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...