Control of individual TreeStore cells



I need to set the font style and/or background color for individual cells of ustrings in one column of a multi-column TreeStore.

CellRendererText::property_background_rgba () changes the background color of the whole column, but that's not what I need.

Since Gtk::TreeColumn is templated ("A Gtk::TreeModelColumn describes the C++ type of the data in a model column..."), and Gtk::Label is a C++ class, I tried putting Labels in the column in question, embedding the ustring and the background color in the Label widget. As an additional test, I use a custom sort function on the Label column.


#include <gtkmm.h>

class Test : public Gtk::Window
{
public:
    Test ();
    virtual ~Test () {}
int Sort ( const Gtk::TreeModel::iterator&, const Gtk::TreeModel::iterator& );
    class Columns : public Gtk::TreeModel::ColumnRecord
    {
    public:
        Columns ()
        { add ( m_label ); add ( m_text ); }
        Gtk::TreeModelColumn<Gtk::Label* > m_label;
        Gtk::TreeModelColumn<Glib::ustring > m_text;
    };
    Columns m_Model;
};

Test::Test ()
{
    Gtk::TreeView* pTreeView = new Gtk::TreeView ();
    add ( *pTreeView );

Glib::RefPtr<Gtk::ListStore > refModel = Gtk::ListStore::create ( m_Model );
    refModel->set_sort_func ( 0, sigc::mem_fun ( *this, &Test::Sort ) );
    refModel->set_sort_column ( 0, Gtk::SORT_ASCENDING );
    pTreeView->set_model ( refModel );
    pTreeView->append_column ( "Label", m_Model.m_label );
    pTreeView->append_column ( "Text", m_Model.m_text );

    Gtk::TreeModel::iterator iter = refModel->append ();
    Gtk::Label* pl = new Gtk::Label ( "Default" );
    (*iter)[m_Model.m_label] = pl;
    (*iter)[m_Model.m_text] = "Default";

    iter = refModel->append ();
    pl = new Gtk::Label ( "Yellow" );
    pl->override_background_color ( Gdk::RGBA ( "#f6f732" ) );
    (*iter)[m_Model.m_label] = pl;
    (*iter)[m_Model.m_text] = "Yellow";

    iter = refModel->append ();
    pl = new Gtk::Label ( "Green" );
    pl->override_background_color ( Gdk::RGBA ( "#4bdf63" ) );
    (*iter)[m_Model.m_label] = pl;
    (*iter)[m_Model.m_text] = "Green";

    set_position ( Gtk::WIN_POS_CENTER );
    set_size_request ( 300, 200 );
    show_all_children ();
}

int Test::Sort ( const Gtk::TreeModel::iterator& i1, const Gtk::TreeModel::iterator& i2 )
{
    Gtk::Label* p1 = (*i1)[m_Model.m_label];
    Glib::ustring s1 = p1->get_text ();
    Gtk::Label* p2 = (*i2)[m_Model.m_label];
    Glib::ustring s2 = p2->get_text ();
    if ( s1 == s2 ) return 0;
    if ( s1 < s2 ) return -1;
    return +1;
}

int main ( int argc, char *argv[] )
{
    Glib::RefPtr<Gtk::Application > pApp =
            Gtk::Application::create ( argc, argv, "org.pwolff.test" );
    Test window;
    return pApp->run ( window );
}

g++ -o test test.cc `pkg-config gtkmm-3.0 --cflags --libs`

TreeStore clearly handles the Labels, as evidenced by the correct sorted order, but the Labels themselves are not visible. The runtime also emits 37 instances of the following:

(test:15753): GLib-GObject-WARNING **: unable to set property 'text' of type 'gchararray' from value of type 'GtkLabel'

The docs say, "CellRenderers are used by Gtk::TreeView columns to render the Gtk::TreeModel column data appropriately.

"They display, and allow editing of, the values of their properties. In most cases, Gtk::TreeView::append_column() will automatically choose the appropriate renderer for the mode column's data type, so you will rarely need to worry about these classes."

Unless using Gtk::Label fails to satisfy the "most cases" qualifier, it seems to me that the labels should be visible and properly colored, and the automatically chosen cell renderer should not be trying to set property_text on a widget.

Should this work? Am I missing something?



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]