Пользовательское представление с моделью и делегатом доступно из обоих файлов QML

Хотя я уже понял это, это заняло довольно много времени. Если вы знаете менее запутанное решение - поделитесь.

Я хотел бы предоставить обычай, который работает с любым типом (с произвольно названными полями):

  • model: 3
  • model: [ "red", "yellow", "green" ]
  • model: [ {color: "red"}, {color: "yellow"}, {color: "green"} ]
  • model: ListModel{ ListElement{color: "red"}; ListElement{color: "green"} }
  • подкласс QAbstractItemModel и тому подобное...

Для этого я решил предоставить property Component delegate этот пользователь будет заполнять визуальный Item который будет вставлен глубоко в мой .

Тем не менее View также необходимо получить доступ к некоторой информации из того же delegate потому что в противном случае это приведет либо к ненужному дублированию кода, либо к ненужной сложности прокси. model.

      MyView {
     mymodel: ["red", "blue"]
     mydelegate: Text {
         text: "color=" + modelData.name
         must_also_somehow_set_color_of_MyView_element_to: modelData.color
     }
}

... где MyView должно быть что-то вроде:

      Column {
    Repeater {
        model: mymodel
        delegate: Rectangle {
            color: somehow_get_color_from_mydelegate
            Text {} // <--- instantiate mydelegate here with data from mymodel
        }
    }
}

Сделать это кажется легко, но наивные попытки не сработали. Решение, опубликованное как ответ, помогло мне.

2 ответа

Я думаю, что вы действительно ищете загрузчик для создания экземпляра делегата, а не второй повторитель. Вы также можете немного упростить, используя псевдонимы. Попробуйте что-то вроде этого:

      Column {
    property alias mymodel: repeater.model
    property Component mydelegate

    Repeater {
        id: repeater
        delegate: Rectangle {
            width: childrenRect.width; height: childrenRect.height

            color: ( null !== loader.item
                     && undefined !== loader.item.bgcolor ) 
                     ? loader.item.bgcolor : "transparent"

            Loader {
                id: loader
                sourceComponent: myDelegate
            }
        }
    }
}

Хитрость в том, что то, что видно для or, содержит все, что видно для указанного, в том числе и .

Сказанное может быть использовано в качестве параметра для ListModel.append()создать ListModelс одним элементом.

Затем он может быть назначен как a для a, который будет загружать копию всех свойств контекста, которые QML обычно извлекает из элемента , включая index, modelDataа также modelсам.

После создания / срабатывает onItemAdded/ onObjectAddedсигнал, который можно использовать в качестве подсказки для получения ссылки на экземпляр '

Пользователя можно попросить предоставить рут propertyв котором будет храниться полученное/вычисленное значение, которое может быть использовано

В качестве альтернативы может содержать другой Repeaterили же Instantiatorи запросить другой delegateдля получения ценностей, в которых он сам нуждается. Или тип контейнера может инкапсулировать оба Viewданные и изображения Item.

Пример:

MyView.qml

      import QtQuick 2.0
import QtQml.Models 2.1
Column {
    property var mymodel
    property Component mydelegate

    Repeater {
        model: mymodel
        delegate: Rectangle {
            width: childrenRect.width; height: childrenRect.height

            //color: model.color //works if "mymodel" has role "color"
            property var myitem: null //this will hold instance of mydelegate
            color: ( null !== myitem
                     && undefined !== myitem.bgcolor ) 
                     ? myitem.bgcolor : "transparent" //reads property of mydelegate

            // <-- mydelegate will be injected here
            Repeater {
                delegate: mydelegate
                model: ListModel{
                    Component.onCompleted: append(model)
                }
                onItemAdded: myitem = item
                onItemRemoved: myitem = null
            }
        }
    }
}

UsageExamples.qml

      import QtQuick 2.0
import QtQuick.Window 2.0
Window{
    visible: true
    Row {
        spacing: 10

        MyView {
            mymodel: ListModel {
                ListElement{ name: "roses"; color: "red";   }
                ListElement{ name: "violets"; color: "blue";   }
            }
             mydelegate: Text {
                 text: name
                 property color bgcolor: model.color
             }
        }

        MyView {
             mymodel: [{name: "roses", color: "red"}, {name: "violets", color: "blue"}]
             mydelegate: Text {
                 text: modelData.name
                 property color bgcolor: modelData.color
             }
        }

        MyView {
             mymodel: ["red", "blue"]
             mydelegate: Text {
                 text: "color="+modelData
                 property color bgcolor: modelData
             }
        }

    }
}
Другие вопросы по тегам