This example has a Gtk::TreeView widget, with a Gtk::ListStore model.
File: examplewindow.h
#ifndef GTKMM_EXAMPLEWINDOW_H #define GTKMM_EXAMPLEWINDOW_H #include <gtkmm.h> class ExampleWindow : public Gtk::Window { public: ExampleWindow(); virtual ~ExampleWindow(); protected: //Signal handlers: virtual void on_button_quit(); //Tree model columns: class ModelColumns : public Gtk::TreeModel::ColumnRecord { public: ModelColumns() { add(m_col_id); add(m_col_name); add(m_col_number); } Gtk::TreeModelColumn<unsigned int> m_col_id; Gtk::TreeModelColumn<Glib::ustring> m_col_name; Gtk::TreeModelColumn<short> m_col_number; }; ModelColumns m_Columns; //Child widgets: Gtk::VBox m_VBox; Gtk::ScrolledWindow m_ScrolledWindow; Gtk::TreeView m_TreeView; Glib::RefPtr<Gtk::ListStore> m_refTreeModel; Gtk::HButtonBox m_ButtonBox; Gtk::Button m_Button_Quit; }; #endif //GTKMM_EXAMPLEWINDOW_H
File: main.cc
#include <gtkmm/main.h> #include "examplewindow.h" int main(int argc, char *argv[]) { Gtk::Main kit(argc, argv); ExampleWindow window; Gtk::Main::run(window); //Shows the window and returns when it is closed. return 0; }
File: examplewindow.cc
#include <iostream> #include "examplewindow.h" ExampleWindow::ExampleWindow() : m_Button_Quit("Quit") { set_title("Gtk::TreeView (ListStore) example"); set_border_width(5); set_default_size(400, 200); add(m_VBox); //Add the TreeView, inside a ScrolledWindow, with the button underneath: m_ScrolledWindow.add(m_TreeView); //Only show the scrollbars when they are necessary: m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); m_VBox.pack_start(m_ScrolledWindow); m_VBox.pack_start(m_ButtonBox, Gtk::PACK_SHRINK); m_ButtonBox.pack_start(m_Button_Quit, Gtk::PACK_SHRINK); m_ButtonBox.set_border_width(5); m_ButtonBox.set_layout(Gtk::BUTTONBOX_END); m_Button_Quit.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_quit) ); //Create the Tree model: m_refTreeModel = Gtk::ListStore::create(m_Columns); m_TreeView.set_model(m_refTreeModel); //Fill the TreeView's model Gtk::TreeModel::Row row = *(m_refTreeModel->append()); row[m_Columns.m_col_id] = 1; row[m_Columns.m_col_name] = "Billy Bob"; row[m_Columns.m_col_number] = 10; row = *(m_refTreeModel->append()); row[m_Columns.m_col_id] = 2; row[m_Columns.m_col_name] = "Joey Jojo"; row[m_Columns.m_col_number] = 20; row = *(m_refTreeModel->append()); row[m_Columns.m_col_id] = 3; row[m_Columns.m_col_name] = "Rob McRoberts"; row[m_Columns.m_col_number] = 30; //Add the TreeView's view columns: m_TreeView.append_column("ID", m_Columns.m_col_id); //This number will be shown with the default numeric formatting. m_TreeView.append_column("Name", m_Columns.m_col_name); m_TreeView.append_column_numeric("Formatted Number", m_Columns.m_col_number, "%010d" /* 10 digits, using leading zeroes. */); //Make all the columns reorderable: //This is not necessary, but it's nice to show the feature. //You can use TreeView::set_column_drag_function() to more //finely control column drag and drop. for(guint i = 0; i < 2; i++) { Gtk::TreeView::Column* pColumn = m_TreeView.get_column(i); pColumn->set_reorderable(); } show_all_children(); } ExampleWindow::~ExampleWindow() { } void ExampleWindow::on_button_quit() { hide(); }
This example is very similar to the ListStore example, but uses a Gtk::TreeStore model instead, and adds children to the rows.
File: examplewindow.h
#ifndef GTKMM_EXAMPLEWINDOW_H #define GTKMM_EXAMPLEWINDOW_H #include <gtkmm.h> class ExampleWindow : public Gtk::Window { public: ExampleWindow(); virtual ~ExampleWindow(); protected: //Signal handlers: virtual void on_button_quit(); virtual void on_treeview_row_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column); //Tree model columns: class ModelColumns : public Gtk::TreeModel::ColumnRecord { public: ModelColumns() { add(m_col_id); add(m_col_name); } Gtk::TreeModelColumn<int> m_col_id; Gtk::TreeModelColumn<Glib::ustring> m_col_name; }; ModelColumns m_Columns; //Child widgets: Gtk::VBox m_VBox; Gtk::ScrolledWindow m_ScrolledWindow; Gtk::TreeView m_TreeView; Glib::RefPtr<Gtk::TreeStore> m_refTreeModel; Gtk::HButtonBox m_ButtonBox; Gtk::Button m_Button_Quit; }; #endif //GTKMM_EXAMPLEWINDOW_H
File: main.cc
#include <gtkmm/main.h> #include "examplewindow.h" int main(int argc, char *argv[]) { Gtk::Main kit(argc, argv); ExampleWindow window; Gtk::Main::run(window); //Shows the window and returns when it is closed. return 0; }
File: examplewindow.cc
#include <iostream> #include "examplewindow.h" ExampleWindow::ExampleWindow() : m_Button_Quit("Quit") { set_title("Gtk::TreeView (TreeStore) example"); set_border_width(5); set_default_size(400, 200); add(m_VBox); //Add the TreeView, inside a ScrolledWindow, with the button underneath: m_ScrolledWindow.add(m_TreeView); //Only show the scrollbars when they are necessary: m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); m_VBox.pack_start(m_ScrolledWindow); m_VBox.pack_start(m_ButtonBox, Gtk::PACK_SHRINK); m_ButtonBox.pack_start(m_Button_Quit, Gtk::PACK_SHRINK); m_ButtonBox.set_border_width(5); m_ButtonBox.set_layout(Gtk::BUTTONBOX_END); m_Button_Quit.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_quit) ); //Create the Tree model: m_refTreeModel = Gtk::TreeStore::create(m_Columns); m_TreeView.set_model(m_refTreeModel); //All the items to be reordered with drag-and-drop: m_TreeView.set_reorderable(); //Fill the TreeView's model Gtk::TreeModel::Row row = *(m_refTreeModel->append()); row[m_Columns.m_col_id] = 1; row[m_Columns.m_col_name] = "Billy Bob"; Gtk::TreeModel::Row childrow = *(m_refTreeModel->append(row.children())); childrow[m_Columns.m_col_id] = 11; childrow[m_Columns.m_col_name] = "Billy Bob Junior"; childrow = *(m_refTreeModel->append(row.children())); childrow[m_Columns.m_col_id] = 12; childrow[m_Columns.m_col_name] = "Sue Bob"; row = *(m_refTreeModel->append()); row[m_Columns.m_col_id] = 2; row[m_Columns.m_col_name] = "Joey Jojo"; row = *(m_refTreeModel->append()); row[m_Columns.m_col_id] = 3; row[m_Columns.m_col_name] = "Rob McRoberts"; childrow = *(m_refTreeModel->append(row.children())); childrow[m_Columns.m_col_id] = 31; childrow[m_Columns.m_col_name] = "Xavier McRoberts"; //Add the TreeView's view columns: m_TreeView.append_column("ID", m_Columns.m_col_id); m_TreeView.append_column("Name", m_Columns.m_col_name); //Connect signal: m_TreeView.signal_row_activated().connect( sigc::mem_fun(*this, &ExampleWindow::on_treeview_row_activated) ); show_all_children(); } ExampleWindow::~ExampleWindow() { } void ExampleWindow::on_button_quit() { hide(); } void ExampleWindow::on_treeview_row_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* /* column */) { Gtk::TreeModel::iterator iter = m_refTreeModel->get_iter(path); if(iter) { Gtk::TreeModel::Row row = *iter; std::cout << "Row activated: ID=" << row[m_Columns.m_col_id] << ", Name=" << row[m_Columns.m_col_name] << std::endl; } }
This example is identical to the ListStore example, but it uses TreeView::append_column_editable() instead of TreeView::append_column().
File: examplewindow.h
#ifndef GTKMM_EXAMPLEWINDOW_H #define GTKMM_EXAMPLEWINDOW_H #include <gtkmm.h> class ExampleWindow : public Gtk::Window { public: ExampleWindow(); virtual ~ExampleWindow(); protected: //Signal handlers: virtual void on_button_quit(); //Tree model columns: class ModelColumns : public Gtk::TreeModel::ColumnRecord { public: ModelColumns() { add(m_col_id); add(m_col_name); add(m_col_foo); add(m_col_number); } Gtk::TreeModelColumn<unsigned int> m_col_id; Gtk::TreeModelColumn<Glib::ustring> m_col_name; Gtk::TreeModelColumn<bool> m_col_foo; Gtk::TreeModelColumn<int> m_col_number; }; ModelColumns m_Columns; //Child widgets: Gtk::VBox m_VBox; Gtk::ScrolledWindow m_ScrolledWindow; Gtk::TreeView m_TreeView; Glib::RefPtr<Gtk::ListStore> m_refTreeModel; Gtk::HButtonBox m_ButtonBox; Gtk::Button m_Button_Quit; }; #endif //GTKMM_EXAMPLEWINDOW_H
File: main.cc
#include <gtkmm/main.h> #include "examplewindow.h" int main(int argc, char *argv[]) { Gtk::Main kit(argc, argv); ExampleWindow window; Gtk::Main::run(window); //Shows the window and returns when it is closed. return 0; }
File: examplewindow.cc
#include <iostream> #include "examplewindow.h" ExampleWindow::ExampleWindow() : m_Button_Quit("Quit") { set_title("Gtk::TreeView Editable Cells example"); set_border_width(5); set_default_size(400, 200); add(m_VBox); //Add the TreeView, inside a ScrolledWindow, with the button underneath: m_ScrolledWindow.add(m_TreeView); //Only show the scrollbars when they are necessary: m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); m_VBox.pack_start(m_ScrolledWindow); m_VBox.pack_start(m_ButtonBox, Gtk::PACK_SHRINK); m_ButtonBox.pack_start(m_Button_Quit, Gtk::PACK_SHRINK); m_ButtonBox.set_border_width(5); m_ButtonBox.set_layout(Gtk::BUTTONBOX_END); m_Button_Quit.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_quit) ); //Create the Tree model: m_refTreeModel = Gtk::ListStore::create(m_Columns); m_TreeView.set_model(m_refTreeModel); //Fill the TreeView's model Gtk::TreeModel::Row row = *(m_refTreeModel->append()); row[m_Columns.m_col_id] = 1; row[m_Columns.m_col_name] = "Billy Bob"; row[m_Columns.m_col_foo] = true; row[m_Columns.m_col_number] = 10; row = *(m_refTreeModel->append()); row[m_Columns.m_col_id] = 2; row[m_Columns.m_col_name] = "Joey Jojo"; row[m_Columns.m_col_foo] = true; row[m_Columns.m_col_number] = 20; row = *(m_refTreeModel->append()); row[m_Columns.m_col_id] = 3; row[m_Columns.m_col_name] = "Rob McRoberts"; row[m_Columns.m_col_foo] = false; row[m_Columns.m_col_number] = 30; //Add the TreeView's view columns: m_TreeView.append_column_editable("ID", m_Columns.m_col_id); m_TreeView.append_column_editable("Name", m_Columns.m_col_name); m_TreeView.append_column_editable("foo", m_Columns.m_col_foo); m_TreeView.append_column_numeric_editable("foo", m_Columns.m_col_number, "%010d"); show_all_children(); } ExampleWindow::~ExampleWindow() { } void ExampleWindow::on_button_quit() { hide(); }
This example is much like the TreeStore example, but has 2 extra columns to indicate whether the row can be dragged, and whether it can receive drag-and-dropped rows. It uses a derived Gtk::TreeStore which overrides the virtual functions as described in the TreeView Drag and Drop section..
File: treemodel_dnd.h
#ifndef GTKMM_EXAMPLE_TREEMODEL_DND_H #define GTKMM_EXAMPLE_TREEMODEL_DND_H #include <gtkmm.h> class TreeModel_Dnd : public Gtk::TreeStore { protected: TreeModel_Dnd(); public: //Tree model columns: class ModelColumns : public Gtk::TreeModel::ColumnRecord { public: ModelColumns() { add(m_col_id); add(m_col_name); add(m_col_draggable); add(m_col_receivesdrags); } Gtk::TreeModelColumn<int> m_col_id; Gtk::TreeModelColumn<Glib::ustring> m_col_name; Gtk::TreeModelColumn<bool> m_col_draggable; Gtk::TreeModelColumn<bool> m_col_receivesdrags; }; ModelColumns m_Columns; static Glib::RefPtr<TreeModel_Dnd> create(); protected: //Overridden virtual functions: virtual bool row_draggable_vfunc(const Gtk::TreeModel::Path& path) const; virtual bool row_drop_possible_vfunc(const Gtk::TreeModel::Path& dest, const Gtk::SelectionData& selection_data) const; }; #endif //GTKMM_EXAMPLE_TREEMODEL_DND_H
File: examplewindow.h
#ifndef GTKMM_EXAMPLEWINDOW_H #define GTKMM_EXAMPLEWINDOW_H #include <gtkmm.h> #include "treemodel_dnd.h" class ExampleWindow : public Gtk::Window { public: ExampleWindow(); virtual ~ExampleWindow(); protected: //Signal handlers: virtual void on_button_quit(); //Child widgets: Gtk::VBox m_VBox; Gtk::ScrolledWindow m_ScrolledWindow; Gtk::TreeView m_TreeView; Glib::RefPtr<TreeModel_Dnd> m_refTreeModel; Gtk::HButtonBox m_ButtonBox; Gtk::Button m_Button_Quit; }; #endif //GTKMM_EXAMPLEWINDOW_H
File: main.cc
#include <gtkmm/main.h> #include "examplewindow.h" int main(int argc, char *argv[]) { Gtk::Main kit(argc, argv); ExampleWindow window; Gtk::Main::run(window); //Shows the window and returns when it is closed. return 0; }
File: treemodel_dnd.cc
#include "treemodel_dnd.h" #include <iostream> TreeModel_Dnd::TreeModel_Dnd() { //We can't just call Gtk::TreeModel(m_Columns) in the initializer list //because m_Columns does not exist when the base class constructor runs. //And we can't have a static m_Columns instance, because that would be //instantiated before the gtkmm type system. //So, we use this method, which should only be used just after creation: set_column_types(m_Columns); } Glib::RefPtr<TreeModel_Dnd> TreeModel_Dnd::create() { return Glib::RefPtr<TreeModel_Dnd>( new TreeModel_Dnd() ); } bool TreeModel_Dnd::row_draggable_vfunc(const Gtk::TreeModel::Path& path) const { //Make the value of the "draggable" column determine whether this row can be dragged: TreeModel_Dnd* unconstThis = const_cast<TreeModel_Dnd*>(this); //TODO: Add a const version of get_iter to TreeModel: const_iterator iter = unconstThis->get_iter(path); //const_iterator iter = get_iter(path); if(iter) { Row row = *iter; bool is_draggable = row[m_Columns.m_col_draggable]; return is_draggable; } return Gtk::TreeStore::row_draggable_vfunc(path); } bool TreeModel_Dnd::row_drop_possible_vfunc(const Gtk::TreeModel::Path& dest, const Gtk::SelectionData& selection_data) const { //Make the value of the "receives drags" column determine whether a row can be dragged into it: //dest is the path that the row would have after it has been dropped: //But in this case we are more interested in the parent row: Gtk::TreeModel::Path dest_parent = dest; bool dest_is_not_top_level = dest_parent.up(); if(!dest_is_not_top_level || dest_parent.empty()) { //The user wants to move something to the top-level. //Let's always allow that. } else { //Get an iterator for the row at this path: //We must unconst this. This should not be necessary with a future version of gtkmm. TreeModel_Dnd* unconstThis = const_cast<TreeModel_Dnd*>(this); //TODO: Add a const version of get_iter to TreeModel: const_iterator iter_dest_parent = unconstThis->get_iter(dest_parent); //const_iterator iter_dest_parent = get_iter(dest); if(iter_dest_parent) { Row row = *iter_dest_parent; bool receives_drags = row[m_Columns.m_col_receivesdrags]; return receives_drags; } } //You could also examine the row being dragged (via selection_data) //if you must look at both rows to see whether a drop should be allowed. //You could use //TODO: Add const version of get_from_selection_data(): Glib::RefPtr<const Gtk::TreeModel> refThis = Glib::RefPtr<const Gtk::TreeModel>(this); //Glib::RefPtr<Gtk::TreeModel> refThis = Glib::RefPtr<Gtk::TreeModel>(const_cast<TreeModel_Dnd*>(this)); //refThis->reference(); //, true /* take_copy */) //Gtk::TreeModel::Path path_dragged_row; //Gtk::TreeModel::Path::get_from_selection_data(selection_data, refThis, path_dragged_row); return Gtk::TreeStore::row_drop_possible_vfunc(dest, selection_data); }
File: examplewindow.cc
#include <iostream> #include "examplewindow.h" ExampleWindow::ExampleWindow() : m_Button_Quit(Gtk::Stock::QUIT) { set_title("Gtk::TreeView (Drag and Drop) example"); set_border_width(5); set_default_size(400, 200); add(m_VBox); //Add the TreeView, inside a ScrolledWindow, with the button underneath: m_ScrolledWindow.add(m_TreeView); //Only show the scrollbars when they are necessary: m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); m_VBox.pack_start(m_ScrolledWindow); m_VBox.pack_start(m_ButtonBox, Gtk::PACK_SHRINK); m_ButtonBox.pack_start(m_Button_Quit, Gtk::PACK_SHRINK); m_ButtonBox.set_border_width(5); m_ButtonBox.set_layout(Gtk::BUTTONBOX_END); m_Button_Quit.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_quit) ); //Create the Tree model: //Use our derived model, which overrides some Gtk::TreeDragDest and Gtk::TreeDragSource virtual functions: m_refTreeModel = TreeModel_Dnd::create(); //The columns are declared in the overridden TreeModel. m_TreeView.set_model(m_refTreeModel); //Enable Drag-and-Drop of TreeView rows: //See also the derived TreeModel's *_vfunc overrides. m_TreeView.enable_model_drag_source(); m_TreeView.enable_model_drag_dest(); //Fill the TreeView's model Gtk::TreeModel::Row row = *(m_refTreeModel->append()); row[m_refTreeModel->m_Columns.m_col_id] = 1; row[m_refTreeModel->m_Columns.m_col_name] = "Billy Bob"; row[m_refTreeModel->m_Columns.m_col_draggable] = true; row[m_refTreeModel->m_Columns.m_col_receivesdrags] = true; Gtk::TreeModel::Row childrow = *(m_refTreeModel->append(row.children())); childrow[m_refTreeModel->m_Columns.m_col_id] = 11; childrow[m_refTreeModel->m_Columns.m_col_name] = "Billy Bob Junior"; childrow[m_refTreeModel->m_Columns.m_col_draggable] = true; childrow[m_refTreeModel->m_Columns.m_col_receivesdrags] = true; childrow = *(m_refTreeModel->append(row.children())); childrow[m_refTreeModel->m_Columns.m_col_id] = 12; childrow[m_refTreeModel->m_Columns.m_col_name] = "Sue Bob"; childrow[m_refTreeModel->m_Columns.m_col_draggable] = true; childrow[m_refTreeModel->m_Columns.m_col_receivesdrags] = true; row = *(m_refTreeModel->append()); row[m_refTreeModel->m_Columns.m_col_id] = 2; row[m_refTreeModel->m_Columns.m_col_name] = "Joey Jojo"; row[m_refTreeModel->m_Columns.m_col_draggable] = true; row[m_refTreeModel->m_Columns.m_col_receivesdrags] = true; row = *(m_refTreeModel->append()); row[m_refTreeModel->m_Columns.m_col_id] = 3; row[m_refTreeModel->m_Columns.m_col_name] = "Rob McRoberts"; row[m_refTreeModel->m_Columns.m_col_draggable] = true; row[m_refTreeModel->m_Columns.m_col_receivesdrags] = true; childrow = *(m_refTreeModel->append(row.children())); childrow[m_refTreeModel->m_Columns.m_col_id] = 31; childrow[m_refTreeModel->m_Columns.m_col_name] = "Xavier McRoberts"; childrow[m_refTreeModel->m_Columns.m_col_draggable] = true; childrow[m_refTreeModel->m_Columns.m_col_receivesdrags] = true; //Add the TreeView's view columns: m_TreeView.append_column("ID", m_refTreeModel->m_Columns.m_col_id); m_TreeView.append_column("Name", m_refTreeModel->m_Columns.m_col_name); m_TreeView.append_column_editable("Draggable", m_refTreeModel->m_Columns.m_col_draggable); m_TreeView.append_column_editable("Receives Drags", m_refTreeModel->m_Columns.m_col_receivesdrags); show_all_children(); } ExampleWindow::~ExampleWindow() { } void ExampleWindow::on_button_quit() { hide(); }
This example is much like the ListStore example, but derives a custom TreeView in order to override the button_press_event, and also to encapsulate the tree model code in our derived class. See the TreeView Popup Context Menu section.
File: treeview_withpopup.h
#ifndef GTKMM_EXAMPLE_TREEVIEW_WITHPOPUP_H #define GTKMM_EXAMPLE_TREEVIEW_WITHPOPUP_H #include <gtkmm.h> class TreeView_WithPopup : public Gtk::TreeView { public: TreeView_WithPopup(); virtual ~TreeView_WithPopup(); protected: // Override Signal handler: // Alternatively, use signal_button_press_event().connect_notify() virtual bool on_button_press_event(GdkEventButton *ev); //Signal handler for popup menu items: virtual void on_menu_file_popup_generic(); //Tree model columns: class ModelColumns : public Gtk::TreeModel::ColumnRecord { public: ModelColumns() { add(m_col_id); add(m_col_name); } Gtk::TreeModelColumn<unsigned int> m_col_id; Gtk::TreeModelColumn<Glib::ustring> m_col_name; }; ModelColumns m_Columns; //The Tree model: Glib::RefPtr<Gtk::ListStore> m_refTreeModel; Gtk::Menu m_Menu_Popup; }; #endif //GTKMM_EXAMPLE_TREEVIEW_WITHPOPUP_H
File: examplewindow.h
#ifndef GTKMM_EXAMPLEWINDOW_H #define GTKMM_EXAMPLEWINDOW_H #include <gtkmm.h> #include "treeview_withpopup.h" class ExampleWindow : public Gtk::Window { public: ExampleWindow(); virtual ~ExampleWindow(); protected: //Signal handlers: virtual void on_button_quit(); //Child widgets: Gtk::VBox m_VBox; Gtk::ScrolledWindow m_ScrolledWindow; TreeView_WithPopup m_TreeView; Gtk::HButtonBox m_ButtonBox; Gtk::Button m_Button_Quit; }; #endif //GTKMM_EXAMPLEWINDOW_H
File: main.cc
#include <gtkmm/main.h> #include "examplewindow.h" int main(int argc, char *argv[]) { Gtk::Main kit(argc, argv); ExampleWindow window; Gtk::Main::run(window); //Shows the window and returns when it is closed. return 0; }
File: examplewindow.cc
#include <iostream> #include "examplewindow.h" ExampleWindow::ExampleWindow() : m_Button_Quit("Quit") { set_title("Gtk::TreeView (ListStore) example"); set_border_width(5); set_default_size(400, 200); add(m_VBox); //Add the TreeView, inside a ScrolledWindow, with the button underneath: m_ScrolledWindow.add(m_TreeView); //Only show the scrollbars when they are necessary: m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); m_VBox.pack_start(m_ScrolledWindow); m_VBox.pack_start(m_ButtonBox, Gtk::PACK_SHRINK); m_ButtonBox.pack_start(m_Button_Quit, Gtk::PACK_SHRINK); m_ButtonBox.set_border_width(5); m_ButtonBox.set_layout(Gtk::BUTTONBOX_END); m_Button_Quit.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_quit) ); show_all_children(); } ExampleWindow::~ExampleWindow() { } void ExampleWindow::on_button_quit() { hide(); }
File: treeview_withpopup.cc
#include "treeview_withpopup.h" #include <iostream> TreeView_WithPopup::TreeView_WithPopup() { //Create the Tree model: m_refTreeModel = Gtk::ListStore::create(m_Columns); set_model(m_refTreeModel); //Fill the TreeView's model Gtk::TreeModel::Row row = *(m_refTreeModel->append()); row[m_Columns.m_col_id] = 1; row[m_Columns.m_col_name] = "right-click on this"; row = *(m_refTreeModel->append()); row[m_Columns.m_col_id] = 2; row[m_Columns.m_col_name] = "or this"; row = *(m_refTreeModel->append()); row[m_Columns.m_col_id] = 3; row[m_Columns.m_col_name] = "or this, for a popup context menu"; //Add the TreeView's view columns: append_column("ID", m_Columns.m_col_id); append_column("Name", m_Columns.m_col_name); //Fill popup menu: { Gtk::Menu::MenuList& menulist = m_Menu_Popup.items(); menulist.push_back( Gtk::Menu_Helpers::MenuElem("_Edit", sigc::mem_fun(*this, &TreeView_WithPopup::on_menu_file_popup_generic) ) ); menulist.push_back( Gtk::Menu_Helpers::MenuElem("_Process", sigc::mem_fun(*this, &TreeView_WithPopup::on_menu_file_popup_generic) ) ); menulist.push_back( Gtk::Menu_Helpers::MenuElem("_Remove", sigc::mem_fun(*this, &TreeView_WithPopup::on_menu_file_popup_generic) ) ); } m_Menu_Popup.accelerate(*this); } TreeView_WithPopup::~TreeView_WithPopup() { } bool TreeView_WithPopup::on_button_press_event(GdkEventButton* event) { //Call base class, to allow normal handling, //such as allowing the row to be selected by the right-click: bool return_value = TreeView::on_button_press_event(event); //Then do our custom stuff: if( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { m_Menu_Popup.popup(event->button, event->time); } return return_value; } void TreeView_WithPopup::on_menu_file_popup_generic() { std::cout << "A popup menu item was selected." << std::endl; Glib::RefPtr<Gtk::TreeView::Selection> refSelection = get_selection(); if(refSelection) { Gtk::TreeModel::iterator iter = refSelection->get_selected(); if(iter) { int id = (*iter)[m_Columns.m_col_id]; std::cout << " Selected ID=" << id << std::endl; } } }