Glade/gtkmm 树视图
Glade/gtkmm TreeView
在跟进我对这个问题的 的回答后,我取得了一些进展,正在寻找下一个指导。简而言之,我在使用 gtkmm 应用程序从 Glade 加载 Treeview 时遇到了问题。
首先,这是来源。 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);
};
定义:
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;
}
和 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>
当我编译和 运行 这段代码(加上对 info_handler()
的一次调用)时,我得到一个包含一行和两个空白列的树视图。当我取消注释附加列的两行时,我得到一个包含一行和四列的树视图。前两列是空白的(根据 glade 文件调整大小),后两列有 "Now"
和 msg
字符串(根据内容自动调整大小)。
我从中了解到 elements.info_columns
与 elements.treeview_info
没有通过 elements.liststore_info
相关联。看起来我只是缺少连接两者的步骤。 liststore_info
在 glade 文件中被列为 treeview_info
的模型,并在 GuiManager
的构造函数中设置。
断线在哪里?
我认为您需要设置每个 table 列中应显示的列表商店字段。
- 在 Glade 中,右键单击树小部件并单击 编辑...(不是 单独编辑)
- 单击层次结构 选项卡
- 点击一列
- 在属性和属性下确保勾选文本并从下拉列表中选择正确的列表存储列(这将更新相应的索引。)对于 Pixbuf 列,您需要 Pixbuf Object 而不是 Text.
- 对每一列重复
在你的情况下,我相信你最终应该为 Time 列索引 0,为 Message 列索引 1,在所有其他字段中索引为 -1。
这将从列表存储中的选定字段填充列的文本。我相信这样做是为了让您可以根据需要通过列表存储填充列的其他属性(字体、颜色等)。
与此无关,我也会考虑将 Gtk::TreeModelColumn<string>
更改为 Gtk::TreeModelColumn<Glib::ustring>
,因为我相信您现在使用它的方式可能会导致转换 to/from 到 Glib::ustring
树视图重新绘制自身的时间。从一开始就将其保持为 Glib::ustring
应该可以避免大部分这种转换。
在跟进我对这个问题的
首先,这是来源。 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);
};
定义:
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;
}
和 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>
当我编译和 运行 这段代码(加上对 info_handler()
的一次调用)时,我得到一个包含一行和两个空白列的树视图。当我取消注释附加列的两行时,我得到一个包含一行和四列的树视图。前两列是空白的(根据 glade 文件调整大小),后两列有 "Now"
和 msg
字符串(根据内容自动调整大小)。
我从中了解到 elements.info_columns
与 elements.treeview_info
没有通过 elements.liststore_info
相关联。看起来我只是缺少连接两者的步骤。 liststore_info
在 glade 文件中被列为 treeview_info
的模型,并在 GuiManager
的构造函数中设置。
断线在哪里?
我认为您需要设置每个 table 列中应显示的列表商店字段。
- 在 Glade 中,右键单击树小部件并单击 编辑...(不是 单独编辑)
- 单击层次结构 选项卡
- 点击一列
- 在属性和属性下确保勾选文本并从下拉列表中选择正确的列表存储列(这将更新相应的索引。)对于 Pixbuf 列,您需要 Pixbuf Object 而不是 Text.
- 对每一列重复
在你的情况下,我相信你最终应该为 Time 列索引 0,为 Message 列索引 1,在所有其他字段中索引为 -1。
这将从列表存储中的选定字段填充列的文本。我相信这样做是为了让您可以根据需要通过列表存储填充列的其他属性(字体、颜色等)。
与此无关,我也会考虑将 Gtk::TreeModelColumn<string>
更改为 Gtk::TreeModelColumn<Glib::ustring>
,因为我相信您现在使用它的方式可能会导致转换 to/from 到 Glib::ustring
树视图重新绘制自身的时间。从一开始就将其保持为 Glib::ustring
应该可以避免大部分这种转换。