14. Фреймворк представления структурированных данных

Содержание

14.1. Обзор фреймворка
14.2. Интерфейс модели дерева (gtk.TreeModel)  и хранение данных (gtk.*Store)
14.2.1. Введение
14.2.2. Создание объектов TreeStore и ListStore
14.2.3. Обращение к веткам в модели дерева
14.2.4. Добавление веток
14.2.5. Удаление веток
14.2.6. Управление данными веток
14.2.7. Поддержка протокола Python
14.2.8. Сигналы модели дерева
14.2.9. Сортировка веток в модели
14.3. Представление данных (gtk.TreeView)
14.3.1. Создание представления
14.3.2. Получение и настройка модели из представления
14.3.3. Установка свойств представления
14.4. Прорисовка ячеек (gtk.CellRenderer)
14.4.1. Обзор
14.4.2. Типы
14.4.3. Свойства
14.4.4. Атрибуты
14.4.5. Привязка произвольной функции к данным из ячейки
14.4.6. Разметка прорисованного текста (gtk.CellRendererText)
14.4.7. Редактирование текста в ячейках
14.4.8. Переключение активности в ячейках
14.4.9. Пример редактирования и активации ячеек
14.5. Представление колонок (gtk.TreeViewColumns)
14.5.1. Создание представления колонок
14.5.2. Управление прорисовкой
14.6. Манипуляции с представлениями
14.6.1. Управлениие колонками
14.6.2. Разворачивание и сворачивание дочерних веток
14.7. Сигналы представлений
14.8. Выбор ветки дерева (gtk.TreeSelection)
14.8.1. Введение
14.8.2. Режимы выбора
14.8.3. Получение выделенных элементов
14.8.4. Использование функций
14.8.5. Выделение и снятие выделения с элементов
14.9. Перетаскивание в представлениях
14.9.1. Реорганизация
14.9.2. Внешнее перетаскивание
14.9.3. Пример перетаскивания в представлении
14.10. Сортировка и фильтрация
14.10.1. Сортировка (gtk.TreeModelSort)
14.10.2. Фильтрация (gtk.TreeModelFilter)
14.11. Типовая модель дерева (gtk.GenericTreeModel)
14.11.1. Обзор типовой модели
14.11.2. Интерфейс
14.11.3. Добавление и удаление веток
14.11.4. Управление памятью
14.11.5. Другие интерфейсы
14.11.6. Применение типовой модели
14.12. Типовая прорисовка ячеек (gtk.GenericCellRenderer)

Виджет TreeView отображает списки и деревья. Он заменяет предыдущий набор виджетов для списков: CList, Tree и CTree более мощным и гибким набором объектов, использующих принцип Model-View-Controller (MVC) для предоставления следующих возможностей:

Конечно, все эти возможности появляются ценой более сложного набора объектов и интерфейсов, которые сначала кажутся огромными. В течении главы мы обьясним вам объекты и интерфейсы до понимания обычного использования. Более экзотичные вещи вы откроете сами.

Начнём с быстрой ознакомительной экскурсии по объектам и интерфейсам, а затем погрузимся в интерфейс TreeModel и предустановленные классы ListStore и TreeStore.

14.1. Обзор фреймворка

Виджет TreeView это объект пользовательского интерфейса, отображающий данные, сохранённые в объекте TreeModel. Два базовых класса TreeModel предоставляются в PyGTK 2.0:

  • TreeStore, который предоставляет иерархическое хранилище данных, организованное в виде веток деревьев с данными в виде столбцов. Каждая ветка может иметь ноль или более веток. Одно условие: все ветки должны иметь одно число столбцов.
  • ListStore, который предоставляет хранилище данных, организованное в виде столбцов и строк, точно также, как и таблица в реляционной базе данных.  ListStore на самом деле упрощённая версия TreeStore, где ветки не имеют вложенных. Он может быть создан для предоставления более простого (и более эффективного) интерфейса для большого числа моделей данных.

Две дополнительные модели деревьев добавляются на базовую модель:

  • TreeModelSort, которая  предоставляет модель, где данные предыдущей модели сортируются.
  • TreeModelFilter, который  предоставляет модель, содержащую подмножество данных из предыдущей модели. Заметьте, что эта модель доступна только в PyGTK 2.4 и выше.

TreeView отображает все ветки TreeModel, но может отображать только лишь несколько столбцов. Также столбцы могут отображаться в ином порядке, чем они сохраняются в TreeModel.

TreeView использует объекты TreeViewColumn для организации отображения данных в столбцах. Каждый экземпляр TreeViewColumn отображает один столбец с опциональным заголовком. Такой экземпляр может содержать данные из различных столбцов TreeModel. Отдельные TreeViewColumn размещаются (как в контейнерах HBox) с объектами CellRenderer для отображения данных, связанных со столбцом TreeModel и положением столбца. Есть три предустановленных класса CellRenderer:

  • CellRendererPixbuf, который отображает картинки в ячейках  TreeViewColumn.
  • CellRendererText, который отображает строку в ячейке TreeViewColumn. Он переведёт данные столбца в строковый формат, если это необходимо, т.е. если в отображаемом столбце содержится дробное число, оно переведётся в строковый тип ещё до начала отображения.
  • CellRendererToggle, который отображает логическое значение как переключатель.

TreeViewColumn может содержать несколько объектов CellRenderer для предоставления столбца. Например, картинка и текст могут быть размещены вместе, в одном столбце, но храниться в разных полях модели.

Наконец, объекты TreeIter, TreeRowReference и TreeSelection предоставляют временный указатель на столбец в TreeModel, постоянный указатель на столбец в TreeModel и объект для управления выделением в TreeView.

Отображение TreeView состоит в использовании следующих основных операций, не обязательно в этом порядке:

  • Объект модели дерева обычно создаётся как  ListStore или TreeStore с одной или более колонкой указанного типа данных.
  • Модель дерева может быть заполнена одной или более веткой данных.
  • Виджет TreeView создаётся и связывается с моделью дерева.
  • Создаётся один или более TreeViewColumn и вставляется в TreeView. Каждый из них представляет один отображаемый столбец.
  • Для каждого TreeViewColumn создаётся один или более CellRenderer и добавляется в TreeViewColumn.
  • Атрибуты каждого CellRenderer устанавливаются для указания из какого столбца модели получаются данные. Например текст для отображения. Это позволяет CellRenderer отображать каждый столбец по своему.
  • TreeView вставляется и отображается в Window или ScrolledWindow.
  • Данные в модели дерева управляются программно, в ответ на действия пользователя. TreeView автоматически следит за изменениями.

Пример basictreeview.py показывает создание и отображение простого TreeView:

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # example basictreeview.py
  4.  
  5. import pygtk
  6. pygtk.require('2.0')
  7. import gtk
  8.  
  9. class BasicTreeViewExample:
  10.  
  11. # Закрываем окно и выходим
  12. def delete_event(self, widget, event, data=None):
  13. gtk.main_quit()
  14. return False
  15.  
  16. def __init__(self):
  17. # Создаём новое окно
  18. self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
  19.  
  20. self.window.set_title("Пример основ TreeView")
  21.  
  22. self.window.set_size_request(200, 200)
  23.  
  24. self.window.connect("delete_event", self.delete_event)
  25.  
  26. # Создаём TreeStore с одним строковым столбцом
  27. self.treestore = gtk.TreeStore(str)
  28.  
  29. # мы добавим немного данных - 4 ветки с 3мя дочерними в каждой
  30. for parent in range(4):
  31. piter = self.treestore.append(None, ['родитель %i' % parent])
  32. for child in range(3):
  33. self.treestore.append(piter, ['дитя %i родителя %i' %
  34. (child, parent)])
  35.  
  36. # Создаём TreeView используя TreeStore
  37. self.treeview = gtk.TreeView(self.treestore)
  38.  
  39. # создаём TreeViewColumn для отображения данных
  40. self.tvcolumn = gtk.TreeViewColumn('Столбец 0')
  41.  
  42. # добавляем tvcolumn к treeview
  43. self.treeview.append_column(self.tvcolumn)
  44.  
  45. # создаём CellRendererText для отображения данных
  46. self.cell = gtk.CellRendererText()
  47.  
  48. # добавляем cell к tvcolumn и позволяем открываться
  49. self.tvcolumn.pack_start(self.cell, True)
  50.  
  51. # устанавливаем cell атрибут "text" для колонки 0 - получаем текст
  52. # из колонки в treestore
  53. self.tvcolumn.add_attribute(self.cell, 'text', 0)
  54.  
  55. # делаем доступным поиск
  56. self.treeview.set_search_column(0)
  57.  
  58. # Позволяем сортировку столбца
  59. self.tvcolumn.set_sort_column_id(0)
  60.  
  61. # Позволяем менять порядок столбцов перетаскиванием
  62. self.treeview.set_reorderable(True)
  63.  
  64. self.window.add(self.treeview)
  65.  
  66. self.window.show_all()
  67.  
  68. def main():
  69. gtk.main()
  70.  
  71. if __name__ == "__main__":
  72. tvexample = BasicTreeViewExample()
  73. main()
  74.  

В настоящей программе TreeStore будет наполняться данными пользовательскими действиями после отображения TreeView. Мы рассмотрим детали интерфейсов TreeView более подробно в следующих разделах.

Рисунок 14.1, “Пример основ отображения структурированных данных” показывает окно, создаваемое программой basictreeview.py после открытия нескольких веток.

Рисунок 14.1. Пример основ отображения структурированных данных

Basic TreeView Example Program

Теперь давайте рассмотрим интерфейс TreeModel, и модели реализующие его.