Могут ли два объекта QStandardItem обрабатывать разные атрибуты одного и того же объекта?

Я новичок в программировании модели/представления Qt и прочитал Пример модели редактируемого дерева в документации Qt. Хорошая особенность в этом примере заключается в том, что один объект (TreeItem) инкапсулирует две части информации, которые позже отображаются в одной строке, содержащей два столбца (name и description) благодаря переопределению QModelIndex QAbstractItemModel::index и QVariant QAbstractItemModel::data.

Теперь у меня также есть пользовательский класс (например, Foo), содержащий две части информации (Foo::m_name и Foo::m_description), которые я хочу отобразить в одной строке, содержащей два столбца, но вместо подкласса QAbstractItemModel я хочу создать подкласс QStandardItemModel, потому что в нем много функциональность. Однако кажется, что я должен создать два объекта QStandardItem для каждого из моих объектов Foo, один для обработки m_name, а другой для обработки m_description. Как я могу сохранить один объект Foo в памяти и сделать так, чтобы эти два объекта QStandardItem ссылались на него?

В моем вопросе есть неявное предположение, что нужно создать объект QStandardItem для каждой пары (строка, столбец). Пожалуйста, дайте мне знать, если это неправильно.


person jmborr    schedule 22.02.2017    source источник


Ответы (2)


QStandardItemModel предназначен для хранения данных в модели, поэтому каждая ячейка представлена ​​QStandardItem, которая содержит данные этой ячейки.

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

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

person Kevin Krammer    schedule 22.02.2017
comment
Я объявил Q_DECLARE_METATYPE(Foo *) и сохранил QVariant<Foo *> в QStandardItem, чтобы не хранить объект Foo. Тем не менее, это по-прежнему приводило к тому, что мне приходилось создавать два объекта QStandardItem для каждого объекта Foo, и я надеялся, что есть какое-то обходное решение. - person jmborr; 22.02.2017
comment
Как я уже сказал: QStandardItemModel использует один QStandardItem на ячейку в качестве принципа конструкции. Его вариант использования заключается в хранении данных в модели, а не в качестве интерфейса для данных, хранящихся в другом месте. - person Kevin Krammer; 23.02.2017

Сообщение в qtcentre предложило главу 4 Advanced Qt Программирование и, о чудо, обсуждается подкласс дерева QstandardItemModel и QStandardIteml, где каждая строка дерева состоит из трех QstandardItem, обрабатывающих разные свойства одного объекта. Исходный код реализации бесплатно доступен.

В основном, у него есть:

class myItem : public QStandardItem {
public:
  myItem(Foo &afoo) : QStandardItem(afoo.getName()), m_foo(afoo) {
    m_description = new QStandardItem(afoo.getDescription());
    }
  QstandardItem *m_description; // display m_description
private:
  Foo &m_foo;    
};

а затем мы вставляем строку из двух QstandardItem в наше дерево модели

class myModel: public QStandardItemModel {

  StandardItem *myModel::appendRow(QStandardItem *parent, Foo &afoo)
  {
      auto *doublet = new myItem(afoo);
      parent->appendRow(QList<QStandardItem*>() << doublet
              << double->m_description);
      return nameItem;  
  }
}
person jmborr    schedule 22.02.2017