GtkTreeView
К этому моменту мы рассмотрели несколько простых виджетов GTK+, но не все виджеты представляют собой однострочные инструменты для ввода или отображения. Сложность виджетов ничего не ограничивается, и GtkTreeView — яркий пример виджета, собравшего в себя огромный объем функциональных возможностей.
GObject
╰── GInitiallyUnowned
╰── GtkWidget
╰── GtkContainer
╰── GtkTreeView
GtkTreeView — член семейства виджетов, создающий представление данных в виде дерева или списка наподобие тех, которые вы можете встретить в электронной таблице или файловом менеджере. С помощью виджета GtkTreeView можно создать сложные представления данных, смешивая текст, растровую графику и даже данные вводимые с помощью виджетов GtkEntry, и т. д.
Самый быстрый способ испытания GtkTreeView — запуск приложения gtk3-demo, которое поставляется вместе с GTK+ 3. Демонстрационное приложение показывает возможности всех виджетов GTK+ 3, включая GtkTreeView (рис. 10.1)
Семейство GtkTreeView состоит из четырех компонентов:
GtkTreeView— отображение дерева или списка;GtkTreeViewColumn— представление столбца или дерева;GtkCellRenderer— управление отображаемыми ячейками;GtkTreeModel— представление данных дерева и списка.
Первые три компонента формируют так называемое Представление, а последний — Модель. Концепция разделения Представление и Модели (часто называемая проектным шаблоном модель/Представление/Действие (Model/View/Controller или сокращенно MVC) не свойственна GTK+, но проектированию уделяется все большее и большее внимание на всех этапах программирования.
Ключевое достоинство проектного шаблона MVC заключается в возможности одновременной визуализации данных в виде разных представлений без ненужного их дублирования. Например, текстовые редакторы могу иметь две разные панели и редактировать разные фрагменты документа без хранения в памяти двух копий документа.
Шаблон MVC также очень популярен в Web-программировании, поскольку облегчает создание Web-сайтов, которые визуализируются в мобильных или WAP-обозревателях не так, как в настольных, просто за счет наличия отдельных компонентов Представление, оптимизированных для Web-обозревателя каждого типа. Вы также можете отделить логику сбора данных, например, запросов к базе данных, от логики пользовательского интерфейса.
Мы начнем с рассмотрения компонента модель, представленного в GTK+ двумя типами. Объект типа GtkTreeStore содержит многоуровневые данные, например, иерархию каталогов, а объект GtkListStore предназначен для простых данных.
Для создания объекта GtkTreeStore в функцию передаётся количество столбцов, за которыми следуют типы всех столбцов:
GtkWidget *store = gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_BOOLEAN);
Чтение, вставка, редактирование и удаление из модели выполняется с помощью структур GtkTreeIter. Эти структуры итераторов указывают на узлы дерева (или строки списка) и помогают находить фрагменты структур данных потенциально очень большого объема, а также манипулировать ими. Есть несколько вызовов API для получения объекта-итератора для разных точек дерева, но мы рассмотрим простейшую функцию gtk_tree_store_append().
Перед тем как вставлять какие-либо данные в модель дерева, вам нужно получить итератор, указывающий на новую строку. Функция gtk_tree_store_append() заполняет объект GtkTreeIter, который представляет новую строку в дереве, как строку верхнего уровня (если вы передаете значение NULL в третьем аргументе), так и подчиненную или дочернюю строку (если вы передаете итератор главного или родительской строки):
GtkTreeIter iter;
gtk_tree_store_append(store, &iter, NULL);
Получив итератор, вы можете заполнять строку с помощью функции gtk_tree_store_set():
gtk_tree_store_set(store, &iter,
0, "Def Leppard",
1, 1987,
2, TRUE,
-1);
Номер столбца и данные передаются парами, которые завершаются -1. Позже вы примените тип enum для того, чтобы сделать номера столбцов более информативными.
Для того чтобы добавить ветвь к данной строке (дочернюю строку), вам нужен только итератор для дочерней строки, который вы получаете, вызвав снова функцию gtk_tree_store_append() и указав на этот раз в качестве параметра строку верхнего уровня:
GtkTreeIter child;
gtk_tree_store_append(store, &child, &iter);
Дополнительную информацию об объектах GtkTreeStore и функциях объекта GtkListStore см. в документации API:
Пойдём дальше и рассмотрим компонент Представление типа GtkTreeView.
Создание объекта GtkTreeView сама простота: только передайте в конструктор в качестве параметра модель типа GtkTreeStore или GtkListStore:
GtkWidget *view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
Сейчас самое время настроить виджет для отображения данных именно так, как вы хотите. Для каждого столбца следует определить 'GtkCellRenderer` и источник данных. Можно выбрать, например, визуализацию только определенных столбцов данных или изменить порядок вывода столбцов.
'GtkCellRenderer` — это объект, отвечающий за прорисовку каждой ячейки на экране, и существует три подкласса, имеющие дело с текстовыми ячейками, ячейками пиксельной графики и ячейками кнопок-выключателей:
GtkCellRendererText;GtkCellRendererPixBuf;GtkCellRendererToggle.
В вашем Представлении будет применено текстовое представление ячеек, GtkCellRendererText.
GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_insert_column_with_attributes(
GTK_TREE_VIEW (treeview),
0, "This is the column title", renderer,
"text", COLUMN_ITEM_NUMBER,
NULL);
Вы создаете представление ячейки и передаете его в функцию вставки столбца. Эта функция позволяет сразу задать свойства GtkCellRendererText, передавая заканчивающиеся значением NULL пары “ключ/значение”. В качестве параметров указаны представление дерева, номер столбца, заголовок столбца, представление ячейки и его свойства. В приведенном примере вы задаёте атрибут “text”, передав номер других атрибутов, включая подчеркивание, шрифт, размер и т. д.
В примере далее, выполнив необходимые шаги, вы увидите, как это работает на практике.
Пример: использование виджета GtkTreeView
Введите следующий программный код и назовите файл gtk_tree.c.
Примените тип
enumдля обозначения столбцов, чтобы можно было ссылаться на них по именам. Общее количество столбцов удобно обозначить какN_COLUMNS:#include <gtk/gtk.h> enum { COLUMN_TITLE, COLUMN_ARTIST, COLUMN_CATALOGUE, N_COLUMNS }; void closeApp(GtkWidget *window, gpointer data) { gtk_main_quit(); } int main(int argc, char *argv[]) { GtkWidget *window; GtkTreeStore *store; GtkWidget *view; GtkTreeIter parent_iter, child_iter; GtkCellRenderer *renderer; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Tree"); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 300, 200); gtk_container_set_border_width(GTK_CONTAINER(window), 10); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(closeApp), NULL);Далее вы создаёте модель дерева, передавая количество столбцов и тип каждого из них:
store = gtk_tree_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);Следующий этап — вставка родительской и дочерней строк в дерево:
gtk_tree_store_append(store, &parent_iter, NULL); gtk_tree_store_set(store, &parent_iter, COLUMN_TITLE, "Dark Side of the Moon", COLUMN_ARTIST, "Pink Floyd", COLUMN_CATALOGUE, "B000024D4P", -1); gtk_tree_store_append(store, &child_iter, &parent_iter); gtk_tree_store_set(store, &child_iter, COLUMN_TITLE, "Speak to Me", -1); view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));Наконец, добавьте столбцы в представление, задавая источники данных для них и заголовки:
renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), COLUMN_TITLE, "Title", renderer, "text", COLUMN_TITLE, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), COLUMN_ARTIST, "Catalogue", renderer, "text", COLUMN_ARTIST, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), COLUMN_CATALOGUE, "Catalogue", renderer, "text", COLUMN_CATALOGUE, NULL); gtk_container_add(GTK_CONTAINER(window), view); gtk_widget_show_all(window); gtk_main(); return 0; }
Назад: Виджеты класса GtkButton
Вернуться на главную страницу