问题
In following up with an answer to my previous question on this issue, I've made some progress and am looking for the next bit of guidance. In brief, I'm having trouble loading up a Treeview from Glade with a gtkmm application.
To start, here's the source. The class:
typedef struct
{
Gtk::Window *window_info;
Gtk::TreeView *treeview_info;
Glib::RefPtr<Gtk::ListStore> liststore_info;
class InfoColumns : public Gtk::TreeModel::ColumnRecord
{
public:
InfoColumns() { add(time); add(message); }
Gtk::TreeModelColumn<string> time;
Gtk::TreeModelColumn<string> message;
} info_columns;
}UiElements;
class GuiManager
{
Glib::RefPtr<Gtk::Builder> builder;
UiElements elements;
public:
GuiManager();
void info_handler(string msg);
};
The definition:
GuiManager::GuiManager()
{
builder = Gtk::Builder::create();
builder->add_from_file("GUI3.glade");
builder->get_widget("window_info", elements.window_info);
builder->get_widget("treeview_info", elements.treeview_info);
//these two methods of loading the liststore appear to function identically
elements.liststore_info = Glib::RefPtr<Gtk::ListStore>::cast_dynamic(builder->get_object("liststore_info"));
// elements.liststore_info = Gtk::ListStore::create(elements.info_columns);
elements.treeview_info->set_model(elements.liststore_info);
//if I append the columns, the data appears at the end of the list
// elements.treeview_info->append_column("Time", elements.info_columns.time);
// elements.treeview_info->append_column("Message", elements.info_columns.message);
}
void GuiManager::info_handler(string msg)
{
Gtk::TreeModel::Row row = *(elements.liststore_info->append());
row[elements.info_columns.time] = "Now";
row[elements.info_columns.message] = msg;
}
And the XML:
<object class="GtkListStore" id="liststore_info">
<columns>
<!-- column-name Time -->
<column type="gchararray"/>
<!-- column-name Message -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkWindow" id="window_info">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Info</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow_info">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<property name="min_content_width">400</property>
<property name="min_content_height">600</property>
<child>
<object class="GtkTreeView" id="treeview_info">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">liststore_info</property>
<property name="enable_search">False</property>
<property name="enable_grid_lines">both</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview_info_selection"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeview_info_column_time">
<property name="resizable">True</property>
<property name="sizing">autosize</property>
<property name="min_width">100</property>
<property name="title" translatable="yes">Time</property>
<property name="clickable">True</property>
<child>
<object class="GtkCellRendererText" id="treeview_info_cellrenderer_time"/>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeview_info_column_message">
<property name="resizable">True</property>
<property name="sizing">autosize</property>
<property name="min_width">300</property>
<property name="title" translatable="yes">Message</property>
<property name="clickable">True</property>
<child>
<object class="GtkCellRendererText" id="treeview_info_cellrenderer_message"/>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
When I compile and run this code (plus one call to info_handler()
) I get a treeview with one row and two blank columns. When I uncomment the two lines appending the columns, I get a treeview with one row and four columns. The first two columns are blank (and sized according to the glade file) and the second two have the "Now"
and msg
strings (and are sized automatically to the contents).
What I gather from this is that elements.info_columns
is not associated with elements.treeview_info
via elements.liststore_info
. It looks like I'm just missing a step to connect the two. liststore_info
is listed as the model for treeview_info
in the glade file, as well as being set in GuiManager
's constructor.
Where's the disconnect?
回答1:
I think you need to set which list store field should be displayed in each table column.
- In Glade, right-click on the tree widget and click Edit... (not Edit separately)
- Click on the Hierarchy tab
- Click on a column
- Under Properties and Attributes ensure Text is ticked and the correct list store column is chosen from the drop down list (which will update the index accordingly.) For Pixbuf columns, you want Pixbuf Object instead of Text.
- Repeat for each column
In your case, I believe you should end up with an index of 0 for the Time column, and 1 for the Message column, and -1 in all the other fields.
This will populate the column's text from the selected field in the list store. I believe it's done this way so you can populate a column's other attributes (font, colour, etc.) through the list store as well, if you want.
Unrelated to this, I would also consider changing Gtk::TreeModelColumn<string>
to Gtk::TreeModelColumn<Glib::ustring>
as I believe the way you have it now may cause a conversion to/from a Glib::ustring
every time the tree view redraws itself. Keeping it as a Glib::ustring
from the start should avoid most of this conversion.
来源:https://stackoverflow.com/questions/32530367/glade-gtkmm-treeview