Вход/Регистрация
QT 4: программирование GUI на С++
вернуться

Саммерфилд Марк

Шрифт:

01 RegExpModel::RegExpModel(QObject *parent)

02 : QAbstractItemModel(parent)

03 {

04 rootNode = 0;

05 }

В конструкторе модели нам надо просто задать корневой вершине безопасное нулевое значение и передать указатель parent базовому классу.

01 RegExpModel::~RegExpModel

02 {

03 delete rootNode;

04 }

В деструкторе мы удаляем корневую вершину. Если корневая вершина имеет дочерние вершины, то каждая из них удаляется и эта процедура повторяется рекурсивно деструктором Node.

01 void RegExpModel::setRootNode(Node *node)

02 {

03 delete rootNode;

04 rootNode = node;

05 reset;

06 }

При установке новой корневой вершины мы начинаем с удаления предыдущей корневой вершины (и всех ее дочерних вершин). Затем мы устанавливаем новое значение для корневой вершины и вызываем функцию reset для уведомления всех представлений о необходимости обновления отображаемых данных всеми видимыми элементами.

01 QModelIndex RegExpModel::index(int row, int column,

02 const QModelIndex &parent) const

03 {

04 if (!rootNode)

05 return QModelIndex;

06 Node *parentNode = nodeFromIndex(parent);

07 return createIndex(row, column, parentNode->children[row]);

08 }

Функция index класса QAbstractItemModel переопределяется. Она всегда вызывается, когда в модели или в представлении требуется создать индекс QModelIndex для конкретного дочернего элемента (или для элемента самого верхнего уровня, если parent имеет недействительное значение QModelIndex). В табличных и списковых моделях нам не требуется переопределять эту функцию, потому что обычно оказываются достаточным реализации по умолчанию моделей QAbstractListModel и QАЬstractTableModel.

В нашей реализации index, если не задано дерево грамматического разбора, мы возвращаем недействительный индекс QModelIndex. В противном случае мы создаем QModelIndex с заданными строкой, столбцом и Node * для запрошенного дочернего элемента. В иерархических моделях знание строки и столбца элемента относительно своего родителя оказывается недостаточным для уникальной идентификации элемента; мы должны также знать, кто является его родителем. Для этого можно хранить в QModelIndex указатель на внутреннюю вершину. В объекте QModelIndex кроме номеров строк и столбцов допускается хранение указателя void * или значения типа int.

Указатель Node * на дочерний элемент можно получить из списка дочерних элементов children родительской вершины. Указатель на родительскую вершину извлекается из индекса модели parent, используя закрытую функцию nodeFromIndex:

01 Node *RegExpModel::nodeFromIndex(

02 const QModelIndex &index) const

03 {

04 if (index.isValid) {

05 return static_cast<Node *>(index.internalPointer);

06 } else {

07 return rootNode;

07 }

Функция nodeFromIndex приводит тип void * заданного индекса в тип Node * или возвращает указатель на корневую вершину, если индекс недостоверен, поскольку недостоверный индекс модели используется для представления корня модели.

01 int RegExpModel::rowCount(const QModelIndex

02 &parent) const

03 {

04 Node *parentNode = nodeFromlndex(parent);

05 if (!parentNode)

06 return 0;

07 return parentNode->children.count;

08 }

Число строк для заданного элемента определяется просто количеством дочерних элементов.

01 int RegExpModel::columnCount(const QModelIndex &

02 /* родительский элемент */) const

03 {

04 return 2;

05 }

Число столбцов фиксировано и равно 2. Первый столбец содержит типы вершин; второй столбец содержит значения вершин.

01 QModelIndex RegExpModel::parent(const QModelIndex

02 &child) const

03 {

04 Node*node = nodeFromIndex(child);

05 if (!node)

06 return QModelIndex;

07 Node *parentNode = node->parent;

  • Читать дальше
  • 1
  • ...
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: