Добавление некоторых пользовательских данных в модель дерева Qt - PullRequest
2 голосов
/ 04 июня 2009

Я новичок в использовании парадигмы модель / представление в Qt и имею следующую проблему: У меня есть древовидная структура, которая должна быть визуализирована через Qt. Я обнаружил, что QAbstractTableModel идеально подходит для моих нужд, поэтому я пишу следующее:

class columnViewModel : public QAbstractTableModel {
   // some stuff...
};

Теперь все работает, но теперь мне нужно реализовать шаблон проектирования «Наблюдатель» над узлами моего дерева. Когда узел расширяется в TreeView, я должен добавить наблюдателя к соответствующему узлу. Всякий раз, когда узел рушится, я должен удалить этого Наблюдателя из узла. Итак, я пишу что-то вроде этого:

void onExpand( const QModelIndex & Index ... ) {
   Node* myNode = static_cast<Node*>(Index->internalPointer());
   Observer* foo = Observer::create();
   myNode->addObserver(foo);

   // ok up to here, but now where can I save this Observer? I must associate 
   // it with the Node, but I cannot change the Node class. Is there any way 
   // to save it within the index?
}

void onCollapse( const QModelIndex & Index ... ) {
   Node* myNode = static_cast<Node*>Index->internalPointer();
   Observer* foo = // well, what should I write here? Node does not have anything 
                   // like "getObserver()"! Can I extract an Observer from Index?

   myNode->remObserver( foo );
}

У меня сейчас нет фрагментов, поэтому код может быть недействительным Qt, но проблема кажется ясной. Я не могу изменить ни Node, ни Observer. У меня может быть внутренний список Наблюдателей, но затем я должен решить, какой Обозреватель удалить из определенного узла. Есть ли способ сохранить указатель Observer в Index (возможно, некоторые пользовательские данные), чтобы быстро разрешить его в onCollapse? Любые идеи приветствуются ...

1 Ответ

7 голосов
/ 04 июня 2009

Выполните следующие действия:

  • Определите новую роль (аналогично Qt :: UserRole), скажем, ObserverRole.
  • Используйте QAbstractItemModel :: setData для установить наблюдателя как данные с роль наблюдателя. Эскиз кода:

    this-> model () -> setData (ObserverRole, QVariant :: fromValue (foo));

  • Возможно, вам потребуется поместить в файл реализации cpp объявление для метаданных, что-то вроде

    Q__DECLARE __METATYPE (Наблюдатель *);

, чтобы QVariant мог правильно выполнить приведение типов.

  • Вы можете получить наблюдателя для индекса, используя QModelIndex :: data с ролью Observer:

    index.data (ObserverRole);

  • В вашей реализации модели добавьте поддержку возврата данных для роли Observer, если таковая имеется (как вы, вероятно, делали для Qt :: UserRole или Qt :: DisplayRole.

Обновление полученного комментария:

Обычно QModelIndex :: data предоставляет данные для зрителя. Роль, указанная при запросе данных, позволяет настройщику модели предоставлять разные данные по разным причинам (например, предоставить строку для роли отображения -> заголовок элемента).

Если вы не используете этот механизм для получения данных, то вам, вероятно, не нужен QTreeView. В этом случае используйте QTreeWidget, где вы можете напрямую работать с QTreeWidgetItems и присоединять данные к элементу с помощью метода setData, либо создать подкласс QTreeWidgetItem и добавить данные в качестве члена этого подкласса.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...