How do I add a ComboBox to a TreeView column?

2019-07-20 06:28发布

问题:

In Gtkmm, I want to have a Gtk TreeView with a ListStore, and have one of the columns in the list be a ComboBoxText. But I can't seem to figure out how to do it.

What I currently have looks like:

class PlayerListColumns : public Gtk::TreeModelColumnRecord
{
public:

    PlayerListColumns()
    { add(name); add(team);}

    TreeModelColumn<string> name;
    TreeModelColumn<ComboBoxText*> team;
}

Then when setting the TreeView (the player_list_view object)

PlayerListColumns *columns = new PlayerListColumns();
Glib::RefPtr<ListStore> refListStore = ListStore::create(*columns);
player_list_view->set_model(refListStore);

ComboBoxText *box = manage(new ComboBoxText());
box->append("Blah");
box->append("Blah");
box->append("Blah");

TreeModel::Row row = *(refListStore->append());
row[columns->name] = "My Name";
row[columns->team] = box;

The column "name" shows up just fine, but no ComboBox. I'm almost positive that simply having a pointer to a combo box as the column type is wrong, but i don't know how it's supposed to go. I do get GTK warning:

GLib-GObject-WARNING **: unable to set property text' of typegchararray' from value of type `GtkComboBoxText'

Which seems to indicate (from a small bit of Googling) that there isn't a default renderer for non-basic types. But I haven't been able to find any examples of how to set one up, if that were the problem. All the tutorials only show TreeViews with primitive data types.

Anyone know how to put a ComboBox into a TreeView?

回答1:

Okay, I haven't gotten it working 100%, but this example class should get you on the right track: http://svn.gnome.org/svn/gtkmm-documentation/trunk/examples/book/treeview/combo_renderer/

Basically you need to add a Gtk::TreeModelColumn<Glib::RefPtr<Gtk::ListStore> > to your columns class and a Gtk::TreeModelColumn<string> to hold the selected data.

Then, to make a column a combobox, you have to add:

//manually created column for the tree view
Gtk::TreeViewColumn* pCol = Gtk::manage(new Gtk::TreeViewColumn("Choose"));

//the combobox cell renderer
Gtk::CellRendererCombo* comboCell = Gtk::manage(new Gtk::CellRendererCombo);

//pack the cell renderer into the column
pCol->pack_start(*comboCell);

//append the column to the tree view
treeView->append_column(*pCol);

//this sets the properties of the combobox and cell
//my gtkmm seems to be set for Glibmm properties
#ifdef GLIBMM_PROPERTIES_ENABLED
   pCol->add_attribute(comboCell->property_text(), columns->team);

   //this is needed because you can't use the ComboBoxText shortcut
   // you have to create a liststore and fill it with your strings separately
   // from your main model
   pCol->add_attribute(comboCell->property_model(), columns->teams);

   comboCell->property_text_column() = 0;
   comboCell->property_editable() = true;
#else
   pCol->add_attribute(*comboCell, "text", columns->team);
   pCol->add_attribute(*comboCell, "model", columns->teams);
   comboCell->set_property(text_column:, 0);
   comboCell->set_property("editable", true);
#endif

//connect a signal so you can set the selected option back into the model
//you can just have a column that is not added to the view if you want
comboCell->signal_edited()
    .connect(sigc::mem_fun(*this,&ComboWindow::on_combo_choice_changed));

EDIT ABOVE

I think something along the lines of using a Gtk::CellRendererCombo* is the way to go in your PlayerListColumns

http://developer.gnome.org/gtkmm/stable/classGtk_1_1CellRendererCombo.html

(I haven't made a working test yet, but I got the idea from: http://developer.gnome.org/gtkmm-tutorial/unstable/sec-treeview.html.en#treeview-cellrenderer-details)



标签: c++ gtkmm