Виджеты дерева, списка и сетки значков
- Обзор виджетов дерева и списка
- GtkTreeModel — Интерфейс дерева, используемый GtkTreeView
- GtkTreeSelection — Объект выделения для GtkTreeView
- GtkTreeViewColumn — Видимый столбец в виджете GtkTreeView
- GtkTreeView — Виджет для отображения деревьев и списков
- Перетаскивание GtkTreeView — Интерфейсы для поддержки перетаскивания в GtkTreeView
- GtkCellView — Виджет, отображающий одну строку GtkTreeModel
- GtkIconView — Виджет, отображающий список значков в сетке
- GtkTreeSortable — Интерфейс сортируемых моделей, используемых GtkTreeView
- GtkTreeModelSort — GtkTreeModel, делающий основную модель дерева сортируемой
- GtkTreeModelFilter — GtkTreeModel, скрывающий части основной модели дерева
- GtkCellLayout — Интерфейс для размещения ячеек
- GtkCellArea — Абстрактный класс для размещения GtkCellRenderers
- GtkCellAreaBox — Область ячеек, отображающая GtkCellRenderers в строке или столбце
- GtkCellAreaContext — Хранит геометрическую информацию для серии строк в GtkCellArea
- GtkCellRenderer — Объект для рендеринга отдельной ячейки
- GtkCellEditable — Интерфейс для виджетов, которые могут использоваться для редактирования ячеек
- GtkCellRendererAccel — Отображает комбинацию клавиш в ячейке
- GtkCellRendererCombo — Отображает раскрывающийся список в ячейке
- GtkCellRendererPixbuf — Отображает pixbuf в ячейке
- GtkCellRendererProgress — Отображает числа в виде полос прогресса
- GtkCellRendererSpin — Отображает спин-кнопку в ячейке
- GtkCellRendererText — Отображает текст в ячейке
- GtkCellRendererToggle — Отображает переключатель в ячейке
- GtkCellRendererSpinner — Отображает анимацию вращения в ячейке
- GtkListStore — Структура данных, похожая на список, которая может использоваться с GtkTreeView
- GtkTreeStore — Структура данных, похожая на дерево, которая может использоваться с GtkTreeView
Для создания дерева или списка в GTK используйте интерфейс GtkTreeModel в сочетании с виджетом GtkTreeView. Этот виджет разработан по принципу Модель/Представление/Контроллер и состоит из четырёх основных частей:
Виджет представления дерева (GtkTreeView)
Столбец представления (GtkTreeViewColumn)
Рендереры ячеек (GtkCellRenderer и т.д.)
Интерфейс модели (GtkTreeModel)
Представление состоит из первых трёх объектов, а последним является Модель. Одним из основных преимуществ архитектуры MVC является возможность создания нескольких представлений для одной модели. Например, можно создать модель, отображающую файловую систему, для файлового менеджера. Можно создать множество представлений для отображения различных частей файловой системы, но в памяти нужно хранить только один экземпляр модели.
Цель рендереров ячеек — обеспечить расширяемость виджета и предоставить различные способы отображения одного и того же типа данных. Например, рассмотрите, как отобразить булеву переменную. Нужно ли отображать её как строку "“True”" или "“False”", "“Вкл”" или "“Выкл”", или нужно ли отображать её как флажок?
Создание модели
GTK предоставляет две простые модели: GtkListStore и GtkTreeStore. GtkListStore используется для моделирования списков, а GtkTreeStore — для моделирования деревьев. Разработать новый тип модели возможно, но существующих моделей должно быть достаточно для всех, кроме самых специализированных ситуаций. Создание модели достаточно
GtkListStore *store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
Это создаёт хранилище списка с двумя столбцами: столбцом строк и столбцом булевых значений. Обычно число 2 никогда не передаётся непосредственно; обычно создаётся перечисление, в котором перечисляются различные столбцы, за которым следует маркер, представляющий общее количество столбцов. Следующий пример продемонстрирует это, используя вместо хранилища списка хранилище дерева. Создание хранилища дерева происходит практически так же.
enum
{
TITLE_COLUMN,
AUTHOR_COLUMN,
CHECKED_COLUMN,
N_COLUMNS
};
GtkTreeStore *store = gtk_tree_store_new (N_COLUMNS, /* Total number of columns */
G_TYPE_STRING, /* Book title */
G_TYPE_STRING, /* Author */
G_TYPE_BOOLEAN); /* Is checked out? */
Добавление данных в модель выполняется с помощью gtk_tree_store_set() или gtk_list_store_set(), в зависимости от типа созданной модели. Для этого необходимо получить GtkTreeIter. Итератор указывает на место, куда будут добавлены данные.
После получения итератора используется gtk_tree_store_set() для применения данных к части модели, на которую указывает итератор. Рассмотрим следующий пример:
GtkTreeIter iter;
gtk_tree_store_append (store, &iter, NULL); /* Acquire an iterator */
gtk_tree_store_set (store, &iter,
TITLE_COLUMN, "The Principle of Reason",
AUTHOR_COLUMN, "Martin Heidegger",
CHECKED_COLUMN, FALSE,
-1);
Обратите внимание, что последний аргумент равен -1. Это всегда делается, так как это функция с переменным числом аргументов, и ей необходимо знать, когда прекратить обработку аргументов. Она может быть использована для задания данных в любой или во всех столбцах в заданной строке.
Третий аргумент в gtk_tree_store_append() — это итератор родительского элемента. Он используется для добавления строки в GtkTreeStore в качестве дочерней строки существующей строки. Это означает, что новая строка будет отображаться только при отображении родительской строки и в раскрытом состоянии. Рассмотрим следующий пример:
GtkTreeIter iter1; /* Parent iter */
GtkTreeIter iter2; /* Child iter */
gtk_tree_store_append (store, &iter1, NULL); /* Acquire a top-level iterator */
gtk_tree_store_set (store, &iter1,
TITLE_COLUMN, "The Art of Computer Programming",
AUTHOR_COLUMN, "Donald E. Knuth",
CHECKED_COLUMN, FALSE,
-1);
gtk_tree_store_append (store, &iter2, &iter1); /* Acquire a child iterator */
gtk_tree_store_set (store, &iter2,
TITLE_COLUMN, "Volume 1: Fundamental Algorithms",
-1);
gtk_tree_store_append (store, &iter2, &iter1);
gtk_tree_store_set (store, &iter2,
TITLE_COLUMN, "Volume 2: Seminumerical Algorithms",
-1);
gtk_tree_store_append (store, &iter2, &iter1);
gtk_tree_store_set (store, &iter2,
TITLE_COLUMN, "Volume 3: Sorting and Searching",
-1);
Создание компонента представления
Несмотря на то, что доступно несколько различных моделей, для работы есть только один виджет представления. Он работает с хранилищем списков или деревьев. Настройка GtkTreeView не представляет сложности. Ему необходима GtkTreeModel, чтобы знать, где получать данные.
GtkWidget *tree; tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
Столбцы и рендереры ячеек
После того, как виджет GtkTreeView получил модель, ему необходимо знать, как отображать модель. Это делается с помощью столбцов и рендереров ячеек.
Рендереры ячеек используются для отображения данных в модели дерева. GTK предоставляет несколько рендереров ячеек, включая GtkCellRendererText, GtkCellRendererPixbuf и GtkCellRendererToggle. Написание пользовательского рендера относительно просто.
GtkTreeViewColumn — это объект, который GtkTreeView использует для организации вертикальных столбцов в представлении дерева. Ему необходимо знать имя столбца для подписи пользователю, какой рендер ячейки использовать и какую часть данных извлекать из модели для данной строки.
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
renderer = gtk_cell_renderer_text_new (<!-- -->);
column = gtk_tree_view_column_new_with_attributes ("Author",
renderer,
"text", AUTHOR_COLUMN,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
На этом этапе все шаги по созданию отображаемого дерева были рассмотрены. Модель создана, данные в неё добавлены, создано представление дерева и добавлены столбцы.
Обработка выделения
Большинству приложений необходимо не только отображать данные, но и получать события ввода от пользователей. Для этого просто получите ссылку на объект выбора и подключитесь к сигналу “changed”.
/* Prototype for selection handler callback */
static void tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data);
/* Setup the selection handler */
GtkTreeSelection *select;
select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
g_signal_connect (G_OBJECT (select), "changed",
G_CALLBACK (tree_selection_changed_cb),
NULL);
Затем для извлечения данных выбранной строки:
static void
tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data)
{
GtkTreeIter iter;
GtkTreeModel *model;
char *author;
if (gtk_tree_selection_get_selected (selection, &model, &iter))
{
gtk_tree_model_get (model, &iter, AUTHOR_COLUMN, &author, -1);
g_print ("You selected a book by s\n", author);
g_free (author);
}
}
Простой пример
Вот простой пример использования виджета GtkTreeView в контексте других виджетов. Он просто создаёт простую модель и представление и объединяет их. Обратите внимание, что модель никогда не заполняется данными — это оставлено в качестве упражнения для читателя. Более подробная информация об этом содержится в разделе GtkTreeModel.
enum
{
TITLE_COLUMN,
AUTHOR_COLUMN,
CHECKED_COLUMN,
N_COLUMNS
};
void
setup_tree (void)
{
GtkTreeStore *store;
GtkWidget *tree;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
/* Create a model. We are using the store model for now, though we
* could use any other GtkTreeModel */
store = gtk_tree_store_new (N_COLUMNS,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_BOOLEAN);
/* custom function to fill the model with data */
populate_tree_model (store);
/* Create a view */
tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
/* The view now holds a reference. We can get rid of our own
* reference */
g_object_unref (G_OBJECT (store));
/* Create a cell render and arbitrarily make it red for demonstration
* purposes */
renderer = gtk_cell_renderer_text_new (<!-- -->);
g_object_set (G_OBJECT (renderer),
"foreground", "red",
NULL);
/* Create a column, associating the "text" attribute of the
* cell_renderer to the first column of the model */
column = gtk_tree_view_column_new_with_attributes ("Author", renderer,
"text", AUTHOR_COLUMN,
NULL);
/* Add the column to the view. */
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
/* Second column.. title of the book. */
renderer = gtk_cell_renderer_text_new (<!-- -->);
column = gtk_tree_view_column_new_with_attributes ("Title",
renderer,
"text", TITLE_COLUMN,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
/* Last column.. whether a book is checked out. */
renderer = gtk_cell_renderer_toggle_new (<!-- -->);
column = gtk_tree_view_column_new_with_attributes ("Checked out",
renderer,
"active", CHECKED_COLUMN,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
/* Now we can manipulate the view just like any other GTK widget */
...
}
© 2005–2020 The GNOME Project
Licensed under the GNU Lesser General Public License version 2.1 or later.
https://developer-old.gnome.org/gtk4/4.0/TreeWidgetObjects.html