Является QAbstractListModel
реализация с скажем роли
name, image, enabled, color, editable
Лучше, чем реализация с одной ролью (простите, что я не могу придумать лучшего имени)
thing
что вызывает QObject*
с вышеупомянутым Q_PROPERTY
должны быть возвращены?
Разница на стороне QML будет дополнительной «косвенностью» при доступе к значениям, скажем, делегата:
model.thing.name
против
model.name
Я склоняюсь к подходу QObject, потому что он отделяет представление данных от модели списка и имеет потенциал для повторного использования. Это также не требует от вас также реализовать setData
функция. Насколько я могу судить, для опции «много ролей» нет конкретных «за», если, конечно, невозможно правильно определить правильное QObject
подкласс обертывания данных (потому что, например, это может иметь мало смысла концептуально для конкретных случаев).
Наличие ролей в модели полезно, если вы хотите использовать ее с функциями, основанными на ролях.
Например, вы хотите передать свою модель ComboBox
Если у него есть роли, вы можете просто указать textRole
к ComboBox
и он сделает свое дело. При использовании одной роли объекта вам придется изменить делегат, чтобы отобразить правильное свойство объекта.
Роли также необходимы, если вы хотите использовать ListView
особенность раздела.
Как сказал @derm, это также полезно с QSortFilterProxyModel
(бесстыдный плагин: если у вашей модели есть роли, ее очень легко отфильтровать или отсортировать SortFilterProxyModel
библиотека).
Вы упомянули возможность повторного использования и необходимость переопределять вещи. Это хороший момент, но вполне выполнимо иметь общую модель с ролями, основанными на QObject
свойства.
Фактически это было сделано, и это доступно с очень допустимой лицензией здесь: Томас Бутруэ QQmlObjectListModel
. Начиная с c ++ он имеет тот же API, что и QList
но это подвергает QAbstractListModel
это можно использовать в QML.
Роли основаны на свойствах ваших объектов, и когда выдается сигнал уведомления, он испускает соответствующий dataChanged
сигнал. insertRows
и друзья также обрабатываются автоматически.
С учетом сказанного, я не вижу особого смысла в создании модели с одной ролью объекта. Если вы хотите правильную модель с rowsInserted
/rowRemoved
сигналы (и вы должны, если у вас есть только статическая модель, в этом случае QVariantList
или QObjectList
достаточно), вам все равно придется реализовать это самостоятельно, когда вы можете просто использовать QQmlObjectListModel
и покончим с этим.
Использование ролей означает, что вы должны придерживаться предварительно определенной схемы модели.
Роли хороши, если ваши объекты находятся на низком уровне, поэтому вы можете выставлять различные члены объекта в качестве ролей.
Но в случае QObject *
модель, которая совершенно не нужна. Вы уже используете мета-объектную систему Qt, которая может облегчить ту же функциональность в сочетании с механизмом QML.
До тех пор, пока свойства правильно реализованы и имеют сигналы уведомления, все они будут бесперебойно работать в QML.
И это также значительно экономит время, так как модель является общей, и вы можете заполнить ее объектами, определенными в QML, без необходимости перекомпилировать код C ++ или иметь выделенную модель для каждой модели.
Имейте в виду, что QObject
Они довольно большие и представляют значительные накладные расходы, если у вас есть множество моделей. Если ваша модель огромна или вы имеете дело с уже существующим набором данных, который недоступен как QObject*
Из коробки будет более эффективно реализовать «классическую» модель с ролями и так далее.
Пока вы не столкнетесь с его ограничениями, я бы сказал, одну роль QObject*
Модель является более простым, легким, быстрым, более гибким и более элегантным решением.
Что касается упомянутой проблемы сортировки и фильтрации, стандартные решения, очевидно, не будут ее сокращать. Как уже упоминалось Вот, есть возможность реализовать сортировку и фильтрацию, которая использует функтор JS, в котором вы можете запускать свою собственную логику, которая, осмелюсь сказать, на самом деле лучше, чем функциональность, основанная на стандартной роли. И снова, вы можете получить новый код в нем без перекомпиляции, даже можно управлять им через функторы, сгенерированные во время выполнения.
Да, ты должен.
Наиболее фундаментальная причина использования ролей: Это способ написания моделей Qt.
Хорошо, эта причина ничего особенного не имеет — если только нет вещей, которые ожидают, что вы сделаете это Qt способом …
Итак, есть причины, по которым вам следует реализовывать роли, но это не значит, что вы должны использовать их в QML — и в зависимости от того, что вы планируете делать с вашей моделью, это будет ненужным.
На мой взгляд, самая важная причина заключается в том, что вы должны реализовать это dataChanged
-сигнал. Если вы этого не сделаете, ваша модель стоит столько же, сколько QVariantList
,
Изменения свойств вашего объекта будут отражаться только в генерируемых делегатах, но в объектах, которые полагаются на dataChanged
-signal не будет получать обновления — если вы не активируете его для роли объекта, когда свойство этого объекта когда-либо изменилось.
Это, с другой стороны, будет иметь большое влияние на делегатов, так как все привязки должны быть переоценены.
Возьмите для примера QSortFilterProxyModel
— если у вас нет dataChanged
-signal, он не будет обновлять фильтр или сортировку, если значение было изменено, так как он прослушивает dataChanged
сигнал для этого.
Специально, я не знаю других случаев, которые бы использовали это из библиотек Qt, но могут быть и другие.
Однако, если вы не собираетесь использовать какой-либо из них — вам не нужно увольнять dataChanged
-сигнал.
Должны ли вы действительно выполнять роли для этого, я не знаю. Я не пытался реализовать dataChanged
-сигнал без ролей.
Код QSortFilterProxyModel, который использует dataChanged
-сигнал
Вам не нужно
Когда вы либо не используете ничего, что полагается на правильно реализованные роли, или вы переопределяете ту функциональность, которая будет зависеть от ролей, которые вы сами.