Свойства модели доступа 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
и sethighlightFollowsCurrentItem:true
наListView
в качестве бонуса в будущем это может быть использовано для создания "TreeTable":)