GNOME Bugzilla – Bug 619656
CellRendererText property changes are not reflected in ComboBoxText
Last modified: 2011-02-08 08:45:36 UTC
I have a class derived from ComboBoxText in which I load the available font families. I want to display each font family entry in its corresponding font family by using a CellRendererText and setting the property_family(), but the entries are all displayed in the default font. In order to test, I also set property_style and property_size_points. The entries are all displayed in the default font family, style and size; however, changing the property_size_points changes the spacing between each entry. Tested only on openSuSE 11.2. Here is my class: #include <set> #include <iostream> #include <gtkmm.h> typedef std::set<Glib::ustring> FontSet; class FontSelector : public Gtk::ComboBoxText { public: FontSelector() { // add columns to model col_records.add(col1); refStore = Gtk::ListStore::create(col_records); set_model(refStore); // add the font family names to the combobox Glib::RefPtr<Pango::Context> pc = this->get_pango_context(); if(pc) { FontSet fonts; Glib::ArrayHandle<Glib::RefPtr<Pango::FontFamily> > families = pc->list_families(); for(Glib::ArrayHandle<Glib::RefPtr<Pango::FontFamily> >::iterator it = families.begin(); it < families.end(); it++) { fonts.insert((*it)->get_name()); } for(FontSet::iterator it = fonts.begin(); it != fonts.end(); it++) { addrow(*it); } } // show font family text in the font family pack_start(renderer, true); add_attribute(renderer, "family", 0); sigc::slot<void, const Gtk::TreeIter> s = sigc::mem_fun(*this, &FontSelector::set_family); set_cell_data_func(renderer, s); } private: Gtk::TreeModelColumnRecord col_records; Glib::RefPtr<Gtk::ListStore> refStore; Gtk::TreeModelColumn<Glib::ustring> col1; Gtk::CellRendererText renderer; void addrow(Glib::ustring family) { Gtk::ListStore::iterator it = refStore->append(); Gtk::ListStore::Row row = *it; row[col1] = family; } void set_family(const Gtk::TreeIter iter) { Gtk::TreeModel::Row row = *iter; Glib::ustring family = row[col1]; renderer.property_family() = family; renderer.property_style() = Pango::STYLE_ITALIC; renderer.property_size_points() = 20; } };
Could you please try to create a full example that can be compiled, and please try to simplify it even more.
(In reply to comment #1) > Could you please try to create a full example that can be compiled, and please > try to simplify it even more. The following is the simplest that I can come up with that illustrates the problem and matches my comments. I could not find a way to simplify without actually resulting in a longer example. #include <set> #include <gtkmm.h> #include <iostream> using namespace std; typedef std::set<Glib::ustring> FontSet; class FontSelector : public Gtk::ComboBoxText { public: FontSelector() { // add colummns to model col_records.add(col1); refStore = Gtk::ListStore::create(col_records); set_model(refStore); // add the font family names to the combobox Glib::RefPtr<Pango::Context> pc = this->get_pango_context(); if(pc) { FontSet fonts; Glib::ArrayHandle<Glib::RefPtr<Pango::FontFamily> > families = pc->list_families(); for(Glib::ArrayHandle<Glib::RefPtr<Pango::FontFamily> >::iterator it = families.begin(); it < families.end(); it++) { fonts.insert((*it)->get_name()); } for(FontSet::iterator it = fonts.begin(); it != fonts.end(); it++) { addrow(*it); } } // show font family text in the font family pack_start(renderer, true); add_attribute(renderer, "family", 0); sigc::slot<void, const Gtk::TreeIter> s = sigc::mem_fun(*this, &FontSelector::set_family); set_cell_data_func(renderer, s); } private: Gtk::TreeModelColumnRecord col_records; Glib::RefPtr<Gtk::ListStore> refStore; Gtk::TreeModelColumn<Glib::ustring> col1; Gtk::CellRendererText renderer; // add the font family into the combobox void addrow(Glib::ustring family) { Gtk::ListStore::iterator it = refStore->append(); Gtk::ListStore::Row row = *it; row[col1] = family; } // set font properties for display of combobox items void set_family(const Gtk::TreeIter iter) { Gtk::TreeModel::Row row = *iter; Glib::ustring family = row[col1]; renderer.property_family() = family; renderer.property_style() = Pango::STYLE_ITALIC; renderer.property_size_points() = 20; } }; int main(int argc, char** argv) { Gtk::Main kit(argc, argv); Gtk::Window window; FontSelector fs; window.add(fs); fs.show(); Gtk::Main::run(window); }
Created attachment 173512 [details] Modification of the test case in comment 2 My conclusions after some experiments with the source code in comment 2: 1. The cell renderer added to FontSelector with pack_start(renderer, true); is not used for showing the text in TreeModelColumn col1. Instead a second column is added to the ComboBoxText. This column contains only empty strings, and is therefore not seen, but it affects the line height. This becomes obvious if in set_family() you add renderer.property_text() = family; 2. Gtk::CellLayout::get_cells() gets all cell renderers. Before the call to pack_start(), there is only one renderer, and that's the one you shall use in add_attribute(). (Gtk::CellLayout is a base class of Gtk::ComboBox.) See the attached slightly modified test case. Tested on Ubuntu 10.10 with gtkmm version 2.20.3 and gtk+ 2.22.0. I suppose that this behavior is by design, but it's not at all obvious. E.g. it took quite a while before I realized that Gtk::CellLayout::get_cells() is very useful here.
Yeah, well, ComboBoxText is a convenience that's meant to do just one text column, and you should use ComboBox to do more complex things. ComboBoxText in gtkmm 3 is now a wrapper of a C class, but the same behaviour is probably still there. I'd even be careful of using set_attribute() on a cell that was automatically added by the class itself. But admittedly I do a similar trick in Glom for ComboBoxEntryText (now ComboBoxText with has_entry=true). I guess this just need a warning in the documentation.
I can confirm that the behaviour is the same in gtkmm 3. Something like this could be added to the description of ComboBoxText: Use this class only for a combo box which contains a single column of text with default properties. If you want to specify your own text properties, use a ComboBox, which lets you decide which cell renderer to use. Some unrelated comments on the descriptions of ComboBox and ComboBoxText in gtkmm 3: ComboBox: Mentions OptionMenu, which has been deprecated for some time, and seems to be removed from gtkmm 3. ComboBoxText: In the class description methods are called append_text(), insert_text(), and prepend_text(). In the code they are called append(), insert(), and prepend(). There's a constructor with a 'model' parameter. When that constructor is used, the model-view complexity is not hidden, is it? The function mentioned in _IGNORE(gtk_combo_box_text_new_with_model) does not exist.
(In reply to comment #5) > ComboBox: Mentions OptionMenu, which has been deprecated for some time, and > seems to be removed from gtkmm 3. Thanks. Fixed by this commit: http://git.gnome.org/browse/gtkmm/commit/?id=d5674d69dc3770483760a55abe7d36d90ae9e270 (The commit message mentions ComboBoxText instead of ComboBox, but that is just a typo.) > ComboBoxText: In the class description methods are called append_text(), > insert_text(), and prepend_text(). In the code they are called append(), > insert(), and prepend(). Yes, also reported in bug #638405, now fixed:
(In reply to comment #5) > There's a constructor with a 'model' parameter. When that constructor is used, > the model-view complexity is not hidden, is it? The function mentioned in > _IGNORE(gtk_combo_box_text_new_with_model) > does not exist. Thanks. It must be a copy/paste error. Fixed: http://git.gnome.org/browse/gtkmm/commit/?id=fc66116ebddb7bbe4a45cfea1663859fc4be3cb3
(In reply to comment #5) > I can confirm that the behaviour is the same in gtkmm 3. > > Something like this could be added to the description of ComboBoxText: > > Use this class only for a combo box which contains a single column of text > with default properties. If you want to specify your own text properties, > use a ComboBox, which lets you decide which cell renderer to use. Can we be more specific. For instance, by adding this too. "Do not attempt to call set_model() on a ComboBoxText, or to pack more cells into it via its CellLayout base class.". I would add this to the C documentation too: http://library.gnome.org/devel/gtk/unstable/GtkComboBoxText.html#GtkComboBoxText.description
(In reply to comment #8) > (In reply to comment #5) > > Something like this could be added to the description of ComboBoxText: > > > > Use this class only for a combo box which contains a single column of text > > with default properties. If you want to specify your own text properties, > > use a ComboBox, which lets you decide which cell renderer to use. > > Can we be more specific. For instance, by adding this too. > "Do not attempt to call set_model() on a ComboBoxText, or to pack more cells > into it via its CellLayout base class.". Yes, that's fine. On second thought I also think that "properties" in my text should be replaced by "attributes". The method that has caused much of the confusion is CellLayout::add_attribute().
(In reply to comment #9) The method that has caused much of the > confusion is CellLayout::add_attribute(). If you don't call set_model() then you'd have no reason to call add_attribute(), so that seems superfluous, just making the warning more complicated.
This is the additional warning in gtkmm-2.24: http://git.gnome.org/browse/gtkmm/commit/?h=gtkmm-2-24&id=4baa3dc789e61f3247ad2739d84aa44f85909f84 and in gtkmm 3: http://git.gnome.org/browse/gtkmm/commit/?id=11decc65f8a57d265709da89147951dc7aea3551 So I think I can close this bug now. If you think any other warning is necessary, a patch would be welcome. Thanks.