Библиотека сайта 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. Сортировка.