gtkmm:

The C++ Interface to Gtk+

TreeView


Model/View Pattern with Gtk::TreeView

The Gtk::TreeView widget stores the data that you want to display in a Gtk::TreeModel or Gtk::ListModel.

Example: Gtk::TreeView

Treeview example

examplewindow.h:


#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <glibmm.h>
#include <gdkmm.h>
#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:
        ExampleWindow();
        virtual ~ExampleWindow();

private:
        void add_entry( const int id, const int dice_id, const char* filename, const char* name );

        // Signal handlers
        virtual void on_button_quit();
        virtual void on_button_delete();
        virtual void on_selection_changed();

        // Types and classes
        typedef Glib::RefPtr<Gdk::Pixbuf> PixbufPtr;

        class ModelColumns : public Gtk::TreeModel::ColumnRecord
        {
                public:

                ModelColumns()
                { add(m_col_id); add(m_dice_id); add(m_pixbuf); add(m_col_name); }

                Gtk::TreeModelColumn<int>			m_col_id;
                Gtk::TreeModelColumn<int>			m_dice_id;
                Gtk::TreeModelColumn<PixbufPtr> 		m_pixbuf;
                Gtk::TreeModelColumn<Glib::ustring>   		m_col_name;
        };

        // Private members
        ModelColumns                            m_Columns;

        Gtk::VBox                               m_VBox;

        Gtk::ScrolledWindow                     m_ScrolledWindow;
        Gtk::TreeView                           m_TreeView;
        Glib::RefPtr<Gtk::ListStore>            m_refTreeModel;
        Glib::RefPtr<Gtk::TreeSelection>        m_refTreeSelection;

        Gtk::HButtonBox                         m_ButtonBox;
        Gtk::Button                             m_Button_Quit;
        Gtk::Button                             m_Button_Delete;
};

#endif //GTKMM_EXAMPLEWINDOW_H

examplewindow.cc:


#include <iostream>
#include "examplewindow.h"

namespace
{
        struct TreeEntry
        {
                int             m_id;
                int             m_dice_id;
                const char*     m_filename;
                const char*     m_name;

                TreeEntry() : m_id(-1), m_dice_id(-1), m_filename(0), m_name(0) {}
                TreeEntry( const int id, const int dice_id, const char* fn, const char* name )
                        : m_id(id), m_dice_id(dice_id), m_filename(fn), m_name(name) {}
        };

        TreeEntry g_entries[] = 
        {
                TreeEntry(  1,  1, "gnome-dice-1.svg", "Billy Bob"        ),
                TreeEntry( 11,  2, "gnome-dice-2.svg", "Billy Bob Junior" ),
                TreeEntry( 12,  3, "gnome-dice-3.svg", "Sue Bob"          ),
                TreeEntry(  2,  4, "gnome-dice-4.svg", "Joey Jojo"        ),
                TreeEntry(  3,  5, "gnome-dice-5.svg", "Rob McRoberts"    ),
                TreeEntry( 31,  6, "gnome-dice-6.svg", "Xavier McRoberts" ),
                TreeEntry( 53,  1, "gnome-dice-1.svg", "Ian McClintock"   ),
                TreeEntry( 27,  2, "gnome-dice-2.svg", "John Roberts"     )
        };
}


ExampleWindow::ExampleWindow() :
        m_Button_Quit("Quit"),
        m_Button_Delete("Delete")
{
        set_title("Gtk::TreeView (TreeStore) example");
        set_border_width(5);
        set_default_size(800, 600);

        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.pack_start(m_Button_Delete, 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) );
        m_Button_Delete.signal_clicked().connect( sigc::mem_fun(*this, &ExampleWindow::on_button_delete) );
        m_Button_Delete.set_sensitive( false ); // Only activate if row selected

        //Create the Tree model:
        m_refTreeModel     = Gtk::ListStore::create(m_Columns);
        m_TreeView.set_model(m_refTreeModel);

        //All the items to be reordered with drag-and-drop:
        m_TreeView.set_reorderable();
        m_TreeView.set_rules_hint();
        m_TreeView.set_headers_clickable(true);
        m_TreeView.set_headers_visible(true);

        // Handle tree selections
        //
        m_refTreeSelection = m_TreeView.get_selection();
        m_refTreeSelection->signal_changed().connect( sigc::mem_fun(*this, &ExampleWindow::on_selection_changed) );

        //Add the TreeView's view columns:
        m_TreeView.append_column("ID", m_Columns.m_col_id);
        m_TreeView.append_column("Image", m_Columns.m_pixbuf);
        m_TreeView.append_column("Name", m_Columns.m_col_name);
        m_refTreeModel->set_sort_column( m_Columns.m_col_name, Gtk::SORT_ASCENDING );   // Initial sorting column

        // Set sorting for each column added
        Gtk::TreeView::Column* pColumn = m_TreeView.get_column(0);
        pColumn->set_sort_column( m_Columns.m_col_id );

        pColumn = m_TreeView.get_column(1);
        pColumn->set_sort_column( m_Columns.m_dice_id );

        pColumn = m_TreeView.get_column(2);
        pColumn->set_sort_column( m_Columns.m_col_name );

        // Fill the TreeView's model
        //
        const int count = sizeof( g_entries ) / sizeof( TreeEntry );
        for( int idx = 0; idx < count; ++idx )
        {
                add_entry( g_entries[idx].m_id, g_entries[idx].m_dice_id, g_entries[idx].m_filename, g_entries[idx].m_name );
        }

        show_all_children();
}


ExampleWindow::~ExampleWindow()
{
}


void ExampleWindow::add_entry( const int id, const int dice_id, const char* filename, const char* name )
{
        Gtk::TreeModel::Row row         = *(m_refTreeModel->append());
        row[m_Columns.m_col_id]         = id;
        row[m_Columns.m_dice_id]        = dice_id;
        row[m_Columns.m_pixbuf]         = Gdk::Pixbuf::create_from_file( filename );
        row[m_Columns.m_col_name]       = name;
}


void ExampleWindow::on_button_quit()
{
        hide();
}


void ExampleWindow::on_button_delete()
{
        Gtk::TreeModel::iterator store_iter = m_refTreeSelection->get_selected();
        m_refTreeModel->erase( store_iter );
}


void ExampleWindow::on_selection_changed()
{
        m_Button_Delete.set_sensitive(
		m_refTreeSelection->count_selected_rows() > 0 );
}



Back

Contents

Next