gtk-demo中的例子都是在一个框架中的,如果想自己单拿出来运行,要添加主函数,大多如下:
- int
- main(int argc, char **argv)
- {
- GtkWidget *window;
- gtk_init(&argc, &argv);
- window = demo-入口函数(NULL);
- g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
- gtk_main();
- return 0;
- }
- #include <gtk/gtk.h>
- #include <string.h>
- #include <stdlib.h>
- static GtkWidget *window = NULL;
- typedef struct
- {
- gint number;
- gchar *product;
- gint yummy;
- }
- Item;
- enum
- {
- COLUMN_ITEM_NUMBER,
- COLUMN_ITEM_PRODUCT,
- COLUMN_ITEM_YUMMY,
- NUM_ITEM_COLUMNS
- };
- enum
- {
- COLUMN_NUMBER_TEXT,
- NUM_NUMBER_COLUMNS
- };
- static GArray *articles = NULL;
- static void
- add_items (void)
- {
- Item foo;
- g_return_if_fail (articles != NULL);
- foo.number = 3;
- foo.product = g_strdup ("bottles of coke");
- foo.yummy = 20;
- g_array_append_vals (articles, &foo, 1);
- foo.number = 5;
- foo.product = g_strdup ("packages of noodles");
- foo.yummy = 50;
- g_array_append_vals (articles, &foo, 1);
- foo.number = 2;
- foo.product = g_strdup ("packages of chocolate chip cookies");
- foo.yummy = 90;
- g_array_append_vals (articles, &foo, 1);
- foo.number = 1;
- foo.product = g_strdup ("can vanilla ice cream");
- foo.yummy = 60;
- g_array_append_vals (articles, &foo, 1);
- foo.number = 6;
- foo.product = g_strdup ("eggs");
- foo.yummy = 10;
- g_array_append_vals (articles, &foo, 1);
- }
- static GtkTreeModel *
- create_items_model (void)
- {
- gint i = 0;
- GtkListStore *model;
- GtkTreeIter iter;
- /* create array */
- articles = g_array_sized_new (FALSE, FALSE, sizeof (Item), 1);
- add_items ();
- /* create list store */
- model = gtk_list_store_new (NUM_ITEM_COLUMNS, G_TYPE_INT, G_TYPE_STRING,
- G_TYPE_INT, G_TYPE_BOOLEAN);
- /* add items */
- for (i = 0; i < articles->len; i++)
- {
- gtk_list_store_append (model, &iter);
- gtk_list_store_set (model, &iter,
- COLUMN_ITEM_NUMBER,
- g_array_index (articles, Item, i).number,
- COLUMN_ITEM_PRODUCT,
- g_array_index (articles, Item, i).product,
- COLUMN_ITEM_YUMMY,
- g_array_index (articles, Item, i).yummy,
- -1);
- }
- return GTK_TREE_MODEL (model);
- }
- static GtkTreeModel *
- create_numbers_model (void)
- {
- #define N_NUMBERS 10
- gint i = 0;
- GtkListStore *model;
- GtkTreeIter iter;
- /* create list store */
- model = gtk_list_store_new (NUM_NUMBER_COLUMNS, G_TYPE_STRING, G_TYPE_INT);
- /* add numbers */
- for (i = 0; i < N_NUMBERS; i++)
- {
- char str[2];
- str[0] = '0' + i;
- str[1] = '\0';
- gtk_list_store_append (model, &iter);
- gtk_list_store_set (model, &iter,
- COLUMN_NUMBER_TEXT, str,
- -1);
- }
- return GTK_TREE_MODEL (model);
- #undef N_NUMBERS
- }
- static void
- add_item (GtkWidget *button, gpointer data)
- {
- Item foo;
- GtkTreeIter iter;
- GtkTreeModel *model = (GtkTreeModel *)data;
- g_return_if_fail (articles != NULL);
- foo.number = 0;
- foo.product = g_strdup ("Description here");
- foo.yummy = 50;
- g_array_append_vals (articles, &foo, 1);
- gtk_list_store_append (GTK_LIST_STORE (model), &iter);
- gtk_list_store_set (GTK_LIST_STORE (model), &iter,
- COLUMN_ITEM_NUMBER, foo.number,
- COLUMN_ITEM_PRODUCT, foo.product,
- COLUMN_ITEM_YUMMY, foo.yummy,
- -1);
- }
- static void
- remove_item (GtkWidget *widget, gpointer data)
- {
- GtkTreeIter iter;
- GtkTreeView *treeview = (GtkTreeView *)data;
- GtkTreeModel *model = gtk_tree_view_get_model (treeview);
- GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
- if (gtk_tree_selection_get_selected (selection, NULL, &iter))
- {
- gint i;
- GtkTreePath *path;
- path = gtk_tree_model_get_path (model, &iter);
- i = gtk_tree_path_get_indices (path)[0];
- gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
- g_array_remove_index (articles, i);
- gtk_tree_path_free (path);
- }
- }
- static gboolean
- separator_row (GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer data)
- {
- GtkTreePath *path;
- gint idx;
- path = gtk_tree_model_get_path (model, iter);
- idx = gtk_tree_path_get_indices (path)[0];
- gtk_tree_path_free (path);
- return idx == 5;
- }
- static void
- editing_started (GtkCellRenderer *cell,
- GtkCellEditable *editable,
- const gchar *path,
- gpointer data)
- {
- gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (editable),
- separator_row, NULL, NULL);
- }
- static void
- cell_edited (GtkCellRendererText *cell,
- const gchar *path_string,
- const gchar *new_text,
- gpointer data)
- {
- GtkTreeModel *model = (GtkTreeModel *)data;
- GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
- GtkTreeIter iter;
- gint column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "column"));
- gtk_tree_model_get_iter (model, &iter, path);
- switch (column)
- {
- case COLUMN_ITEM_NUMBER:
- {
- gint i;
- i = gtk_tree_path_get_indices (path)[0];
- g_array_index (articles, Item, i).number = atoi (new_text);
- gtk_list_store_set (GTK_LIST_STORE (model), &iter, column,
- g_array_index (articles, Item, i).number, -1);
- }
- break;
- case COLUMN_ITEM_PRODUCT:
- {
- gint i;
- gchar *old_text;
- gtk_tree_model_get (model, &iter, column, &old_text, -1);
- g_free (old_text);
- i = gtk_tree_path_get_indices (path)[0];
- g_free (g_array_index (articles, Item, i).product);
- g_array_index (articles, Item, i).product = g_strdup (new_text);
- gtk_list_store_set (GTK_LIST_STORE (model), &iter, column,
- g_array_index (articles, Item, i).product, -1);
- }
- break;
- }
- gtk_tree_path_free (path);
- }
- static void
- add_columns (GtkTreeView *treeview,
- GtkTreeModel *items_model,
- GtkTreeModel *numbers_model)
- {
- GtkCellRenderer *renderer;
- /* number column */
- renderer = gtk_cell_renderer_combo_new ();
- g_object_set (renderer,
- "model", numbers_model,
- "text-column", COLUMN_NUMBER_TEXT,
- "has-entry", FALSE,
- "editable", TRUE,
- NULL);
- g_signal_connect (renderer, "edited",
- G_CALLBACK (cell_edited), items_model);
- g_signal_connect (renderer, "editing-started",
- G_CALLBACK (editing_started), NULL);
- g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_ITEM_NUMBER));
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
- -1, "Number", renderer,
- "text", COLUMN_ITEM_NUMBER,
- NULL);
- /* product column */
- renderer = gtk_cell_renderer_text_new ();
- g_object_set (renderer,
- "editable", TRUE,
- NULL);
- g_signal_connect (renderer, "edited",
- G_CALLBACK (cell_edited), items_model);
- g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_ITEM_PRODUCT));
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
- -1, "Product", renderer,
- "text", COLUMN_ITEM_PRODUCT,
- NULL);
- /* yummy column */
- renderer = gtk_cell_renderer_progress_new ();
- g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_ITEM_YUMMY));
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
- -1, "Yummy", renderer,
- "value", COLUMN_ITEM_YUMMY,
- NULL);
- }
- GtkWidget *
- do_editable_cells (GtkWidget *do_widget)
- {
- if (!window)
- {
- GtkWidget *vbox;
- GtkWidget *hbox;
- GtkWidget *sw;
- GtkWidget *treeview;
- GtkWidget *button;
- GtkTreeModel *items_model;
- GtkTreeModel *numbers_model;
- /* create window, etc */
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_screen (GTK_WINDOW (window),
- gtk_widget_get_screen (do_widget));
- gtk_window_set_title (GTK_WINDOW (window), "Shopping list");
- gtk_container_set_border_width (GTK_CONTAINER (window), 5);
- g_signal_connect (window, "destroy",
- G_CALLBACK (gtk_widget_destroyed), &window);
- vbox = gtk_vbox_new (FALSE, 5);
- gtk_container_add (GTK_CONTAINER (window), vbox);
- gtk_box_pack_start (GTK_BOX (vbox),
- gtk_label_new ("Shopping list (you can edit the cells!)"),
- FALSE, FALSE, 0);
- sw = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
- GTK_SHADOW_ETCHED_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
- /* create models */
- items_model = create_items_model ();
- numbers_model = create_numbers_model ();
- /* create tree view */
- treeview = gtk_tree_view_new_with_model (items_model);
- gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
- gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
- GTK_SELECTION_SINGLE);
- add_columns (GTK_TREE_VIEW (treeview), items_model, numbers_model);
- g_object_unref (numbers_model);
- g_object_unref (items_model);
- gtk_container_add (GTK_CONTAINER (sw), treeview);
- /* some buttons */
- hbox = gtk_hbox_new (TRUE, 4);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
- button = gtk_button_new_with_label ("Add item");
- g_signal_connect (button, "clicked",
- G_CALLBACK (add_item), items_model);
- gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
- button = gtk_button_new_with_label ("Remove item");
- g_signal_connect (button, "clicked",
- G_CALLBACK (remove_item), treeview);
- gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
- gtk_window_set_default_size (GTK_WINDOW (window), 320, 200);
- }
- if (!GTK_WIDGET_VISIBLE (window))
- gtk_widget_show_all (window);
- else
- {
- gtk_widget_destroy (window);
- window = NULL;
- }
- return window;
- }
- int
- main(int argc, char **argv)
- {
- GtkWidget *window;
- gtk_init(&argc, &argv);
- window = do_editable_cells(NULL);
- g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
- gtk_main();
- return 0;
- }
- gcc `pkg-config --libs --cflags gtk+-2.0` -o t_editable_cells t_editable_cells.c