Библиотека сайта rus-linux.net
Программирование с использованием gtkmm 3. Виджет древовидного представления данных (TreeView)
Оригинал: Programming with gtkmm 3
Авторы: Murray Cumming, Bernhard Rieder, Jonathon Jongsma, Ole Laursen, Marko Anastasov, Daniel Elstner, Chris Vine, David King, Pedro Ferreira, Kjell Ahlstedt
Перевод: А.Панин
9.2. Представление
Представление является самим виджетом (реализованным в рамках класса Gtk::TreeView
), который отображает данные модели (реализованной в рамках класса Gtk::TreeModel
) и позволяет пользователю взаимодействовать с ней. Представление может выводить данные из всех столбцов модели или только из некоторых, а также позволяет производить вывод этих данных различными способами.
9.2.1. Использование модели
Gtk::TreeModel
при создании экземпляра класса Gtk::TreeView
, или же использовать метод set_model()
аналогичным образом:
m_TreeView.set_model(m_refListStore);
9.2.2. Добавление столбцов представления
append_column()
для того, чтобы сообщить виджету древовидного представления данных о том, что он должен показывать определенные столбцы модели в определенном порядке и с определенными заголовками.
m_TreeView.append_column("Сообщения", m_Columns.m_col_text);
При использовании этого простого метода append_column()
виджет древовидного представления данных будет выводить данные модели с помощью определенного объекта прорисовки ячеек (представленного классом Gtk::CellRenderer
). Например, строковые и числовые значения могут выводиться с помощью простого виджета, представленного классом Gtk::Entry
, а логические значения - с помощью виджета, представленного классом Gtk::CheckButton
. Обычно эти виджеты вполне подходят для вывода подобных данных. Для вывода других типов данных в столбцах вам придется либо присоединить функцию обратного вызова, которая будет преобразовывать данные вашего типа в строковое представление, с помощью метода TreeViewColumn::set_cell_data_func()
, либо создавать собственный класс прорисовки ячеек, унаследованный от класса Gtk::CellRenderer
. Учтите, что короткие (беззнаковые) целочисленные значения (unsigned short) по умолчанию не поддерживаются, поэтому вам придется использовать либо (беззнаковые) целочисленные значения (unsigned int), либо длинные (беззнаковые) целочисленные значения (unsigned long) вместо них для данных столбцов.
9.2.3. Использование более одного столбца модели для формирования столбца представления
Для вывода данных из более чем одного столбца модели в столбце представления вам придется создать представленный классом TreeView::Column
виджет вручную и использовать метод pack_start()
для добавления в него столбцов модели.
После этого следует использовать метод append_column()
для добавления сформированного столбца в представление. Заметьте, что метод Gtk::View::append_column()
перекрывается для обработки как виджетов, представленных классом Gtk::View::Column
, так и столбцов, представленных экземплярами класса Gtk::TreeModelColumn
, на основе которых впоследствии генерируется подходящие виджеты, представленные классом Gtk::View::Column
.
demos/gtk-demo/example_stockbrowser.cc
, в котором изображение и текст выводятся в одном и том же столбце:
Gtk::TreeView::Column* pColumn = Gtk::manage( new Gtk::TreeView::Column("Символ") ); // m_columns.icon и m_columns.symbol являются столбцами модели. // pColumn является столбцом виджета древовидного представления данных: pColumn->pack_start(m_columns.icon, false); //false = не расширять. pColumn->pack_start(m_columns.symbol); m_TreeView.append_column(*pColumn);
9.2.4. Задание параметров объектов прорисовки ячеек
Gtk::CellRenderer
и стандартное поведение созданных на его основе объектов в большинстве случаев будут удовлетворять всем предъявляемым к ним требованиям, но иногда вы можете столкнуться с необходимостью осуществления более тонкого управления параметрами соответствующих объектов. Например, в коде из файла примера demos/gtk-demo/example_treestore.cc
вручную создается виджет на основе класса Gtk::CellRenderer
, который настраивается для вывода данных из различных столбцов модели с различными параметрами вывода.
Gtk::CellRendererToggle* pRenderer = Gtk::manage( new Gtk::CellRendererToggle() ); int cols_count = m_TreeView.append_column("Alex", *pRenderer); Gtk::TreeViewColumn* pColumn = m_TreeView.get_column(cols_count-1); if(pColumn) { pColumn->add_attribute(pRenderer->property_active(), m_columns.alex); pColumn->add_attribute(pRenderer->property_visible(), m_columns.visible); pColumn->add_attribute(pRenderer->property_activatable(), m_columns.world);
Gtk::CellRenderer
для обработки действий пользователя. Например, следующим образом:
Gtk::CellRendererToggle* pRenderer = Gtk::manage( new Gtk::CellRendererToggle() ); pRenderer->signal_toggled().connect( sigc::bind( sigc::mem_fun(*this, &Example_TreeView_TreeStore::on_cell_toggled), m_columns.dave) );
9.2.5. Редактируемые ячейки
9.2.5.1. Редактируемые ячейки с автоматическим сохранением значений
Ячейки виджета древовидного представления данных могут непосредственно редактироваться пользователем. Для активации этой возможности следует использовать методы класса Gtk::TreeView
insert_column_editable()
и append_column_editable()
вместо методов insert_column()
и append_column()
. После редактирования таких ячеек новые значения будут немедленно сохраняться в модели. Следует учесть, что описанные методы являются шаблонами, которые могут использоваться для работы только с такими простыми типами данных, как строки в кодировке Unicode (Glib::ustring), целые числа (int) и длинные целые числа (long).
9.2.5.2. Реализация пользовательской логики для обработки значений редактируемых ячеек
Однако, вам может не подходить вариант с немедленным сохранением новых значений. Например, вам может потребоваться запрет ввода определенных символов или диапазонов значений.
Для реализации данного поведения вы должны использовать обычные методы класса Gtk::TreeView inset_column()
и append_column()
и после этого вызывать метод get_column_cell_renderer()
для получения используемого этим столбцом экземпляра класса прорисовки ячеек Gtk::CellRenderer
.
В последствии вы должны преобразовать этот экземпляр класса Gtk::CellRenderer*
к определенному, ожидаемому вами типу объекта прорисовки ячеек для получения возможности использования специфического API.
Gtk::CellRendererText
, вы можете включить возможность редактирования текста в ячейке путем установки значения true для параметра editable таким образом, как показано ниже:
cell.property_editable() = true;
Для объекта, представленного классом Gtk::CellRendererToggle
, вместо значения описанного параметра вы можете установить значение параметра activatable.
После этого вы можете установить обработчик сигнала для подходящего сигнала редактирования "edited". К примеру, можно соединить обработчики с сигналами Gtk::CellRendererText::signal_edited()
или Gtk::CellRendererToggle::signal_toggled()
. В том случае, если столбец содержит более одного объекта прорисовки ячеек, вам придется использовать метод Gtk::TreeView::get_column()
и после этого вызывать метод get_cell_renderers()
полученного объекта столбца.
В рамках вашего обработчика сигнала вы должны исследовать новое значение и сохранить его в модели в том случае, если оно подходит для вашего приложения.
Следующий раздел : 9.3. Обход строк модели.