我一直在自学如何用 C 编写代码并利用 GTK 在 Linux 中编写应用程序,在实现之前使用 Glade 设计 UI。我一直在尝试利用 GtkTreeView 和 GtkListStore 来显示数据,但我似乎遇到了问题。我可以让我的应用程序正常启动并正确显示窗口和对话框,但我无法弄清楚如何以编程方式将数据行添加到列表存储并让它们出现在树视图中;我发现的大多数教程似乎更喜欢在 Glade 中制作行,或者通过代码设计整个界面。使用代码原样运行程序时,我没有收到任何错误,但我看不到在 GtkTreeView 中添加任何内容。我也没有看到任何空白行被添加。
通过编写一些代码强制生成错误,我可以看到postingButton
正在连接的信号(我认为)所以应该没问题。我只是在 GtkTreeView 的实际实现中遗漏了一些东西。如果有人可以帮助我,我将不胜感激!
编辑:存在的 GtkEntries 将在稍后实施;我只是想让数据显示出来。
C代码:
/* I'd give objects better names normally, no worries!
* Just goofing around for now.*/
#include <gtk-3.0/gtk/gtk.h> // Needed for interface.
#include <gtk-3.0/gdk/gdk.h>
#include <glib-2.0/glib-object.h>
void on_mainWindow_destroy(GObject *object, gpointer user_data)
{
gtk_main_quit();
}
void on_stupidButton_clicked(GtkButton *button, gpointer *user_data)
{
gtk_dialog_run(GTK_DIALOG(user_data));
}
void on_postingButton_clicked(GtkButton *button, gpointer *user_data)
{
GtkListStore *liststore1;
GtkWidget *treeview1; // I've tried defining this as a GtkTreeView as well.
GtkTreeIter iter;
GtkBuilder *listStoreBuilder;
listStoreBuilder = gtk_builder_new();
gtk_builder_add_from_file(listStoreBuilder,
"../testing_interface.glade", 0);
treeview1 = GTK_WIDGET(gtk_builder_get_object(listStoreBuilder,
"treeview1")); // I'd change this to GTK_TREE_VIEW if the
// above is a GtkTreeView.
liststore1 = GTK_LIST_STORE(
gtk_tree_view_get_model((GtkTreeView *)treeview1));
gtk_list_store_append(liststore1, &iter);
gtk_list_store_set(liststore1, &iter, 0, "c", 1, "d", -1);
gtk_builder_connect_signals(listStoreBuilder, 0);
g_object_unref(G_OBJECT(listStoreBuilder));
g_object_unref(G_OBJECT(liststore1));
}
void on_cancelButton_clicked(GtkButton *button, gpointer *user_data)
{
gtk_widget_destroy((GtkWidget *)user_data);
}
int main(int argc, char *argv[])
{
GtkBuilder *builder;
GtkWidget *mainWindow, *dumbDialog;
GtkButton *stupidButton;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "../testing_interface.glade",
0);
mainWindow = GTK_WIDGET(gtk_builder_get_object(builder, "mainWindow"));
stupidButton = GTK_BUTTON(gtk_builder_get_object(builder, "stupidButton"));
dumbDialog = GTK_WIDGET(gtk_builder_get_object(builder, "dumbDialog"));
gtk_builder_connect_signals(builder, 0);
g_object_unref(G_OBJECT(builder));
gtk_widget_show(mainWindow);
gtk_main();
return 0;
}
林间空地文件(testing_interface.glade):
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkDialog" id="dumbDialog">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="postingButton">
<property name="label" translatable="yes">Post</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_postingButton_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="cancelButton">
<property name="label" translatable="yes">Cancel</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_cancelButton_clicked" object="dumbDialog" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkEntry" id="entry1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">postingButton</action-widget>
<action-widget response="0">cancelButton</action-widget>
</action-widgets>
</object>
<object class="GtkListStore" id="liststore1">
<columns>
<!-- column-name Testing -->
<column type="gchararray"/>
<!-- column-name Testing1 -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkWindow" id="mainWindow">
<property name="can_focus">False</property>
<signal name="destroy" handler="on_mainWindow_destroy" swapped="no"/>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkTreeView" id="treeview1">
<property name="height_request">183</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">liststore1</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="testing1Col">
<property name="title" translatable="yes">column</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext1"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="testing2Col">
<property name="title" translatable="yes">column</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext2"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="stupidButton">
<property name="label" translatable="yes">button</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="on_stupidButton_clicked" object="dumbDialog" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>