gtk_list_store_new ()

功能:新建 ListStore控件
函数:

GtkListStore *
gtk_list_store_new (gint n_columns,
                    ...);

参数:

  • n_columns
    需要创建的列的个数;

  • 各个列的数据类型,多个列使用 , 分割

例如:

//创建一个GtkListStore控件,该控件有3列,对应的数据类型分别为:int, string and GdkPixbuf
gtk_tree_store_new (3, G_TYPE_INT, G_TYPE_STRING, GDK_TYPE_PIXBUF);

gtk_list_store_append ()

功能:向list store追加一个新行。
函数:

void
gtk_list_store_append (GtkListStore *list_store,
                       GtkTreeIter *iter);

参数:

  • list_store
    指向创建的 GtkListStore对象;
  • iter
    该参数的值记录新增的行号;
    在该函数被调用完毕之后,它将指向空;

为了填充新值,你需要调用gtk_list_store_set() or gtk_list_store_set_value()函数。

gtk_list_store_set ()

功能:
通过iter指向的行,向对应的一个或多个单元格设置对应的值。
函数:

void
gtk_list_store_set (GtkListStore *list_store,
                    GtkTreeIter *iter,
                    ...);

参数:

  • list_store
    指向创建的 GtkListStore对象;
  • iter
    指向新的行;

  • 此处传递的参数必须以”列索引(从0开始编号)和对应的值”成对出现,最终以 -1 表示结束;
    例如:
    想设置第0列的类型为G_TYPE_STRING,值为为”Foo”,则应该这样写:gtk_list_store_set (store, iter, 0, “Foo”, -1).
    如果值的类型为 G_TYPE_OBJECT ,那么它将被store引用;
    如果值的类型为 G_TYPE_STRING 或 G_TYPE_BOXED ,那么它将被复制;

示例:

效果:

ListStore - 图1

源码:

#include <gtk/gtk.h>

typedef struct
{
    gint iNum;
    gchar *pStr;
} WebItem;

const WebItem m_list[] = 
{ 
    {1, "www.softool.cn" }, 
    {2, "www.softool.cn" },
    {3, "www.softool.cn" },
    {4, "www.softool.cn" },
    {5, "www.softool.cn" },
    {6, "www.softool.cn" },
    //此处我用来标志结束,因为我在程序要判断 pStr是否为 NULL 来表示结束。
    {0, NULL }
};

static void setup_tree_view (GtkWidget*);

int main (int argc,
          char *argv[])
{
    GtkWidget *window, *treeview;
    GtkListStore *plstore;
    //用来记录 list store 新增的行句柄:
    GtkTreeIter iter;
    guint i = 0;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (window), "www.softool.cn - list store");
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
    gtk_widget_set_size_request (window, 250, 175);
    g_signal_connect (G_OBJECT (window), "destroy",
                    G_CALLBACK (gtk_main_quit), NULL);

    //新建一个 tree view 控件:
    treeview = gtk_tree_view_new ();
    setup_tree_view (treeview);

    /* 新建一个 list store 类型,它有2列,分别对应的数据类型为: gint 、string */
    plstore = gtk_list_store_new (2,    //2列
                                    G_TYPE_INT,        //第0列的数据类型为 gint
                                    G_TYPE_STRING    //第1列的数据类型为 string
                                );

    /* 向 list store 添加行数据 */
    while (m_list[i].pStr != NULL)
    {
        //让 plstore 追加一个新行,并将新增的行记录到 iter临时变量中:
        gtk_list_store_append (plstore, &iter);
        //向 plstore 模式的 iter指向的行的第0列和第1列设置对应的值:
        gtk_list_store_set (plstore, 
                                &iter, 
                                //向 plstore控件的 iter记录行的第 0 列设置的值为 m_list[i].iNum
                                0, m_list[i].iNum, 
                                //向 plstore控件的 iter记录行的第 1 列设置的值为 m_list[i].pStr
                                1, m_list[i].pStr,
                                //标记当前行设置结束
                                -1);

        i++;
    }

    //将上面新建的treeview控件的模式设置为 list store
    gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (plstore));
    /*以下注释内容,引用自:李先静 absurd
    *    引用计数是控制对象生命周期常用的手法,对象初始引用计数为一,引用一次计数加一,反引用一次计数减一,直到计数降为零时,对象被销毁。
    * GObject也实现了引用计数机制,g_object_ref函数用于引用,增加引用计数。
    * g_object_unref函数用于反引用,减少引用计数。
    */
    //此处的作用应该是在上面使用完 plstore对象之后,将其内存回收,防止内存泄露。
    g_object_unref (plstore);


    gtk_container_add (GTK_CONTAINER (window), treeview);
    gtk_widget_show_all (window);

    gtk_main ();
    return 0;
}

//向 treeview指向的控件增加2列,这2列都作为 text 显示。
static void setup_tree_view (GtkWidget *treeview)
{
    GtkCellRenderer *renderer;
    GtkTreeViewColumn *column;

    //第0列:
    //
    //gtk_cell_renderer_text_new () 
    //功能:创建一个新的 GtkCellRenderer对象。 
    //      通过object属性调整如何绘制文本,可以全局设置对象属性(使用g_object_set())。 
    //        同样,使用 GtkTreeViewColumn,您可以将属性绑定到 GtkTreeModel 其中的一个值。 
    //        例如,您可以将单元格渲染器上的“文本”属性绑定到model中的一个字符串值,从而在 GtkTreeView 的每一行中渲染一个不同的字符串。
    renderer = gtk_cell_renderer_text_new ();
    //新建一个 GtkTreeViewColumn列,新建的同时可以设置对应的各个属性。
    column = gtk_tree_view_column_new_with_attributes("序号",        //设置列的标题
                                                        renderer,    //上面新建的单元格渲染对象
                                                        //后续 ... 表示 renderer的属性, 以NULL来终止当前属性设置完毕。
                                                        "text",        //text 属性,可以用来渲染字符串内容。
                                                        0,             //我认为此处表示的是第 0 列
                                                        NULL        //表示当前属性设置完毕。
                                                        );
    //将上面新建的列添加到treeview控件中:
    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);

    //第1列:
    //
    renderer = gtk_cell_renderer_text_new ();
    column = gtk_tree_view_column_new_with_attributes("网址",    //第1列标题
                                                        renderer,
                                                        "text", 
                                                        1,            //我认为此处表示的是第 1 列
                                                        NULL);
    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
}

小结:

SofTool.CN Note:
本小结内容,属于个人想法,仅供参考。

通过上面的示例我们可以知道,GtkListStore 只是一种模式,不属于GtkWidget类型控件,所以要显示出来,就需要借助 treeview控件,间接放到 window控件来显示。 因为 treeview 和 window 都属于 GtkWidget同类型控件。


英文手册:
https://developer.gnome.org/gtk2/2.24/GtkListStore.html