•
•
•
•
Давайте начнем с класса
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
10 };
Каждая вершина имеет тип, строку (которая может быть пустой), ссылку на родительский элемент (которая может быть нулевой) и список дочерних вершин (который может быть пустым).
01 Node::Node(Type type, const QString &str)
02 {
03 this->type = type;
04 this->str = str;
05 parent = 0;
06 }
Конструктор просто инициализирует тип и строку вершины. Поскольку все данные открыты, в программном коде, использующим
01 Node::~Node()
02 {
03 qDeleteAll(children);
04 }
Функция
Теперь, когда мы определили элементы наших данных (представленные вершиной
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 };
На этот раз мы построили подкласс на основе класса
01 RegExpModel::RegExpModel(QObject *parent)
02 : QAbstractItemModel(parent)
03 {
04 rootNode = 0;
05 }
В конструкторе модели нам надо просто задать корневой вершине безопасное нулевое значение и передать указатель
01 RegExpModel::~RegExpModel()
02 {
03 delete rootNode;
04 }
В деструкторе мы удаляем корневую вершину. Если корневая вершина имеет дочерние вершины, то каждая из них удаляется и эта процедура повторяется рекурсивно деструктором
01 void RegExpModel::setRootNode(Node *node)
02 {
03 delete rootNode;
04 rootNode = node;
05 reset();
06 }