Свойства модели доступа QML TableView из делегата

У меня есть TableView, для которого я определил свой собственный itemDelegate. Теперь из этого делегата я могу получить доступ к значению для столбца с помощью styleData.значение, но мне также нужно получить доступ к другим свойствам в этом же элементе, но я не могу найти, как это сделать.

Мне это нужно, потому что стиль текста должен изменяться в зависимости от какого-либо другого свойства модели элемента.

какие идеи? спасибо!

3 ответов


отсутствует некоторая документация. В делегате элемента вы можете получить доступ к следующему (взято из код TreeView.qml):

  • styleData (документации)
  • model (в настоящее время не документированы)
  • modelData (в настоящее время не документировано, не уверен в этом, но я думаю, что это похоже на ListView)

(кстати, что также отсутствует в документации но что полезно styleData.role. Кроме того, в документации других делегатов также отсутствуют некоторые доступные свойства; лучше всего заглянуть в исходный код файла QML и найти элемент Loader, который создает экземпляр вашего делегата. Плюс в том, что ты узнаешь, как это работает. ;))

С model и информация о строке / столбце вы можете перейти к данным элемента. Этот код зависит от типа модели.

если вы используете QML ListModel, тогда вы можете использовать model.get: model.get(styleData.row)[styleData.role] должен работать (непроверенный, так как я использую его редко, пожалуйста, дайте обратную связь).

если вы используете C++ QAbstractItemModel или friends, лучше всего добавить слот в класс модели, который принимает только имя строки и роли, так как это информация TableView работает с (ни с номерами ролей ни со столбцами...).

в обоих случаях вы не должны использовать выражения в привязка собственности! Система уведомлений не будет работать, так как вы не используете систему свойств для доступа к данным. По вашему вопросу, я думаю, вы хотели использовать его в выражении с привязкой. Я не знаю, как правильно слушать изменения в модель вручную.

альтернативным подходом является доступ к другим элементам строки и предоставление свойства там. Некоторые подсказки:

  • из одного элемента, вы можете получить доступ к другим пунктам одна и та же строка, дважды пройдя дерево объектов вверх (сначала к загрузчику, который создает экземпляр вашего компонента, затем к фактической строке), а затем вниз (сначала к конкретному дочернему объекту, который является загрузчиком, а затем к его экземпляру). Вам нужно знать номер столбца, к которому вы хотите получить доступ (а не имя роли), я предполагаю, что вы хотите получить доступ к первому столбцу (индекс 0):

    parent.parent.children[0].item
    
  • вы можете предоставить данные модели, используя свойство в каждом элементе. Предполагая простой текст элемент это может быть:

    Text {
        property variant value: styleData.value // <-- Here you make it available
    
        // your other stuff
    }
    

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

// (within TableView)
itemDelegate: Text {
    property variant value: styleData.value
    text: styleData.value
    color: (styleData.column == 1 && parent.parent.children[0].item.value === 0)
            "red" : "black"
}

Я думаю, что это довольно легко, если Вы читаете исходный код TableViewItemDelegateLoader.qml (это частный код в qtquickcontrol)
для доступа к любой используемой роли используйте:model[your_role_name] .

для exp:model["comment"]


столкнувшись с той же проблемой сегодня, это результат моих исследований (Qt 5.2.x)

если у вас есть жесткий предел TableView, есть только одно правильное решение-используйте model.get(styleData.row)["roleForStyling"] Как написал @leemes. Но это будет очень медленно, если у вас большой объем данных в модели и использование, например, прокси-модели для сортировки / фильтрации.

прямое решение от @leemes ответ отличный, но в общем случае не работает, потому что в TableView любой Item завернут в Loader и поэтому независимый от родителя и других деталей:

  • когда создается какой-либо элемент (где вы хотите изменить стиль текста) другой элемент (от которого получить идентичность) еще не может быть создано
  • у вас может не быть "родителя" при создании элемента (т. е. привязка будет быть разбитым)

в моем случае лучшим решением для глубокой настройки было создание простой оболочки для ListView. В этом случае вы иметь доступ к полным данным строк в делегате без накладных расходов. Основные моменты для создания компонента ("мой собственный ListView как таблица"):

  • создать автономный заголовка (Rectangle или Item) - Не используйте форму заголовка ListView.Это делает его фиксированным для любого объема данных.
  • обертывание ListView до ScrollView (если вам нужны полосы прокрутки)
  • использовать Clip: true свойство в списке для make correct
  • установить стиль для highlight и set highlightFollowsCurrentItem:true на ListView

в качестве бонуса в будущем это может быть использовано для создания "TreeTable":)