5

So I am trying to create a simple menu in GTK3+ using C. I am trying to recreate the menus found at:

https://web.archive.org/web/20141228062527/https://developer.gnome.org/gtk-tutorial/stable/x743.html

So I copied the code, and have been trying to isolate the parts I need, and covert said pieces to 3+. I have not had much luck with this code segment. First of all, gtk_option_menu is deprecated, and replaced with gtk_combo_box. I tried to find tutorials with that, but nothing came up.

Honestly, I don't even know the theory behind how to create a menu with GTK in the first place, so its very hard for me to do the conversion. I am flying practically blind here.

My code is below:

#include "/usr/include/gtk-3.0/gtk/gtk.h" static void print_stuff( GtkWidget *item, gpointer data) { printf("Hello World!\n"); return; } static GtkWidget *make_menu_item(gchar *name, GCallback callback, gpointer data ){ GtkWidget *item; item = gtk_menu_item_new_with_label (name); g_signal_connect (item, "activate", callback, (gpointer) data); gtk_widget_show (item); return item; } static void create_range_controls( void ){ GtkWidget *window; GtkWidget *box1, *box2, *box3; GtkWidget *button; GtkWidget *scrollbar; GtkWidget *separator; GtkWidget *opt, *menu, *item; GtkWidget *label; GtkWidget *scale; GObject *adj1, *adj2; window = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_window_set_title(GTK_WINDOW(window), "range controls"); box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER (window), box1); gtk_widget_show(box1); opt = gtk_option_menu_new (); menu = gtk_menu_new (); item = make_menu_item ("Top", G_CALLBACK (print_stuff), NULL); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); item = make_menu_item ("Bottom", G_CALLBACK (print_stuff), NULL); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); item = make_menu_item ("Left", G_CALLBACK (print_stuff), NULL); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); item = make_menu_item ("Right", G_CALLBACK (print_stuff), NULL); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_option_menu_set_menu(GTK_OPTION_MENU(opt), menu); gtk_box_pack_start(GTK_BOX (box1), opt, TRUE, TRUE, 0); gtk_widget_show(opt); gtk_widget_show (window); } int main( int argc, char *argv[] ){ gtk_init (&argc, &argv); create_range_controls (); gtk_main (); return 0; } 

Can anyone illustrate what I am doing wrong, and why? Are there any tutorials for GTK3+, like the one for GTK2+ that I linked above?

Thanks!

3
  • That tutorial is for GTK+ 2 (as it says at the top of the page). I do not know if the tutorials in any version of the GTK+ 3 documentation cover menus (nor have I actually used GTK+ 3 menus myself, so IDK; sorry). Also you definitely do not want to include the absolute path to the GTK+ header file(s). As the GTK+ 3 tutorial will show, you'll want to include <gtk/gtk.h> and let pkg-config set the include search path correctly when compiling. Commented Jan 25, 2015 at 5:56
  • I know its for GTK2, but I need GTK3. If I needed GTK2, then the tutorial would have sufficed. I tried including it that way, and for some reason it doesn't work. I get undefined references everywhere. Instead, I have done it manually, and it seems to work fine for the other things that I actually got working. Commented Jan 25, 2015 at 13:36
  • Yes, and I pointed you twoard the GTK+ 3 tutorials and documentation. Did you forget to use pkg-config --libs when building the program executable? The GTK+ 3 tutorial does describe this. (Alternatively you can forego the tutorial and go straight for the reference pages...) Commented Jan 25, 2015 at 14:54

1 Answer 1

11

It's hard to do all manually. You can use glade for rapid development interfaces. But here's a little example about how to use menus and gtk_combo_box with gtk+-3.x series:

// cc menu-gtk3.c `pkg-config --cflags --libs gtk+-3.0` -o menu-gtk3 #include <gtk/gtk.h> void cb_combo_change (GtkComboBox *combo, gpointer user_data) { gint index = gtk_combo_box_get_active (combo); if (index) { // we need some string to be displayed GtkTreeModel *model; GtkTreeIter iter; gchar *buf; model = gtk_combo_box_get_model (combo); gtk_tree_model_iter_nth_child (model, &iter, NULL, index); gtk_tree_model_get (model, &iter, 0, &buf, -1); g_print ("%s\n", buf); g_free (buf); } } void show_message_cb (GtkMenuItem *item, gpointer user_data) { g_print ("Hello world\n"); } int main (int argc, char *argv[]) { GtkWidget *toplevel; GtkWidget *center_vbox; GtkWidget *menuBar; GtkWidget *menuItem1; GtkWidget *submenu1; GtkWidget *item_message; GtkWidget *item_quit; GtkWidget *combobox; GtkListStore *combo_ls; GtkCellRenderer *renderer; GtkTreeIter iter; gtk_init (&argc, &argv); /* create toplevel window */ toplevel = gtk_window_new (GTK_WINDOW_TOPLEVEL); /* create the box here */ center_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); /* create menubar */ menuBar =gtk_menu_bar_new (); /* create 1st menu item */ menuItem1 = gtk_menu_item_new_with_mnemonic ("_Application"); /* add the submenu for the 1st menu item */ submenu1 = gtk_menu_new (); /* add the message item */ item_message = gtk_menu_item_new_with_label ("Message"); /* add the quit item menu for the submenu */ item_quit = gtk_menu_item_new_with_label ("Quit"); /* create the list model for the combo */ combo_ls = gtk_list_store_new (1, G_TYPE_STRING); /* add some strings */ gtk_list_store_append (combo_ls, &iter); gtk_list_store_set (combo_ls, &iter, 0, "Choose one", -1); gtk_list_store_append (combo_ls, &iter); gtk_list_store_set (combo_ls, &iter, 0, "String1", -1); gtk_list_store_append (combo_ls, &iter); gtk_list_store_set (combo_ls, &iter, 0, "String2", -1); /* add a combobox with the model * you could use combo_box_text for faster text append */ combobox = gtk_combo_box_new_with_model (GTK_TREE_MODEL (combo_ls)); /* destroy here the model, because you increase its reference * by attach it to the combo */ g_object_unref (combo_ls); /* now prepare the combo */ 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); /* set index to 0 */ gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), 0); /* packing */ gtk_menu_shell_append (GTK_MENU_SHELL (submenu1), item_message); gtk_menu_shell_append (GTK_MENU_SHELL (submenu1), item_quit); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuItem1), submenu1); gtk_menu_shell_append (GTK_MENU_SHELL (menuBar), menuItem1); gtk_box_pack_start (GTK_BOX (center_vbox), menuBar, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (center_vbox), combobox, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (toplevel), center_vbox); /* signal handlers */ g_signal_connect (toplevel, "destroy", G_CALLBACK (gtk_main_quit), NULL); g_signal_connect (combobox, "changed", G_CALLBACK (cb_combo_change), NULL); g_signal_connect_swapped (item_quit, "activate", G_CALLBACK (gtk_widget_destroy), toplevel); g_signal_connect (item_message, "activate", G_CALLBACK (show_message_cb), NULL); /* let them loose */ gtk_widget_show_all (toplevel); gtk_main (); return 0; } 
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you so much! I will look into using glade, as you suggest.
No problem, need help just ask me :)
The only hard thing about doing it manually is the terrible documentation without examples and overall description. Menus should use the GAction system and i still haven't found any tutorial or real explaining concept documentation for it.
Properly you want to set this to FALSE, FALSE: gtk_box_pack_start (GTK_BOX (center_vbox), menuBar, TRUE, TRUE, 0); And the next line to TRUE TRUE.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.