The following reference is a small extract from two books I read to become familiar with GTK programming. This is not a summary of this books but more for keeping things in mind. I hope not to hurt some license terms using some parts here. If so please write me and I will get rid of these things or prevent access with password. But for now I see no need for this. To learn such things it is necessary to read more about GTK than only read the part below.
Additionally to that the source code is free to download at http://www.gtkbook.com
My book recommendation:
Basics:
Dialogs:
gulong g_signal_connect(gpointer object, const gchar *signal_name, GCallback handler, gpointer data);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), (gpointer) label);
g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(gtk_widget_destroy), (gpointer) window);
g_signal_connect(G_OBJECT(button), "notify::relief", G_CALLBACK(property_changed), NULL); static void property_changed(GObject *button, GParamSpec *property, gpointer data) { printf("changed %s", property->name); }
static void callback_function(GtkWidget *widget, ..., gpointer data);
void g_signal_emit_by_name(gpointer instance, const gchar *signal_name, ...); void g_signal_stop_emission_by_name(gpointer instance, const gchar *signal_name);
are initially emitted by the X Window System and then sent from the window manager to your application to be interpreted by the signal system provided by GLib.
static gboolean callback_function(GtkWidget *widget, GdkEvent *event, gpointer data);
Return value TRUE gtk+ assumes the event has already been handled. With FALSE gtk+ continue to handling the event.
If we know what kind of event we handle, we can adjust some parameters. Like here with GtkEventKey instead of GdkEvent.
g_signal_connect(G_OBJECT(widget), "key-press-event", G_CALLBACK(key_press), NULL); static gboolean key_press(GtkWidget *widget, GtkEventKey *event, gpointer dat);
GtkWidget *label; label = gtk_label_new("Hello World"); gtk_label_set_selectable(GTK_LABEL(label), TRUE); void gtk_label_set_text(GtkLabel *label, const gchar *str); void gtk_label_set_markup(GtkLabel *label, const gchar *str);
gtk_container_set_border_width(GTK_CONTAINER(window), 10); void gtk_container_add(GtkContainer *container, GtkWidget *child);
void gtk_widget_destroy(GtkWidget *widget);
void gtk_widget_set_size_request(GtkWidget *widget, gint width, gint height);
void gtk_widget_grab_focus(GtkWidget *widget);
void gtk_widget_set_sensitive(GtkWidget *widget, gboolean sensitive);
void gtk_widget_show_all(GtkWidget *widget); void gtk_widget_hide_all(GtkWidget *widget);
gtk_button_new()
gtk_button_new_with_label()
gtk_button_new_with_mnemonic("_Close")
gtk_button_set_relief()
g_object_get(button, "relief", &value, NULL); g_object_set(button, "relief", GTK_RELIEF_NORMAL, NULL);
GObject has a table that associates a list of strings to a list of pointers. You can change entries with:
void g_object_set_data(GObject *object, const gchar *key, gpointer data);
and with g_object_get_data() you can get data, which returns the pointer associated with key.
gtk_button_new()
gtk_button_new_with_label()
gtk_button_new_with_mnemonic("_Close")
gtk_button_set_relief()
gtk_widget_set_size_request()
gboolean homogeneous = TRUE; gint spacing = 5; GtkWidget *vbox = gtk_vbox_new(homogeneous, spacing); gtk_box_pack_start_defaults(GTK_BOX(vox), button); /* expand=TRUE,fill=TRUE */ void gtk_box_pack_end(GtkBox *box gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 5);
Special type of container widget that holds exactly two widgets with a resize bar between them.
GtkWidget *hpaned = gtk_hpaned_new(); gtk_paned_add1(GTK_PANED(hpaned), button1); gtk_paned_add2(GTK_PANED(hpaned), button2); gtk_container_add(GTK_CONTAINER(window), hpaned); gtk_paned_pack1(GTK_PANED(hpaned), label1, FALSE, TRUE); gtk_paned_pack2(GTK_PANED(hpaned), label2, TRUE, TRUE); /* set position of the resize bar */ void gtk_paned_set_position(GtkPaned *paned, gint position); gint gtk_paned_get_position(GtkPaned *paned);
GtkWidget *table = gtk_table_new(guint rows, guint columns, gboolean homogeneous); void gtk_table_resize(GtkTable *table, guint rows, guint columns); void gtk_table_set_homogeneous(GtkTable *table, gboolean homogeneous); void gtk_table_attach(GtkTable *table , GtkWidget *child , guint left , guint right , guint top , guint bottom , GtkAttachOptions xoptions , GtkAttachOptions yoptions , guint xpadding , guint ypadding); gtk_table_attach(GTK_TABLE(table), label, 0, 2, 0, 1, GTK_EXPAND, GTK_SHRINK, 0, 0);
void gtk_table_attach_defaults(GtkTable *table , GtkWidget *child , guint left , guint right , guint top , guint bottom);
void gtk_table_set_col_spacings(GtkTable *table, guint spacing); void gtk_table_set_col_spacing(GtkTable *table, guint column, guint spacing); void gtk_table_set_col_spacings(GtkTable *table, guint spacing);
void gtk_fixed_move(GtkFixed *fixed, GtkWidget *child, gint x_pos, gint y_pos);
GtkWidget *expander = gtk_expander_new_with_mnemonic("_Expand me");
gtk_container_add(GTK_CONTAINER(expander), label);
gtk_expander_set_expanded(GTK_EXPANDER(expander), TRUE);
gtk_expander_set_spacing(GTK_EXPANDER(expander), guint spacing);
gtk_container_add(GTK_CONTAINER(window), expander);
is another type of GtkBin container that allows its child to be removed from the parent window by dragging it with the mouse.
GtkWidget *handle = gtk_handle_box_new(); GtkWidget *label = gtk_label_new("asdf"); gtk_handle_box_set_shadow_type(GTK_HANDLE_BOX(handle), GTK_POS_LEFT); gtk_handle_box_set_snap_edge(GTK_HANDLE_BOX(handle), GTK_POS_TOP);
GtkWidget *notebook = gtk_notebook_new(); label1 = gtk_label_new("Page One"); label2 = gtk_label_new("Page Two"); child1 = gtk_label_new("Content of Page One"); child2 = gtk_label_new("Content of Page Two"); g_signal_connect(G_OBJECT(child1), "clicked", G_CALLBACK(switch_page), (gpointer) notebook); g_signal_connect(G_OBJECT(child2), "clicked", G_CALLBACK(switch_page), (gpointer) notebook); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), child1, label1); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), child2, label2); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_BOTTOM); gtk_container_add(GTK_CONTAINER(window), notebook); gint gtk_notebook_append_page(GtkNotebook *notebook, GtkWidget *child, sGtkWidget *tab_label); gint gtk_notebook_insert_page(GtkNotebook *notebook, GtkWidget *child, GtkWidget *tab_label, gint position); void gtk_notebook_set_tab_pos(GtkNotebook *notebook, GtkPositionType position); void gtk_notebook_set_show_tabs(GtkNotebook *notebook, gboolean show_tabs); void gtk_notebook_set_scrollable(GtkNotebook *notebook, gboolean scrollable); void gtk_notebook_remove_page(GtkNotebook *notebook, gint page_number); void gtk_notebook_reorder_child(GtkNotebook *notebook, GtkWidget *child, gint position); void gtk_notebook_set_current_page(GtkNotebook *notebook, gint page_number);
Various widgets including GtkLabel do not respond to GDK events, because they do not have an associated GDK window. For those cases the event box exists.
GtkWidget *eventbox = gtk_event_box_new(); gtk_event_box_set_above_child(GTK_EVENT_BOX(eventbox), FALSE); g_signal_connect(G_OBJECT(eventbox), "button_press_event", G_CALLBACK(button_pressed), (gpointer) label); gtk_widget_set_events(eventbox, GDK_BUTTON_PRESS_MASK); gtk_widget_realize(eventbox); gdk_window_set_cursor(eventbox->window, gdk_cursor_new(GDK_HAND1)); gtk_widget_show_all(window); static gboolean button_pressed(GtkWidget *eventbox, GdkEventButton *event, GtkLabel *label) { if(event->type == GDK_2BUTTON_PRESS) {} }
button = gtk_button_new_from_stock(GTK_STOCK_FLOPPY) g_signal_connect_swapped(G_OBJECT(BUTTON), "clicked", G_CALLBACK(open_floppy_handler), (gpointer)window);
The GtkTobbleButton widget is a type of GtkButton that holds its active or inactive state after it is clicked. It is shown as pressed down when active. Clicking an active tobble button will cause it to return to its normal state. There are two widgets derived from GtkTobbleButton:
GtkWidget *tobble1 = gtk_toggle_button_new_with_mnemonic("_Press down"); g_signal_connect(G_OBJECT(toggle1), "toggled", G_CALLBACK(button_toggled), toggle2); static void button_toggled(GtkToggleButton *toggle, GtkWidget *other_toggle) { gtk_widget_set_sensitive(other_toggle, TRUE); }
Sensitivity is actually only one of many widget flags provided by the GtkWidgetFlags enumeration. For more Flags see here.
gboolean gtk_toggle_button_get_active()
void gtk_toggle_button_set_active(GtkTobbleButton *toggle, gboolean active);
GtkWidget *check1 = gtk_check_button_new_with_label("Click here"); GtkWidget *check2 = gtk_check_button_new_with_label("or here"); /* Only enable the second check button when the first is enabled. */ gtk_widget_set_sensitive(check2, FALSE); g_signal_connect(G_OBJECT(check), "toggled", G_CALLBACK(check_toggled), (gpointer) check2); static void check_toggled(GtkToggleButton *check1, GtkWidget *check2) { g_printf("toggled-signal raised\n"); }
In a group, when one radio button is selected, all others will be deselected.
GtkWidget *radio1, ...
radio1 = gtk_radio_button_new_with_label(NULL, "option1");
radio2 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(radio1), "option2");
radio3 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(radio2), "option2");
To create the first member of the group:
GtkWidget* gtk_radio_button_new(GSList *group); GtkWidget* gtk_radio_button_new_with_label(GSList *group, const gchar *label); GtkWidget* gtk_radio_button_new_with_mnemonic(GSList *group, const gchar *label);
To create the rest of the group:
GtkWidget* gtk_radio_button_new_from_widget(GtkRadioButton *group); GtkWidget* gtk_radio_button_new_with_label_from_widget(GtkRadioButton *group, const gchar *label); GtkWidget* gtk_radio_button_new_with_mnemonic_from_widget(GtkRadioButton *group, const gchar *label);
Every radio button in the group must be connected to the toggled signal.
GtkWidget *window, *vbox, *hbox, *question, *label, *pass; gchar *str; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Password?"); gtk_container_set_border_width (GTK_CONTAINER (window), 10); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL); str = g_strconcat ("What is the password for ", g_get_user_name(), "?", NULL); question = gtk_label_new (str); label = gtk_label_new ("Password:"); /* Create a new GtkEntry widget and hide its content from view. */ pass = gtk_entry_new (); gtk_entry_set_visibility (GTK_ENTRY (pass), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (pass), '*'); hbox = gtk_hbox_new (FALSE, 5); gtk_box_pack_start_defaults (GTK_BOX (hbox), label); gtk_box_pack_start_defaults (GTK_BOX (hbox), pass); vbox = gtk_vbox_new (FALSE, 5); gtk_box_pack_start_defaults (GTK_BOX (vbox), question); gtk_box_pack_start_defaults (GTK_BOX (vbox), hbox); gtk_container_add (GTK_CONTAINER (window), vbox); gtk_widget_show_all (window); gtk_main (); void gtk_editable_set_editable(GtkEditable *editable, gboolean is_editable); void gtk_entry_set_max_length(GtkEntry *entry, gtin max_length); void gtk_entry_set_invisible_char(GtkEntry *entry, gunichar inv_char); void gtk_entry_set_visibility(GtkEntry *entry, gboolean visible); void gtk_entry_set_text(GtkEntry *entry, const gchar *text); void gtk_editable_insert_text(GtkEditable *editable, const gchar *text , gint length_of_text, gint *position);
void gtk_editable_delete_text(GtkEditable *editable, gint start_pos, gint end_pos); void gtk_editable_select_region(GtkEditable *editable, gint start_pos, gint end_pos); void gtk_editable_delete_selection(GtkEditable *editable); gchar* gtk_editable_get_chars(GtkEditable *editable, gint start_pos, gint end_pos); /* the following functions are built into entries by default */ void gtk_editable_cut_clipboard(GtkEditable *editable); void gtk_editable_copy_clipboard(GtkEditable *editable); void gtk_editable_paste_clipboard(GtkEditable *editable);
The GtkSpinButton widget is a number selection widget that is capable of handling integers and floating-point numbers. Ti is derived from GtkEntry, so GtkSpinButton inherits all of its functions and signals.
GtkObject* gtk_adjustment_new(gdouble initial_value,
gdouble lower_range,
gdouble upper_range,
gdouble step_increment,
gdouble page_increment,
gdouble page_size);
float_pt = GTK_ADJUSTMENT(gtk_adjustment_new(0.5, 0.0, 1.0, 0.1, 0.5, 0.5));
spin_float = gtk_spin_button_new(float_pt, 0.1, 1);
gtk_box_pack_start_defaults(GTK_BOX(vbox), spin-float);
scale_float = gtk_hscale_new_with_range(0.0, 1.0, 0.1); gtk_scale_set_digits(GTK_SCALE(scale_float), 1); gtk_scale_set_value_pos(GTK_SCALE(scale_float), GTK_POS_LEFT);
typedef struct { GtkStyle *style; GtkRequisition requisition; GtkAllocation allocation; GdkWindow *window; GtkWidget *parent; } GtkWidget;
Widget states:
chooser = gtk_file_chooser_button_new("Choose a Folder", GTK_FILE_CHOOSER_ACTION_OPEN); g_signal_connect(G_OBJECT(chooser), "selection_changed", G_CALLBACK(file_changed), (gpointer)label); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(chooser), g_get_homedir()); filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, "Image Files"); gtk_file_filter_add_pattern(filter, "*.png"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(chooser), filter); static void file_changed(GtkFileChooser *chooser, GtkLabel *label) { gchar *file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser)); gtk_label_set_text(label, file); g_free(file); } void gtk_file_filter_add_mime_type(GtkFileFilter *filter, const char *mime_type);
typedef struct { GtkWidget *vbox; GtkWidget *action_area; } GtkDialog; gtk_box_pack_start_defaults(GTK_BOX(dialog->vbox), child);
Example
{ /* event handler of one of the events of main loop */ dialog = gtk_dialog_new_with_buttons("Information", parent, GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); label = gtk_label_new("BLABLA"); image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG); /* GtkWidget* gtk_image_new_from_stock(const gchar *stock_id, GtkIconSize size); */ . . gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(); } GtkWidget *gtk_image_new_from_file(const gchar *filename); GtkWidget *gtk_image_new_from_pixbuf(GdkPixbuf *pixbuf);
In order to create a nonmodal dialog, you need to connect to GtkDialog's response signal.
dialog = gtk_dialog_new_with_buttons("Info", parent, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); result = gtk_dialog_run(GTK_DIALOG(dialog)); switch( result ) { case(GTK_RESPONSE_OK): break; case(GTK_RESPONSE_APPLY): break; } gtk_widget_destroy(dialog);
dialog = gtk_message_dialog_new(parent, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "hello"); gtk_window_set_title(GTK_WINDOW(dialog), "info"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog);
gtk_message_dialog_new_with_markup()
void gtk_message_dialog_set_format_secondary_text(GtkMessageDialog *dialog, const gchar *message_format, ...);
dialog = gtk_about_dialog_new(); logo = gdk_pixbuf_new_from_file("/path/logo.png", &error); if( error==NULL ) gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog), logo); GdkPixbuf* gdk_pixbuf_scale_simple(const GdkPixbuf *src, int dest_width, int dest_height, GdkInterpType interpolation); gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(dialog), "dialog"); gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), "1.0"); gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog), "(C) 2007 Firstname Backname"); gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog), "All About ..."); gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(dialog), "blabla"); gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog), "http://www.nowhere.to"); gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(dialog), "www.nowhere.to"); const gchar *authors[] = { "author1", "author2", NULL }; gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(dialog), authors); gtk_about_dialog_set_documenters(GTK_ABOUT_DIALOG(dialog), authors); gtk_about_dialog_set_translator_credits(GTK_ABOUT_DIALOG(dialog), "line1 \n line2"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog);
struct GError
{
gchar *message;
gint code;
}
if( error->domain==GDK_PIXBUF_ERROR)
g_print("GdkPixbufError: %s\n", error->message);
dialog = gtk_file_chooser_dialog_new("Save File as ...", window , GTK_FILE_CHOOSER_ACTION_SAVE , GTK_STOCK_CANCEL , GTK_RESPONSE_CANCEL , GTK_STOCK_SAVE , GTK_RESPONSE_ACCEPT , NULL); gint result = gtk_dialog_run(GTK_DIALOG(dialog)); if(result==GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gtk_button_set_label(button, filename); } gtk_widget_destroy(dialog);
dialog = gtk_file_chooser_dialog_new("Save File as ...", window , GTK_FILE_CHOOSER_CREATE_FOLDER , GTK_STOCK_CANCEL , GTK_RESPONSE_CANCEL , GTK_STOCK_OK , GTK_RESPONSE_OK , NULL); gint result = gtk_dialog_run(GTK_DIALOG(dialog)); if(result==GTK_RESPONSE_OK) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); g_print("no need to make folder %s. This provides the dialog itself.\n", filename); } gtk_widget_destroy(dialog);
The difference between GtkFileChooserDialog and GtkFileChooserButton using the GTK_FILE_CHOOSER_ACTION_OPEN type is that dialogs are capable of selecting multiple files while buttons are restricted to one file.
dialog = gtk_file_chooser_dialog_new("Open File(s) ...", window
, GTK_FILE_CHOOSER_ACTION_OPEN
, GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
, GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
, NULL);
gtk_file_chosser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
gint result = gtk_dialog_run(GTK_DIALOG(dialog));
if(result==GTK_RESPONSE_ACCEPT)
{
GSList *filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
while( filenames !=NULL )
{
g_print("%s was selected.\n", (gchar*) filenames->data);
filenames = filenames->next;
}
}
gtk_widget_destroy(dialog);
index = gtk_assistant_append_page(GTK_ASSISTANT(assistant), widget);
Page type:
void gtk_assistant_set_page_complete(GtkAssistant *assistant, GtkWidget *page, gboolean complete);
while( percent<=100.0 ) { gchar *message = g_strdup_printf("%.0f complete", percent); gtk_progress_bar_set_fraction(progress, percent/100.0 ); gtk_progress_bar_set_text(progress, message); while( gtk_events_pending()) gtk_main_iteration(); g_usleep(3600); percent += 3.141529; }
to set progress step:
gtk_progress_bar_set_pulse_step()
void gtk_assistant_set_forward_page_func(...);
Both scrollbars int the scrolled window have associated GtkAdjustment objects. These adjustments are used to track the current position and range of a scrollbar.
swin = gtk_scrolled_window_new(NULL,NULL); horizontal = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(swin)); vertical = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(swin)); gtk_container_set_border_width(GTK_CONTAINER(swin), 5); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swin), table1);
Each text view is used to display the contents of a class called GtkTextBuffer.
A simple GtkTextView Example:
int main(int argc, char **argv) {
GtkWidget *window, *scrolled_win, *textview; GtkTextBuffer *buffer; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "title"); gtk_container_set_border_width(GTK_CONTAINER(window), 10); gtk_widget_set_size_request(window, 250,150); textview = gtk_text_view_new(); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); gtk_text_buffer_set_text(buffer, "This you first text view widget!!!!", -1); scrolled_win = gtk_scrolled_window_new(NULL, NULL); gtk_container_add(GTK_CONTAINER(scrolled_win), textview); gtk_container_add(GTK_CONTAINER(window), scrolled_win); gtk_widget_show_all(window); gtk_main(); return 0;
}
gtk_text_view_set_wrap_mode() gtk_widget_set_sensitive()
gtk_text_view_set_cursor_visible()
When manipulating text within a GtkTextBuffer, there are two objects that can be used to keep track of a position within the buffer: GtkTextIter and GtkTextMark
Text iterators are used to represent a position between two characters in a buffer. The problem presented by text iterators is that they automatically become invalidated when a text buffer is edited. For keeping track of a position throughout changes within a text buffer, the GtkTextMark object is provided.
void gtk_text_buffer_get_iter_at_mark();
typdef struct { GtkWidget *entry, *textview; } Widgets Widgets *w = g_slice_new(Widgets); ... w->textview = gtk_text_view_new(); w->entry = gtk_entry_new(); g_signal_connect(G_OBJECT(insert), "clicked", G_CALLBACK(insert_text), (gpointer) w); scrolled_win = gtk_scrolled_window_new(NULL, NULL); gtk_container_add(GTK_CONTAINER(scrolled_win), w->textview); gtk_container_add(GTK_CONTAINER(window), vbox); gtk_widget_show_all(window); insert_text() { GtkTextBuffer *buffer;
GtkTextIter iter;
const gchar *text;
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w->textview));
text = gtk_entry_get_text(GTK_ENTRY(w->entry));
mark = gtk_text_buffer_get_insert(buffer);
gtk_trxt_buffer_get_iter_at_mark(buffer, &iter, mark);
gtk_text_buffer_insert(buffer, &iter, text, -1);
}
Retrieving Text Iterators and Marks
mark = gtk_text_buffer_get_insert(); gtk_text_buffer_get_iter_at_mark(); gtk_text_buffer_get_bounds(); gtk_text_buffer_get_text(); gtk_text_buffer_get_iter_at_offset(); gtk_text_buffer_get_iter_at_line();
Changing Text Buffer Contents
gtk_text_buffer_get_insert(); gtk_text_buffer_insert_at_cursor() gtk_text_buffer_delete();