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

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.5. Сортировка

Классы стандартных моделей представления данных (Gtk::TreeStore и Gtk::ListStore) наследуются от класса Gtk::TreeSortable, следовательно они предоставляют функции сортировки. Например, можно вызвать метод set_sort_column() для сортировки модели на основе данных в определенном столбце. Или же можно передать имя функции обратного вызова методу set_sort_func() для реализации более сложного алгоритма сортировки.

Справочная информация для класса Gtk::TreeSortable

9.5.1. Сортировка по нажатию на заголовки столбцов

Для того, чтобы пользователь имел возможность осуществления сортировки строк виджета древовидного представления данных путем нажатия на заголовок столбца, следует осуществить вызов метода Gtk::TreeViewModel::set_sort_column() с передачей столбца модели, на основе данных из которого она должна быть отсортирована в момент нажатия на заголовок столбца виджета. Например, описанное действие могут быть осуществлено следующим образом:
Gtk::TreeView::Column* pColumn = treeview.get_column(0);
if(pColumn)
  pColumn->set_sort_column(m_columns.m_col_id);

9.5.2. Независимо сортируемые представления одной и той же модели

Класс Gtk::TreeView на данный момент уже позволяет вам выводить данные одной и той же модели в двух виджетах древовидного представления. Если же вы хотите, чтобы один из этих виджетов использовался для вывода данных модели, отсортированных не так, как в другом виджете, вам придется использовать класс Gtk::TreeModelSort вместо простого вызова метода Gtk::TreeViewModel::set_sort_column(). Класс Gtk::TreeModelSort реализует модель, которая содержит другую модель, представляющую отсортированную версию оригинальной модели.

Например, вы можете передать отсортированную версию модели виджету древовидного представления следующим образом:
Glib::RefPtr<Gtk::TreeModelSort> sorted_model =
    Gtk::TreeModelSort::create(model);
sorted_model-7gt;set_sort_column(columns.m_col_name, Gtk::SORT_ASCENDING);
treeview.set_model(sorted_model);
Однако, следует помнить о том, что виджет древовидного представления будет предоставлять итераторы для отсортированной модели. Вы должны преобразовать их в итераторы для расположенной уровнем ниже дочерней модели перед выполнением операций с этой моделью. Например, следующим образом:
void ExampleWindow::on_button_delete()
{
  Glib::RefPtr<Gtk::TreeSelection> refTreeSelection =
      m_treeview.get_selection();
  if(refTreeSelection)
  {
    Gtk::TreeModel::iterator sorted_iter =
        m_refTreeSelection->get_selected();
    if(sorted_iter)
    {
      Gtk::TreeModel::iterator iter =
          m_refModelSort->convert_iter_to_child_iter(sorted_iter);
      m_refModel->erase(iter);
    }
  }
}

Справочная информация для класса Gtk::TreeModelSort

9.6. Механизм захвата и перемещения элементов Drag and Drop

В рамках класса Gtk::TreeView реализован простой механизм захвата и перемещения элементов drag-and-drop, который используется при работе с моделями представлений данных на основе классов Gtk::ListStore и Gtk::TreeStore. В случае необходимости у вас есть возможность реализации более сложных механизмов захвата и перемещения элементов благодаря наличию обычного API Drag and Drop.

9.6.1. Перемещаемые строки

В том случае, если вы осуществляете вызов метода Gtk::TreeView::set_reorderable(), строки вашего виджета древовидного представления данных получают возможность перемещения в рамках самого представления. Эта возможность демонстрируется в примере работы с моделью представления данных.

Однако, эта возможность не позволяет вам обозначать элементы, которые могут быть захвачены, а также места, в которые эти элементы могут быть перемещены. Если у вас есть необходимость в регламентации описанных особенностей работы механизма захвата и перемещения, вы можете создать класс модели представления данных Gtk::TreeModel, унаследованный от класса Gtk::TreeStore или от класса Gtk::ListStore и перекрыть в потомке виртуальные методы Gtk::TreeDragSource::row_draggable() и Gtk::TreeDragDest::row_drop_possible(). После этого вы можете исследовать передаваемые с помощью экземпляров класса Gtk::TreeModel::Path пути и позволять или не позволять захват и перемещение элемента путем возврата логического значения true или false соответственно.

Такой подход продемонстрирован в примере использования механизма захвата и перемещения элементов (drag_and_drop).

9.7. Всплывающее контекстное меню

Многие люди сталкиваются с необходимостью реализации активируемых с помощью правой кнопки мыши всплывающих контекстных меню для виджетов древовидного представления данных, поэтому мы расскажем о реализации таких меню для сохранения вашего времени. За исключением одного или двух отличий эти меню полностью идентичны обычным контекстным меню, описанным в разделе "Меню".

9.7.1. Обработка сигнала "button_press_event"

Для выявления события нажатия правой кнопки мыши вам придется обрабатывать сигнал "button_press_event" и проверять то, какая из кнопок была нажата в действительности. Так как виджет древовидного представления данных в обычных условиях обрабатывает этот сигнал в полном объеме, вам придется либо перекрыть стандартный обработчик сигнала в унаследованном классе виджета древовидного представления данных, либо использовать функцию connect_notify() вместо connect(). Скорее всего, вы захотите также вызвать стандартный обработчик сигнала перед тем, как делать что-либо еще для того, чтобы нажатие правой кнопки мыши приводило в первую очередь к выбору строки.

Данный подход продемонстрирован в примере работы со специальными всплывающими меню.


Следующий раздел : 9.8. Примеры.