QT 4: программирование GUI на С++
вернуться

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

Шрифт:

08 if (!parentNode)

09 return QModelIndex;

10 Node *grandparentNode = parentNode->parent;

11 if (!grandparentNode)

12 return QModelIndex;

13 int row = grandparentNode->children.indexOf(parentNode);

14 return createIndex(row, child.column, parentNode);

15 }

Получить QModelIndex родительского элемента из дочернего немного сложнее, чем найти дочерний элемент родителя. Можно легко получить родительскую вершину, применяя сначала функцию nodeFromIndex и поднимаясь затем вверх с помощью указателя на родительский элемент, но для получения номера строки (позиции родительской верщины в соответствующем списке дочерних вершин) мы должны перейти к родителю родительского элемента и найти в его списке дочерних элементов значение индекса первого родителя (родителя исходной дочерней вершины).

01 QVariant RegExpModel::data(const QModelIndex

02 &index, int role) const

03 {

04 if (role != Qt::DisplayRole)

05 return QVariant;

06 Node *node = nodeFromIndex(index);

07 if (!node)

08 return QVariant;

09 if (index.column == 0) {

10 switch (node->type) {

11 case Node::RegExp:

12 return tr("RegExp");

13 case Node::Expression:

14 return tr("Expression");

15 case Node::Term:

16 return tr("Term");

17 case Node::Factor:

18 return tr("Factor");

19 case Node::Atom:

20 return tr("Atom");

21 case Node::Terminal:

22 return tr("Terminal");

23 default:

24 return tr("Unknown");

25 }

26 } else if (index.column == 1) {

27 return node->str;

28 }

29 return QVariant;

30 }

В функции data получаем для запрошенного элемента указатель Node * и используем его для получения доступа к данным соответствующей вершины. Если вызывающая программа запрашивает какую-нибудь роль, отличную от Qt::DisplayRole, или если не удается получить вершину Node для заданного индекса модели, мы возвращаем недействительное значение типа QVariant. Если столбец равен 0, возвращаем название типа вершины; если столбец равен 1, вбзвращаем значение вершины (ее строку).

01 QVariant RegExpModel::headerData(int section,

02 Qt::Orientation orientation, int role) const

03 {

04 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {

05 if (section == 0) {

06 return tr("Node");

07 else if (section == 1) {

08 return tr("Value");

09 }

10 }

11 return QVariant;

12 }

При переопределении функции headerData мы возвращаем соответствующие метки горизонтального заголовка. Класс QTreeView, который используется для визуального представления иерархических моделей, не имеет заголовков строк, поэтому мы их игнорируем.

Теперь, когда рассмотрены классы Node и RegExpModel, давайте посмотрим, как создается корневая вершина, когда пользователь изменяет текст в строке редактирования.

01 void RegExpWindow::regExpChanged(const QString&regExp)

02 {

03 RegExpParser parser;

04 Node *rootNode = parser.parse(regExp);

05 regExpModel->setRootNode(rootNode);

06 }

При изменении пользователем текста в строке редактирования вызывается слот главного окна regExpChanged. В этом слоте выполняется синтаксический анализ введенного пользователем текста, и парсер возвращает указатель на корневую вершину дерева грамматического разбора.

Мы не показываем класс RegExpParser, потому что он не имеет отношения к графическому интерфейсу или программированию модели/представления. Полный исходный код для этого примера находится на компакт-диске.

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

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

Private-Bookers - русскоязычная библиотека для чтения онлайн. Здесь удобно открывать книги с телефона и ПК, возвращаться к сохраненной странице и держать любимые произведения под рукой. Материалы добавляются пользователями; если считаете, что ваши права нарушены, воспользуйтесь формой обратной связи.

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

  • Моя полка

Контакты

  • help@private-bookers.win