|
|
Строка 1: |
Строка 1: |
- | In this part of the GTK+ programming tutorial, we will work with a GtkTreeView widget.
| |
| | | |
- | <b>GtkTreeView</b> widget is a complex widget which can be used to display lists and trees.
| |
- | The widget can have one or multiple columns. The GtkTreeView widget has a MVC (Model View Controller) design architecture.
| |
- | This means, that the data is separated from the view.
| |
- |
| |
- | There are several other objects that are used with the GtkTreeView widget.
| |
- | The <b>GtkCellRenderer</b> determines, how the data is going to be displayed in the <b>GtkTreeViewColumn</b>.
| |
- | The <b>GtkTreeStore</b> represent the model. They handle data, that are displayed in the GtkTreeView widget. <b>GtkTreeIter</b> is a structure used to refer to a row in the GtkTreeView.
| |
- |
| |
- | <b>GtkTreeSelection</b> is a an object that handles selections.
| |
- |
| |
- | == Simple List View ==
| |
- |
| |
- | The first example will show a simple list view. We will display textual data.
| |
- |
| |
- | <source lang="cpp">
| |
- | #include <gtk/gtk.h>
| |
- |
| |
- | enum
| |
- | {
| |
- | LIST_ITEM = 0,
| |
- | N_COLUMNS
| |
- | };
| |
- |
| |
- | static void
| |
- | init_list(GtkWidget *list)
| |
- | {
| |
- |
| |
- | GtkCellRenderer *renderer;
| |
- | GtkTreeViewColumn *column;
| |
- | GtkListStore *store;
| |
- |
| |
- | renderer = gtk_cell_renderer_text_new();
| |
- | column = gtk_tree_view_column_new_with_attributes("List Items",
| |
- | renderer, "text", LIST_ITEM, NULL);
| |
- | gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
| |
- |
| |
- | store = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING);
| |
- |
| |
- | gtk_tree_view_set_model(GTK_TREE_VIEW(list),
| |
- | GTK_TREE_MODEL(store));
| |
- |
| |
- | g_object_unref(store);
| |
- | }
| |
- |
| |
- | static void
| |
- | add_to_list(GtkWidget *list, const gchar *str)
| |
- | {
| |
- | GtkListStore *store;
| |
- | GtkTreeIter iter;
| |
- |
| |
- | store = GTK_LIST_STORE(gtk_tree_view_get_model
| |
- | (GTK_TREE_VIEW(list)));
| |
- |
| |
- | gtk_list_store_append(store, &iter);
| |
- | gtk_list_store_set(store, &iter, LIST_ITEM, str, -1);
| |
- | }
| |
- |
| |
- |
| |
- | void on_changed(GtkWidget *widget, gpointer label)
| |
- | {
| |
- | GtkTreeIter iter;
| |
- | GtkTreeModel *model;
| |
- | char *value;
| |
- |
| |
- |
| |
- | if (gtk_tree_selection_get_selected(
| |
- | GTK_TREE_SELECTION(widget), &model, &iter)) {
| |
- |
| |
- | gtk_tree_model_get(model, &iter, LIST_ITEM, &value, -1);
| |
- | gtk_label_set_text(GTK_LABEL(label), value);
| |
- | g_free(value);
| |
- | }
| |
- |
| |
- | }
| |
- |
| |
- | int main (int argc, char *argv[])
| |
- | {
| |
- |
| |
- | GtkWidget *window;
| |
- | GtkWidget *list;
| |
- |
| |
- | GtkWidget *vbox;
| |
- | GtkWidget *label;
| |
- | GtkTreeSelection *selection;
| |
- |
| |
- | gtk_init(&argc, &argv);
| |
- |
| |
- |
| |
- | window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
| |
- | gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
| |
- | gtk_container_set_border_width(GTK_CONTAINER(window), 10);
| |
- | gtk_widget_set_size_request(window, 270, 250);
| |
- | gtk_window_set_title(GTK_WINDOW(window), "List View");
| |
- |
| |
- | list = gtk_tree_view_new();
| |
- | gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE);
| |
- |
| |
- | vbox = gtk_vbox_new(FALSE, 0);
| |
- |
| |
- | gtk_box_pack_start(GTK_BOX(vbox), list, TRUE, TRUE, 5);
| |
- |
| |
- | label = gtk_label_new("");
| |
- | gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
| |
- | gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 5);
| |
- |
| |
- | gtk_container_add(GTK_CONTAINER(window), vbox);
| |
- |
| |
- | init_list(list);
| |
- | add_to_list(list, "Aliens");
| |
- | add_to_list(list, "Leon");
| |
- | add_to_list(list, "Capote");
| |
- | add_to_list(list, "Saving private Ryan");
| |
- | add_to_list(list, "Der Untergang");
| |
- |
| |
- |
| |
- | selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
| |
- |
| |
- | g_signal_connect(selection, "changed",
| |
- | G_CALLBACK(on_changed), label);
| |
- |
| |
- | g_signal_connect(G_OBJECT (window), "destroy",
| |
- | G_CALLBACK(gtk_main_quit), NULL);
| |
- |
| |
- | gtk_widget_show_all(window);
| |
- |
| |
- | gtk_main ();
| |
- |
| |
- | return 0;
| |
- | }
| |
- | </source>
| |
- |
| |
- | In our code example, we will show 5 items in the GtkTreeView.
| |
- | We will have only one column and the header of the column will be hidden.
| |
- | We will place a <b>GtkVBox</b> into the window. This box will have two widgets. A
| |
- |
| |
- | <b>GtkLabel</b>.
| |
- |
| |
- | <source lang="cpp">
| |
- | list = gtk_tree_view_new();
| |
- | gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE);
| |
- | </source>
| |
- |
| |
- | The <b>GtkTreeView</b> is created and the columns are hidden.
| |
- |
| |
- | <source lang="cpp">
| |
- | label = gtk_label_new("");
| |
- | gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
| |
- | gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 5);
| |
- | </source>
| |
- |
| |
- | The <b>GtkTreeView</b>
| |
- |
| |
- | <source lang="cpp">
| |
- |
| |
- | init_list(list);
| |
- | </source>
| |
- |
| |
- | This function initializes the list.
| |
- |
| |
- | <source lang="cpp">
| |
- | renderer = gtk_cell_renderer_text_new();
| |
- | column = gtk_tree_view_column_new_with_attributes("List Items",
| |
- | renderer, "text", LIST_ITEM, NULL);
| |
- | gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
| |
- | </source>
| |
- |
| |
- | Inside that function, we create and append one single column.
| |
- |
| |
- | <source lang="cpp">
| |
- | store = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING);
| |
- |
| |
- | gtk_tree_view_set_model(GTK_TREE_VIEW(list),
| |
- | GTK_TREE_MODEL(store));
| |
- | </source>
| |
- |
| |
- | We create a <b>GtkListStore</b> (a model) and set it to the list.
| |
- |
| |
- | <source lang="cpp">
| |
- | g_object_unref(store);
| |
- | </source>
| |
- |
| |
- | The model is destroyed automatically with the view.
| |
- |
| |
- | <source lang="cpp">
| |
- | add_to_list(list, "Aliens");
| |
- | </source>
| |
- |
| |
- | This user function adds an option to the list.
| |
- |
| |
- | <source lang="cpp">
| |
- | store = GTK_LIST_STORE(gtk_tree_view_get_model
| |
- | (GTK_TREE_VIEW(list)));
| |
- |
| |
- | gtk_list_store_append(store, &iter);
| |
- | gtk_list_store_set(store, &iter, LIST_ITEM, str, -1);
| |
- |
| |
- | </source>
| |
- |
| |
- | Inside the <b>gtk_tree_view_get_model()</b> function call. We append a new row and set a value to the row, which is reference by an <b>GtkTreeIter</b> object.
| |
- |
| |
- | <source lang="cpp">
| |
- | selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
| |
- |
| |
- | </source>
| |
- |
| |
- | The <b>GtkTreeSelection</b> need not to be created explicitely. It is automatically created with the <b>GtkTreeView</b> widget. The reference to the widget is obtained using the <b>gtk_tree_view_get_selection()</b> function call.
| |
- |
| |
- | <source lang="cpp">
| |
- | g_signal_connect(selection, "changed",
| |
- | G_CALLBACK(on_changed), label);
| |
- |
| |
- | </source>
| |
- |
| |
- | Upon change signal of the <b>on_changed()</b> handler.
| |
- |
| |
- | <source lang="cpp">
| |
- | gtk_tree_model_get(model, &iter, LIST_ITEM, &value, -1);
| |
- | gtk_label_set_text(GTK_LABEL(label), value);
| |
- | </source>
| |
- |
| |
- | Inside the handler function, we get the value of the cell in the row referenced by the iter object.
| |
- |
| |
- | [[image: gtk_faq_listview.png | center]]
| |
- |
| |
- | == Advanced List View ==
| |
- |
| |
- | The second example will add additional functionality to the previous one. We will be able to add and remove items from the list view.
| |
- |
| |
- | <source lang="cpp">
| |
- | #include <gtk/gtk.h>
| |
- |
| |
- | enum
| |
- | {
| |
- | LIST_ITEM = 0,
| |
- | N_COLUMNS
| |
- | };
| |
- |
| |
- | GtkWidget *list;
| |
- |
| |
- |
| |
- | static void
| |
- | append_item(GtkWidget *widget, gpointer entry)
| |
- | {
| |
- | GtkListStore *store;
| |
- | GtkTreeIter iter;
| |
- |
| |
- | const char *str = gtk_entry_get_text(entry);
| |
- |
| |
- | store = GTK_LIST_STORE(gtk_tree_view_get_model(
| |
- | GTK_TREE_VIEW(list)));
| |
- |
| |
- | gtk_list_store_append(store, &iter);
| |
- | gtk_list_store_set(store, &iter, LIST_ITEM, str, -1);
| |
- | }
| |
- |
| |
- | static void
| |
- | remove_item(GtkWidget *widget, gpointer selection)
| |
- | {
| |
- | GtkListStore *store;
| |
- | GtkTreeModel *model;
| |
- | GtkTreeIter iter;
| |
- |
| |
- |
| |
- | store = GTK_LIST_STORE(gtk_tree_view_get_model(
| |
- | GTK_TREE_VIEW (list)));
| |
- | model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
| |
- |
| |
- | if (gtk_tree_model_get_iter_first(model, &iter) == FALSE)
| |
- | return;
| |
- |
| |
- | if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection),
| |
- | &model, &iter)) {
| |
- | gtk_list_store_remove(store, &iter);
| |
- | }
| |
- | }
| |
- |
| |
- | static void
| |
- | remove_all(GtkWidget *widget, gpointer selection)
| |
- | {
| |
- | GtkListStore *store;
| |
- | GtkTreeModel *model;
| |
- | GtkTreeIter iter;
| |
- |
| |
- |
| |
- | store = GTK_LIST_STORE(gtk_tree_view_get_model(
| |
- | GTK_TREE_VIEW (list)));
| |
- | model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
| |
- |
| |
- | if (gtk_tree_model_get_iter_first(model, &iter) == FALSE)
| |
- | return;
| |
- | gtk_list_store_clear(store);
| |
- | }
| |
- |
| |
- | static void
| |
- | init_list(GtkWidget *list)
| |
- | {
| |
- |
| |
- | GtkCellRenderer *renderer;
| |
- | GtkTreeViewColumn *column;
| |
- | GtkListStore *store;
| |
- |
| |
- | renderer = gtk_cell_renderer_text_new();
| |
- | column = gtk_tree_view_column_new_with_attributes("List Item",
| |
- | renderer, "text", LIST_ITEM, NULL);
| |
- | gtk_tree_view_append_column(GTK_TREE_VIEW (list), column);
| |
- |
| |
- | store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING);
| |
- |
| |
- | gtk_tree_view_set_model(GTK_TREE_VIEW (list),
| |
- | GTK_TREE_MODEL(store));
| |
- |
| |
- | g_object_unref(store);
| |
- | }
| |
- |
| |
- |
| |
- | int main (int argc, char *argv[])
| |
- | {
| |
- |
| |
- | GtkWidget *window;
| |
- | GtkWidget *sw;
| |
- |
| |
- | GtkWidget *remove;
| |
- | GtkWidget *add;
| |
- | GtkWidget *removeAll;
| |
- | GtkWidget *entry;
| |
- |
| |
- | GtkWidget *vbox;
| |
- | GtkWidget *hbox;
| |
- |
| |
- | GtkTreeSelection *selection;
| |
- |
| |
- | gtk_init(&argc, &argv);
| |
- |
| |
- |
| |
- | window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
| |
- | sw = gtk_scrolled_window_new(NULL, NULL);
| |
- | list = gtk_tree_view_new();
| |
- |
| |
- | gtk_window_set_title (GTK_WINDOW (window), "List View");
| |
- | gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
| |
- | gtk_container_set_border_width (GTK_CONTAINER (window), 10);
| |
- | gtk_widget_set_size_request (window, 370, 270);
| |
- |
| |
- | gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(sw),
| |
- | GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
| |
- |
| |
- | gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw),
| |
- | GTK_SHADOW_ETCHED_IN);
| |
- |
| |
- | gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list), FALSE);
| |
- |
| |
- | vbox = gtk_vbox_new(FALSE, 0);
| |
- |
| |
- | gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 5);
| |
- |
| |
- | hbox = gtk_hbox_new(TRUE, 5);
| |
- |
| |
- | add = gtk_button_new_with_label("Add");
| |
- | remove = gtk_button_new_with_label("Remove");
| |
- | removeAll = gtk_button_new_with_label("Remove All");
| |
- | entry = gtk_entry_new();
| |
- |
| |
- | gtk_box_pack_start(GTK_BOX(hbox), add, FALSE, TRUE, 3);
| |
- | gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, TRUE, 3);
| |
- | gtk_box_pack_start(GTK_BOX(hbox), remove, FALSE, TRUE, 3);
| |
- | gtk_box_pack_start(GTK_BOX(hbox), removeAll, FALSE, TRUE, 3);
| |
- |
| |
- | gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 3);
| |
- |
| |
- | gtk_container_add(GTK_CONTAINER (sw), list);
| |
- | gtk_container_add(GTK_CONTAINER (window), vbox);
| |
- |
| |
- | init_list(list);
| |
- |
| |
- | selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
| |
- |
| |
- | g_signal_connect(G_OBJECT(add), "clicked",
| |
- | G_CALLBACK(append_item), entry);
| |
- |
| |
- | g_signal_connect(G_OBJECT(remove), "clicked",
| |
- | G_CALLBACK(remove_item), selection);
| |
- |
| |
- | g_signal_connect(G_OBJECT(removeAll), "clicked",
| |
- | G_CALLBACK(remove_all), selection);
| |
- |
| |
- | g_signal_connect (G_OBJECT (window), "destroy",
| |
- | G_CALLBACK(gtk_main_quit), NULL);
| |
- |
| |
- | gtk_widget_show_all(window);
| |
- |
| |
- | gtk_main ();
| |
- |
| |
- | return 0;
| |
- | }
| |
- |
| |
- | </source>
| |
- |
| |
- | Instead of a label, we create three buttons and one text entry. We will be able to add a new option dynamically and remove the currently selected option or remove all list items.
| |
- |
| |
- | <source lang="cpp">
| |
- | sw = gtk_scrolled_window_new(NULL, NULL);
| |
- | ...
| |
- |
| |
- | gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(sw),
| |
- | GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
| |
- |
| |
- | gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw),
| |
- | GTK_SHADOW_ETCHED_IN);
| |
- |
| |
- | ...
| |
- | gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 5);
| |
- | ...
| |
- | gtk_container_add(GTK_CONTAINER (sw), list);
| |
- | </source>
| |
- |
| |
- | The <b>GtkTreeView</b> is placed inside the scrolled window.
| |
- |
| |
- | <source lang="cpp">
| |
- | if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection),
| |
- | &model, &iter)) {
| |
- | gtk_list_store_remove(store, &iter);
| |
- | }
| |
- | </source>
| |
- |
| |
- | The <b>gtk_list_store_remove()</b> function removes an item from the list.
| |
- |
| |
- | <source lang="cpp">
| |
- | gtk_list_store_clear(store);
| |
- |
| |
- | </source>
| |
- |
| |
- | The <b>gtk_list_store_clear()</b> will remove all items from the list.
| |
- |
| |
- | <source lang="cpp">
| |
- | if (gtk_tree_model_get_iter_first(model, &iter) == FALSE)
| |
- | return;
| |
- | </source>
| |
- |
| |
- | This code checks if there is some item left in the list. Obviosly, we can remove items only if there is at least one left in the list.
| |
- |
| |
- | [[image: gtk_faq_manage.png | center]]
| |
- |
| |
- | == Tree View ==
| |
- |
| |
- | Next we will use the <b>GtkTreeView</b> widget to display hierarchical data. In the previous two examples, we used the list view, now we are going to use tree view.
| |
- |
| |
- | <source lang="cpp">
| |
- | #include <gtk/gtk.h>
| |
- |
| |
- | enum
| |
- | {
| |
- | COLUMN = 0,
| |
- | NUM_COLS
| |
- | } ;
| |
- |
| |
- | void on_changed(GtkWidget *widget, gpointer statusbar)
| |
- | {
| |
- | GtkTreeIter iter;
| |
- | GtkTreeModel *model;
| |
- | char *value;
| |
- |
| |
- |
| |
- | if (gtk_tree_selection_get_selected(
| |
- | GTK_TREE_SELECTION(widget), &model, &iter)) {
| |
- |
| |
- | gtk_tree_model_get(model, &iter, COLUMN, &value, -1);
| |
- | gtk_statusbar_push(GTK_STATUSBAR(statusbar),
| |
- | gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbar),
| |
- | value), value);
| |
- | g_free(value);
| |
- | }
| |
- | }
| |
- |
| |
- |
| |
- | static GtkTreeModel *
| |
- | create_and_fill_model (void)
| |
- | {
| |
- | GtkTreeStore *treestore;
| |
- | GtkTreeIter toplevel, child;
| |
- |
| |
- | treestore = gtk_tree_store_new(NUM_COLS,
| |
- | G_TYPE_STRING);
| |
- |
| |
- | gtk_tree_store_append(treestore, &toplevel, NULL);
| |
- | gtk_tree_store_set(treestore, &toplevel,
| |
- | COLUMN, "Scripting languages",
| |
- | -1);
| |
- |
| |
- | gtk_tree_store_append(treestore, &child, &toplevel);
| |
- | gtk_tree_store_set(treestore, &child,
| |
- | COLUMN, "Python",
| |
- | -1);
| |
- | gtk_tree_store_append(treestore, &child, &toplevel);
| |
- | gtk_tree_store_set(treestore, &child,
| |
- | COLUMN, "Perl",
| |
- | -1);
| |
- | gtk_tree_store_append(treestore, &child, &toplevel);
| |
- | gtk_tree_store_set(treestore, &child,
| |
- | COLUMN, "PHP",
| |
- | -1);
| |
- |
| |
- | gtk_tree_store_append(treestore, &toplevel, NULL);
| |
- | gtk_tree_store_set(treestore, &toplevel,
| |
- | COLUMN, "Compiled languages",
| |
- | -1);
| |
- |
| |
- | gtk_tree_store_append(treestore, &child, &toplevel);
| |
- | gtk_tree_store_set(treestore, &child,
| |
- | COLUMN, "C",
| |
- | -1);
| |
- |
| |
- | gtk_tree_store_append(treestore, &child, &toplevel);
| |
- | gtk_tree_store_set(treestore, &child,
| |
- | COLUMN, "C++",
| |
- | -1);
| |
- |
| |
- | gtk_tree_store_append(treestore, &child, &toplevel);
| |
- | gtk_tree_store_set(treestore, &child,
| |
- | COLUMN, "Java",
| |
- | -1);
| |
- |
| |
- | return GTK_TREE_MODEL(treestore);
| |
- | }
| |
- |
| |
- |
| |
- |
| |
- | static GtkWidget *
| |
- | create_view_and_model (void)
| |
- | {
| |
- | GtkTreeViewColumn *col;
| |
- | GtkCellRenderer *renderer;
| |
- | GtkWidget *view;
| |
- | GtkTreeModel *model;
| |
- |
| |
- | view = gtk_tree_view_new();
| |
- |
| |
- | col = gtk_tree_view_column_new();
| |
- | gtk_tree_view_column_set_title(col, "Programming languages");
| |
- | gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
| |
- |
| |
- | renderer = gtk_cell_renderer_text_new();
| |
- | gtk_tree_view_column_pack_start(col, renderer, TRUE);
| |
- | gtk_tree_view_column_add_attribute(col, renderer,
| |
- | "text", COLUMN);
| |
- |
| |
- | model = create_and_fill_model();
| |
- | gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
| |
- | g_object_unref(model);
| |
- |
| |
- | return view;
| |
- | }
| |
- |
| |
- |
| |
- | int
| |
- | main (int argc, char **argv)
| |
- | {
| |
- | GtkWidget *window;
| |
- | GtkWidget *view;
| |
- | GtkTreeSelection *selection;
| |
- | GtkWidget *vbox;
| |
- | GtkWidget *statusbar;
| |
- |
| |
- | gtk_init(&argc, &argv);
| |
- |
| |
- | window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
| |
- | gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
| |
- | gtk_window_set_title(GTK_WINDOW(window), "Tree View");
| |
- | gtk_widget_set_size_request (window, 350, 300);
| |
- |
| |
- |
| |
- | vbox = gtk_vbox_new(FALSE, 2);
| |
- | gtk_container_add(GTK_CONTAINER(window), vbox);
| |
- |
| |
- |
| |
- | view = create_view_and_model();
| |
- | selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
| |
- |
| |
- | gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 1);
| |
- |
| |
- | statusbar = gtk_statusbar_new();
| |
- | gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, TRUE, 1);
| |
- |
| |
- | g_signal_connect(selection, "changed",
| |
- | G_CALLBACK(on_changed), statusbar);
| |
- |
| |
- | g_signal_connect (G_OBJECT (window), "destroy",
| |
- | G_CALLBACK(gtk_main_quit), NULL);
| |
- |
| |
- | gtk_widget_show_all(window);
| |
- |
| |
- | gtk_main();
| |
- |
| |
- | return 0;
| |
- | }
| |
- |
| |
- | </source>
| |
- |
| |
- | In our example, we divide programming languages into two groups. Scripting languages and compiled languages.
| |
- | The language categories serve as toplevel nodes for their list of items. The currently selected node or item is shown in the statusbar.
| |
- |
| |
- | The steps to create a tree view are very similar to creating a list view.
| |
- |
| |
- | <source lang="cpp">
| |
- | GtkTreeStore *treestore;
| |
- | </source>
| |
- |
| |
- | Here we use a different model. A <b>GtkTreeStore</b>.
| |
- |
| |
- | <source lang="cpp">
| |
- | treestore = gtk_tree_store_new(NUM_COLS,
| |
- | G_TYPE_STRING);
| |
- | </source>
| |
- |
| |
- | We create a <b>GtkTreeStore</b> with only one column.
| |
- |
| |
- | <source lang="cpp">
| |
- | gtk_tree_store_append(treestore, &toplevel, NULL);
| |
- | gtk_tree_store_set(treestore, &toplevel,
| |
- | COLUMN, "Scripting languages",
| |
- | -1);
| |
- |
| |
- | </source>
| |
- |
| |
- | This creates a toplevel node.
| |
- |
| |
- | <source lang="cpp">
| |
- | gtk_tree_store_append(treestore, &child, &toplevel);
| |
- | gtk_tree_store_set(treestore, &child,
| |
- | COLUMN, "Python",
| |
- | -1);
| |
- | </source>
| |
- |
| |
- | This code creates a child item.
| |
- |
| |
- | [[image: gtk_faq_treeview.png | center]]
| |
- |
| |
- |
| |
- | [[Категория:GTK+]]
| |