Должен ли я использовать много ролей или одну, откладывающую фактические свойства до QObject, оборачивая / выставляя данные в качестве его свойств - PullRequest
0 голосов
/ 27 июня 2018

Это QAbstractListModel реализация, скажем, с ролями

name, image, enabled, color, editable

Лучше, чем реализация с одной ролью (простите, что я не могу придумать лучшего имени)

thing

, что вызывает возврат QObject* с вышеупомянутыми Q_PROPERTY с?

Разницей на стороне QML будет дополнительная «косвенность» при доступе к значениям, скажем, делегата:

model.thing.name

против

model.name

Я склоняюсь к подходу QObject, потому что он отделяет представление данных от модели списка и имеет потенциал для повторного использования. Также не требуется, чтобы вы также реализовали функцию setData. Насколько я могу судить, для опции «много ролей» нет конкретных «за», если, конечно, невозможно правильно определить правильный подкласс QObject, обертывающий данные (потому что, например, это не имеет большого смысла концептуально для конкретных случаев).

Ответы [ 3 ]

0 голосов
/ 27 июня 2018

Использование ролей означает, что вы должны придерживаться предварительно определенной схемы модели.

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

Но в случае модели QObject * это совершенно не нужно. Вы уже используете мета-объектную систему Qt, которая может упростить ту же функциональность в сочетании с механизмом QML.

До тех пор, пока свойства правильно реализованы и имеют сигналы уведомления, все они будут бесперебойно работать в QML.

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

Имейте в виду, что QObject довольно большие, и представляют значительные накладные расходы, если у вас есть множество моделей. Если ваша модель огромна или вы имеете дело с уже существующим набором данных, который недоступен в виде QObject* из коробки, будет более эффективно реализовать «классическую» модель с ролями и еще чем-то.

Пока вы не столкнетесь с ее ограничениями, я бы сказал, что модель на одну роль QObject* является более простым, легким, быстрым, более гибким и более элегантным решением.

Что касается упомянутой проблемы сортировки и фильтрации, стандартные решения, очевидно, не будут ее сокращать. Как уже упоминалось здесь , можно реализовать сортировку и фильтрацию с использованием функтора JS, в котором вы можете запускать свою собственную логику, которая, осмелюсь сказать, на самом деле лучше, чем функциональность, основанная на стандартной роли. И снова, вы можете получить новый код без перекомпиляции, даже можно управлять им через функторы, сгенерированные во время выполнения.

0 голосов
/ 28 июня 2018

Наличие ролей в модели полезно, если вы хотите использовать ее с функциями, основанными на ролях.

Например, вы хотите передать свою модель в ComboBox, если у нее есть роли, вы можете просто указать textRole для ComboBox, и она сделает свое дело. При использовании одной роли объекта вам придется изменить делегат, чтобы отобразить правильное свойство объекта. Роли также необходимы, если вы хотите использовать функцию секции ListView.

Как сказал @derm, это также полезно с QSortFilterProxyModel (бесстыдный плагин: если у вашей модели есть роли, ее очень легко отфильтровать или отсортировать с помощью моей SortFilterProxyModel библиотеки ).

Вы упомянули возможность повторного использования и необходимость переопределения вещей. Это хороший момент, но вполне возможно иметь общую модель с ролями, основанными на свойствах QObject. Фактически это было сделано, и это доступно с очень допустимой лицензией здесь: Томас Бутру QQmlObjectListModel. Из c ++ он имеет тот же API, что и QList, но он предоставляет QAbstractListModel, который может использоваться QML. Роли основаны на свойствах ваших объектов, и когда выдается сигнал уведомления, он испускает соответствующий сигнал dataChanged. insertRows и друзья также обрабатываются автоматически.

С учетом вышесказанного я не вижу особого смысла в создании модели с одной ролью объекта. Если вам нужна подходящая модель с сигналами rowsInserted / rowRemoved (и вам следует, если у вас нет статической модели, в данном случае достаточно QVariantList или QObjectList), вам придется реализовать в любом случае, если вы можете просто использовать QQmlObjectListModel и покончить с этим.

0 голосов
/ 27 июня 2018

Да, вы должны.

Наиболее фундаментальная причина использования ролей: Это способ написания моделей Qt.

Хорошо, эта причина ничего особенного не имеет, если только нет вещей, которые ожидают, что вы сделаете это Qt ...

Итак, есть причины, по которым вам следует реализовывать роли, но это не значит, что вы должны использовать их в QML - и в зависимости от того, что вы планируете делать с вашей моделью , это будет ненужным .

На мой взгляд, самая важная причина в том, что вы должны реализовать этот dataChanged -сигнал. Если вы этого не сделаете, ваша модель будет стоить столько же, сколько и QVariantList.

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

Возьмем, к примеру, QSortFilterProxyModel - если у вас нет сигнала dataChanged, он не будет обновлять фильтр или сортировку, если значение было изменено, так как он прослушивает dataChanged -сигнал за это.

Ad hoc, я не знаю других случаев, которые бы использовали это из библиотек Qt, но могут быть и другие.

Однако, если вы не собираетесь использовать ни один из них - вам не нужно запускать сигнал dataChanged.

Должны ли вы действительно выполнять роли для этого, я не знаю. Я не пытался реализовать сигнал dataChanged без ролей.

Код QSortFilterProxyModel, который использует dataChanged -сигнал


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

...