Chinaunix首页 | 论坛 | 博客
  • 博客访问: 245163
  • 博文数量: 38
  • 博客积分: 517
  • 博客等级: 下士
  • 技术积分: 419
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-07 09:05
文章分类

全部博文(38)

文章存档

2018年(1)

2015年(1)

2014年(4)

2013年(11)

2012年(4)

2011年(17)

分类: LINUX

2011-12-14 17:42:34

GtkComboBox采用了模型-视图的模式实现,在程序中使用列表框时也按照这个思路会给开发带来极大的方便。如果只是需要简单的提供一个包含字符串的列表框,可直接使用GtkComboBoxText。示例代码如下,注释中有解释。示例代码中包含了三个方面的内容:
  1. 构建一个与GtkTreeModel关联的GtkComboBox示例。create_combobox_with_model函数。
  2. 添加列表项。add_item_clicked函数。
  3. 动态选择一个列表项。select_item_clicked函数。
构建GtkComboBox的思路:
  1. 列表框要显示的字符串们从哪来。它们存在于实现了GtkTreeModel接口的GtkListStore中,可以把它称为数据源。
  2. 用这个数据源创建一个GtkComboBox实例。
  3. 实例怎么显示这些字符串呢。使用GtkCellRendererText以文本显示。由于GtkComboBox实现了GtkCellLayout接口,因此用这个接口把GtkCellRendererText的示例跟列表框关联起来。
说明,我不知道如何在发布出来的文章中保留C的注释结构,因此改用C++的形式。
#include

// 使用GtkTreeModel作为下拉列表框的数据来源
static GtkWidget *create_combobox_with_model()
{
    GtkWidget *combobox = NULL;
    GtkListStore *store = NULL;
    GtkTreeIter iter;
    GtkCellRenderer *renderer = NULL;

    // 填充数据。在这里只需要一列字符串。
    store = gtk_list_store_new(1, G_TYPE_STRING);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, 0, "home", -1);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, 0, "work", -1);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, 0, "public", -1);

    combobox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
    // 设置GtkTreeModel中的每一项数据如何在列表框中显示
    renderer = gtk_cell_renderer_text_new();
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, TRUE);
    gtk_cell_layout_set_attributes(
        GTK_CELL_LAYOUT(combobox), renderer, "text", 0, NULL);
    return combobox;
}

static void
add_item_clicked(GtkWidget *sender, gpointer data)
{
    GtkWidget *combobox;
    GtkTreeModel *model;
    GtkTreeIter iter;

    // 给列表框添加一个新条目,实际上就是给它背后的GtkTreeModel增加一个数据项。
    // 这是GTK+的模型-视图模式带来的巨大好处。类似也能用在GtkTreeView中,等等。
    combobox = (GtkWidget *)data;
    model = gtk_combo_box_get_model(GTK_COMBO_BOX(combobox));
    gtk_list_store_append(GTK_LIST_STORE(model), &iter);
    gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, "new item", -1);
}

// 假设:能找到要选择的列表项。
static void
select_item_clicked(GtkWidget *sender, gpointer data)
{
    GtkWidget *combobox;
    GtkTreeModel *model;
    GtkTreeIter iter;
    gchar *text = NULL;
    gboolean end_search = FALSE;

    combobox = (GtkWidget *)data;

    // 先从model中找到要选择的字符串,用iter记住位置
    model = gtk_combo_box_get_model(GTK_COMBO_BOX(combobox));
    if (gtk_tree_model_get_iter_first(model, &iter))
    {
        do
        {
            gtk_tree_model_get(model, &iter, 0, &text, -1);
            end_search = g_strcmp0(text, "work") == 0;
            g_free(text);
        }
        while (!end_search && gtk_tree_model_iter_next(model, &iter));
    }

    // 用iter选择那一项。
    gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combobox), &iter);
}

int main(int argc, char *argv[])
{
    GtkWidget *dialog, *box, *button, *combobox;

    gtk_init(&argc, &argv);

    dialog = gtk_dialog_new_with_buttons(
            "Test GtkComboBox",
            NULL,
            GTK_DIALOG_MODAL,
            GTK_STOCK_OK, GTK_RESPONSE_OK,
            NULL);

    // 作为演示,首先在对话框的内容区域(content_area)添加一个GtkComboBox。
    // 然后,在行为区域(action_area)添加两个额外的按钮,
    // 一个用于添加新条目,另一个用于选择某个条目。
    box = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
    combobox = create_combobox_with_model();
    gtk_box_pack_start(GTK_BOX(box), combobox, TRUE, TRUE, 3);

    button = gtk_button_new_with_label("Add item");
    box = gtk_dialog_get_action_area(GTK_DIALOG(dialog));
    gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0);
    g_signal_connect(
        G_OBJECT(button), "clicked",
        G_CALLBACK(add_item_clicked), combobox);

    button = gtk_button_new_with_label("Select work");
    gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0);
    g_signal_connect(
        G_OBJECT(button), "clicked",
        G_CALLBACK(select_item_clicked), combobox);

    gtk_widget_show_all(dialog);
    // 忽略对话框的返回值
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
    return 0;
}
阅读(2742) | 评论(0) | 转发(0) |
0

上一篇:按扭构件

下一篇:GTK+中的构件

给主人留下些什么吧!~~