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

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

Жанры

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.

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

Барон играет по своим правилам

Ренгач Евгений
5. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Барон играет по своим правилам

Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Клеванский Кирилл Сергеевич
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.51
рейтинг книги
Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Герцогиня в ссылке

Нова Юлия
2. Магия стихий
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Герцогиня в ссылке

Ну привет, заучка...

Зайцева Мария
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Ну привет, заучка...

На Ларэде

Кронос Александр
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
На Ларэде

Сердце Дракона. Том 12

Клеванский Кирилл Сергеевич
12. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.29
рейтинг книги
Сердце Дракона. Том 12

Истинная поневоле, или Сирота в Академии Драконов

Найт Алекс
3. Академия Драконов, или Девушки с секретом
Любовные романы:
любовно-фантастические романы
6.37
рейтинг книги
Истинная поневоле, или Сирота в Академии Драконов

Кодекс Охотника. Книга VI

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Сама себе хозяйка

Красовская Марианна
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Сама себе хозяйка

Душелов. Том 3

Faded Emory
3. Внутренние демоны
Фантастика:
альтернативная история
аниме
фэнтези
ранобэ
хентай
5.00
рейтинг книги
Душелов. Том 3

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

Стеллар. Заклинатель

Прокофьев Роман Юрьевич
3. Стеллар
Фантастика:
боевая фантастика
8.40
рейтинг книги
Стеллар. Заклинатель

Возвышение Меркурия. Книга 5

Кронос Александр
5. Меркурий
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 5