Наши партнеры

UnixForum





Библиотека сайта 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.3. Обход строк модели

Класс Gtk::TreeModel реализует характерный для стандартной библиотеки языка программирования C++ контейнер для дочерних элементов, доступ к которому осуществляется с помощью метода children(). Вы можете использовать привычные методы begin() и end() для работы с итератором так, как это показано ниже:
typedef Gtk::TreeModel::Children type_children; //для сокращения объема кода.
type_children children = refModel->children();
for(type_children::iterator iter = children.begin();
    iter != children.end(); ++iter)
{
  Gtk::TreeModel::Row row = *iter;
  //Какая-либо обработка строки - методы получения и изменения значений обсуждались выше.
}

9.3.1. Дочерние строки

При работе с классом Gtk::TreeStore у строк могут быть дочерние строки, которые, в свою очередь, могут иметь свои дочерние строки. Используйте метод Gtk::TreeModel::Row::children() для получения доступа к контейнеру с дочерними строками:
Gtk::TreeModel::Children children = row.children();

9.4. Выбор строк

Для установления того, какие строки выбрал пользователь, следует получить объект типа Gtk::TreeView::Selection от экземпляра класса виджета древовидного представления данных следующим образом:
Glib::RefPtr<Gtk::TreeSelection> refTreeSelection =
    m_TreeView.get_selection();

9.4.1. Единичный или множественный выбор

По умолчанию может быть выбрана только одна строка, но вы можете разрешить множественный выбор, установив соответствующий режим выбора строк следующим образом:
refTreeSelection->set_mode(Gtk::SELECTION_MULTIPLE);

9.4.2. Выбранные строки

При единичном выборе вы можете просто использовать метод get_selected() так, как показано ниже:
TreeModel::iterator iter = refTreeSelection->get_selected();
if(iter) //Если строка выбрана
{
  TreeModel::Row row = *iter;
  //Выполнение каких-либо действий со строкой.
}
При множественном выборе вам придется установить функцию обратного вызова и передать ее имя методу selected_foreach(), selected_foreach_path() или selected_foreach_iter() так, как показано ниже:
refTreeSelection->selected_foreach_iter(
    sigc::mem_fun(*this, &TheClass::selected_row_callback) );

void TheClass::selected_row_callback(
    const Gtk::TreeModel::iterator& iter)
{
  TreeModel::Row row = *iter;
  //Выполнение каких-либо действий со строкой.
}

9.4.3. Сигнал "changed"

Для обработки события выбора пользователем строки или диапазона строк следует установить обработчик сигнала следующим образом:
refTreeSelection->signal_changed().connect(
    sigc::mem_fun(*this, &Example_StockBrowser::on_selection_changed)
);

9.4.4. Предотвращение выбора строк

Может возникнуть ситуация, в которой пользователь не должен иметь возможности выбора каждого элемента из вашего списка или дерева. Например, в демонстрационной программе gtk-demo вы можете выбрать пример программы для ознакомления с исходным кодом, но при этом нет никакого смысла в выборе категории примеров.

Для контроля за тем, какие строки могут быть выбраны следует использовать метод set_select_function() предоставив имя функции обратного вызова. Например, следующим образом:
m_refTreeSelection->set_select_function( sigc::mem_fun(*this,
    &DemoWindow::select_function) );
после чего реализовать функцию обратного вызова
bool DemoWindow::select_function(
    const Glib::RefPtr<Gtk::TreeModel>& model,
    const Gtk::TreeModel::Path& path, bool)
{
  const Gtk::TreeModel::iterator iter = model->get_iter(path);
  return iter->children().empty(); // предоставить возможность выбора исключительно дочерних строк
}

9.4.5. Изменение выбора

Для изменения выбора используйте объект итератора типа Gtk::TreeModel::iterator или строки типа Gtk::TreeModel::Row следующим образом:
Gtk::TreeModel::Row row = m_refModel->children()[5]; //Пятая строка.
if(row)
  refTreeSelection->select(row);
или так
Gtk::TreeModel::iterator iter = m_refModel->children().begin()
if(iter)
  refTreeSelection->select(iter);

Следующий раздел : 9.5. Сортировка.