Чтение онлайн

на главную - закладки

Жанры

QT 4: программирование GUI на С++

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

Шрифт:

RegExpParser формирует дерево грамматического разбора для заданного регулярного выражения;

RegExpModel — модель дерева, используемая деревом грамматического разбора;

Node (вершина) представляет один элемент в дереве грамматического разбора.

Давайте начнем с класса Node:

01 class Node {

02 public:

03 enum Type { RegExp, Expression, Term, Factor, Atom, Terminal };

04 Node(Type type, const QString &str = "");

05 ~Node;

06 Type type;

07 QString str;

08 Node *parent;

09 QList<Node *> children;

10 };

Каждая

вершина имеет тип, строку (которая может быть пустой), ссылку на родительский элемент (которая может быть нулевой) и список дочерних вершин (который может быть пустым).

01 Node::Node(Type type, const QString &str)

02 {

03 this->type = type;

04 this->str = str;

05 parent = 0;

06 }

Конструктор просто инициализирует тип и строку вершины. Поскольку все данные открыты, в программном коде, использующим Node, можно непосредственно манипулировать типом, строкой, родительским элементом и дочерними элементами.

01 Node::~Node

02 {

03 qDeleteAll(children);

04 }

Функция qDeleteAll проходит no всем указателям контейнера и вызывает оператор delete для каждого из них. Она не устанавливает указатели в 0, поэтому, если она используется вне деструктора, обычно за ней следует вызов функции clear для контейнера, содержащего указатели.

Теперь, когда мы определили элементы наших данных (представленные вершиной Node), мы готовы создать модель:

01 class RegExpModel : public QAbstractItemModel

02 {

03 public:

04 RegExpModel(QObject *parent = 0);

05 ~RegExpModel;

06 void setRootNode(Node *node);

07 QModelIndex index(int row, int column,

08 const QModelIndex &parent) const;

09 QModelIndex parent(const QModelIndex &child) const;

10 int rowCount(const QModelIndex &parent) const;

11 int columnCount(const QModelIndex &parent) const;

12 QVariant data(const QModelIndex &index, int role) const;

13 QVariant headerData(int section,

14 Qt::Orientation Orientation, int role) const;

15 private:

16 Node *nodeFromIndex(const QModelIndex &index) const;

17 Node *rootNode;

18 };

На этот раз мы построили подкласс на основе класса QAbstractItemModel, а не на основе его удобного подкласса QAbstractTableModel, потому что мы хотим создать иерархическую модель. Нам необходимо переопределить те же самые функции и, кроме того, требуется реализовать функции index и parent. Для

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

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.

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

Идеальный мир для Лекаря 26

Сапфир Олег
26. Лекарь
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 26

Я уже князь. Книга XIX

Дрейк Сириус
19. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я уже князь. Книга XIX

Камень. Книга восьмая

Минин Станислав
8. Камень
Фантастика:
фэнтези
боевая фантастика
7.00
рейтинг книги
Камень. Книга восьмая

Тринадцатый IV

NikL
4. Видящий смерть
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Тринадцатый IV

На границе империй. Том 10. Часть 1

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 1

Сирота

Шмаков Алексей Семенович
1. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Сирота

Земля под ногами. Из истории заселения и освоения Эрец Исраэль. 1918-1948. Книга 2

Кандель Феликс Соломонович
Научно-образовательная:
история
5.00
рейтинг книги
Земля под ногами. Из истории заселения и освоения Эрец Исраэль. 1918-1948. Книга 2

Слезы Эйдена 1

Владимиров Денис
11. Глэрд
Фантастика:
боевая фантастика
фэнтези
попаданцы
5.00
рейтинг книги
Слезы Эйдена 1

На границе империй. Том 4

INDIGO
4. Фортуна дама переменчивая
Фантастика:
космическая фантастика
6.00
рейтинг книги
На границе империй. Том 4

Бастард Императора. Том 13

Орлов Андрей Юрьевич
13. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Бастард Императора. Том 13

Черный Маг Императора 13

Герда Александр
13. Черный маг императора
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 13

Дважды одаренный

Тарс Элиан
1. Дважды одаренный
Фантастика:
альтернативная история
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Дважды одаренный

Форма жизни

Драу Михаэль
Фантастика:
боевая фантастика
киберпанк
7.62
рейтинг книги
Форма жизни

Камень. Книга пятая

Минин Станислав
5. Камень
Фантастика:
боевая фантастика
6.43
рейтинг книги
Камень. Книга пятая