Make the menu items of menu created, functionable using GTK+ - c

Here in this code I have created a menu bar and added menus and menu items to it...
But i dont know how to make the created menu items functionable... for eg: I want the 'Open' menu item of 'File' in the menu bar, open a file and display it...
I'm making a project on a Text Editor using GTK+ 3
#include <gtk/gtk.h>
GtkWidget *window;
GdkPixbuf *icon;
GtkWidget *vbox;
GtkWidget *menubar;
GtkWidget *fileMenu;
GtkWidget *fileMi;
GtkWidget *editMenu;
GtkWidget *editMi;
GtkWidget *searchMenu;
GtkWidget *searchMi;
GtkWidget *newMi;
GtkWidget *openMi;
GtkWidget *saveMi;
GtkWidget *saveasMi;
GtkWidget *quitMi;
GtkWidget *undoMi;
GtkWidget *redoMi;
GtkWidget *cutMi;
GtkWidget *copyMi;
GtkWidget *pasteMi;
GtkWidget *fontMi;
GtkWidget *findMi;
GtkWidget *replaceMi;
GtkWidget *text_view;
GtkTextBuffer *buffer;
void txt(){
text_view = gtk_text_view_new ();
gtk_box_pack_start (GTK_BOX (vbox), text_view, TRUE, TRUE, 0);
}
GdkPixbuf *create_pixbuf (const gchar *filename)
{
GdkPixbuf *pixbuf;
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_file (filename, &error);
if (!pixbuf)
{
fprintf (stderr, "%s\n", error->message);
g_error_free (error);
}
return pixbuf;
}
static void fileOpen(GtkWidget *load, gpointer window)
{
GtkWidget *choose;
GtkFileChooserAction action= GTK_FILE_CHOOSER_ACTION_OPEN;
choose = gtk_file_chooser_dialog_new("Choose a file to open", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
if (gtk_dialog_run(GTK_DIALOG(choose)) == GTK_RESPONSE_ACCEPT)
{
char *path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(choose));
gtk_text_buffer_set_text(buffer, path, -1);
}
gtk_widget_destroy(choose);
}
static void fileSave(GtkWidget *save, gpointer window)
{
GtkWidget *saved;
saved = gtk_file_chooser_dialog_new("Choose a file to open", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
gtk_widget_show_all(saved);
gint resp = gtk_dialog_run(GTK_DIALOG(saved));
gtk_widget_destroy(saved);
}
int main (int argc, char *argv[])
{
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
icon = create_pixbuf ("Web.png");
gtk_window_set_title (GTK_WINDOW (window), "Write Pad");
gtk_window_set_default_size (GTK_WINDOW (window), 500, 400);
gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
gtk_window_set_icon (GTK_WINDOW (window), icon);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
menubar = gtk_menu_bar_new ();
fileMenu = gtk_menu_new ();
fileMi = gtk_menu_item_new_with_label ("File");
newMi = gtk_menu_item_new_with_label ("New");
openMi = gtk_menu_item_new_with_label ("Open");
saveMi = gtk_menu_item_new_with_label ("Save");
saveasMi = gtk_menu_item_new_with_label ("Save As");
quitMi = gtk_menu_item_new_with_label ("Quit");
menubar = gtk_menu_bar_new ();
editMenu = gtk_menu_new ();
editMi = gtk_menu_item_new_with_label ("Edit");
undoMi = gtk_menu_item_new_with_label ("Undo");
redoMi = gtk_menu_item_new_with_label ("Redo");
cutMi = gtk_menu_item_new_with_label ("Cut");
copyMi = gtk_menu_item_new_with_label ("Copy");
pasteMi = gtk_menu_item_new_with_label ("Paste");
fontMi = gtk_menu_item_new_with_label ("Font");
menubar = gtk_menu_bar_new ();
searchMenu = gtk_menu_new ();
searchMi = gtk_menu_item_new_with_label ("Search");
findMi = gtk_menu_item_new_with_label ("Find");
replaceMi = gtk_menu_item_new_with_label ("Replace");
gtk_menu_item_set_submenu (GTK_MENU_ITEM (fileMi), fileMenu);
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), newMi);
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), openMi);
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), saveMi);
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), saveasMi);
gtk_menu_shell_append (GTK_MENU_SHELL (fileMenu), quitMi);
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), fileMi);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (editMi), editMenu);
gtk_menu_shell_append(GTK_MENU_SHELL(editMenu), undoMi);
gtk_menu_shell_append(GTK_MENU_SHELL(editMenu), redoMi);
gtk_menu_shell_append(GTK_MENU_SHELL(editMenu), cutMi);
gtk_menu_shell_append(GTK_MENU_SHELL(editMenu), copyMi);
gtk_menu_shell_append (GTK_MENU_SHELL (editMenu), pasteMi);
gtk_menu_shell_append (GTK_MENU_SHELL (editMenu), fontMi);
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), editMi);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (searchMi), searchMenu);
gtk_menu_shell_append(GTK_MENU_SHELL(searchMenu), findMi);
gtk_menu_shell_append(GTK_MENU_SHELL(searchMenu), replaceMi);
gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
txt();
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (G_OBJECT (quitMi), "activate", G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (G_OBJECT (newMi), "activate", G_CALLBACK (main), NULL);
g_signal_connect(G_OBJECT (openMi), "activate", G_CALLBACK(fileOpen), NULL);
g_signal_connect(G_OBJECT (saveMi), "activate", G_CALLBACK(fileSave), NULL);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}

Basically, the problem you have is caused by the fact that all of your widgets are global variables, but your fileOpen function takes a gpointer window argument:
//global
GtkWidget *window;
//gpointer window argument -> local variable, not global
static void fileOpen(GtkWidget *load, gpointer window)
{
GtkWidget *choose;
GtkFileChooserAction action= GTK_FILE_CHOOSER_ACTION_OPEN;
choose = gtk_file_chooser_dialog_new(
"Choose a file to open",
GTK_WINDOW(window),//window is not global, but function argument here !
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL
);
if (gtk_dialog_run(GTK_DIALOG(choose)) == GTK_RESPONSE_ACCEPT)
{
char *path = gtk_file_chooser_get_filename(
GTK_FILE_CHOOSER(choose)
);
gtk_text_buffer_set_text(buffer, path, -1);
}
gtk_widget_destroy(choose);
}
A quick fix would be to rename the argument to something like gp_data or something. A better fix would be to not use a global variable, and instead rely on the gpointer to pass on the objects you need:
g_signal_connect(
G_OBJECT (openMi),
"activate",
G_CALLBACK(fileOpen),
(gpointer)text_view // text_view and buffer needn't be global now
);
And then use the gpointer argument to get the window and anything else you might need. You could also use a custom struct or array of widgets to pass to the callback in case you need more stuff to work with, but in this case, you should be OK with just passing the text_view widget, and changing the callback to something like this:
static void fileOpen(GtkWidget *load, gpointer widget)
{
//get the buffer
GtkTextBuffer *buffer = gtk_text_view_get_buffer(
GTK_TEXT_VIEW (widget)
);
//get window from text_View widget passed to callback
//so window doesn't have to be global either...
GtkWidget *window = gtk_widget_get_toplevel(
widget
), *choose;
GtkFileChooserAction action= GTK_FILE_CHOOSER_ACTION_OPEN;
choose = gtk_file_chooser_dialog_new(
"Choose a file to open",
GTK_WINDOW(window),
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL
);
if (gtk_dialog_run(GTK_DIALOG(choose)) == GTK_RESPONSE_ACCEPT)
{
char *path = gtk_file_chooser_get_filename(
GTK_FILE_CHOOSER(choose)
);
gtk_text_buffer_set_text(buffer, path, -1);
}
gtk_widget_destroy(choose);
}
Note that I haven't tested this code, but this should be enough to get you started. You'll have to change the code you have a bit, but you should be able to get rid of all of those global variables simply by passing the right widget to the callbacks.
As always: Read the documentation, just adding the link to the answer for future reference

Related

How to change the background color of the line numbers mode in GTK3+?

I'm designing a text editor in C/GTK3+, using the GtkSourceView class to be able to show the line numbers via the method gtk_source_view_set_show_line_numbers. I'm able to modify the background color of textview and text but not that of panel containing line numbers. By default it seems to be white. Can you show me how to modify it?
This is the code:
#include <gtk/gtk.h>
#include <gtksourceview/gtksource.h>
void find (GtkTextView *text_view, const gchar *text, GtkTextIter *iter)
{
GtkTextIter mstart, mend;
GtkTextBuffer *buffer;
gboolean found;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
found = gtk_text_iter_forward_search (iter, text, 0, &mstart, &mend, NULL);
if (found)
{
gtk_text_buffer_select_range (buffer, &mstart, &mend);
gtk_text_buffer_create_mark (buffer, "last_pos", &mend, FALSE);
}
}
typedef struct App
{
GtkWidget *text_view;
GtkWidget *search_entry;
} App;
/* Called when main window is destroyed. */
void
win_destroy (void)
{
gtk_main_quit();
}
void
next_button_clicked (GtkWidget *next_button, App *app)
{
const gchar *text;
GtkTextBuffer *buffer;
GtkTextMark *last_pos;
GtkTextIter iter;
text = gtk_entry_get_text (GTK_ENTRY (app->search_entry));
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (app->text_view));
last_pos = gtk_text_buffer_get_mark (buffer, "last_pos");
if (last_pos == NULL)
return;
gtk_text_buffer_get_iter_at_mark (buffer, &iter, last_pos);
find (GTK_TEXT_VIEW (app->text_view), text, &iter);
}
/* Called when search button is clicked. */
void
search_button_clicked (GtkWidget *search_button, App *app)
{
const gchar *text;
GtkTextBuffer *buffer;
GtkTextIter iter;
text = gtk_entry_get_text (GTK_ENTRY (app->search_entry));
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (app->text_view));
gtk_text_buffer_get_start_iter (buffer, &iter);
find (GTK_TEXT_VIEW (app->text_view), text, &iter);
}
int
main (int argc, char *argv[])
{
GtkWidget *win;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *search_button;
GtkWidget *next_button;
GtkWidget *swindow;
GtkCssProvider *provider;
GtkStyleContext *context;
App app;
gtk_init (&argc, &argv);
/* Create a window with a search entry, search button and a text
area. */
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (win), "destroy", win_destroy, NULL);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL,0);
gtk_container_add (GTK_CONTAINER (win), vbox);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL,0);
gtk_container_add(GTK_CONTAINER (vbox), hbox);
app.search_entry = gtk_entry_new ();
search_button = gtk_button_new_with_label ("Search");
next_button = gtk_button_new_with_label ("Next");
gtk_container_add(GTK_CONTAINER (hbox), app.search_entry);
gtk_container_add(GTK_CONTAINER (hbox), search_button);
gtk_container_add(GTK_CONTAINER (hbox), next_button);
g_signal_connect (G_OBJECT (search_button), "clicked",
G_CALLBACK (search_button_clicked), &app);
g_signal_connect (G_OBJECT (next_button), "clicked",
G_CALLBACK (next_button_clicked), &app);
/* A scrolled window which automatically displays horizontal and
vertical scrollbars when the text exceeds the text view's size. */
swindow = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_widget_set_vexpand (swindow, TRUE);
gtk_container_add(GTK_CONTAINER (vbox), swindow);
app.text_view = gtk_source_view_new ();
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (provider,
"textview{"
"font-size: 30px;"
"font-family: serif;"
"} text{"
"color: green;"
"background: black;"
"}",
-1,
NULL);
context = gtk_widget_get_style_context (app.text_view);
gtk_style_context_add_provider (context,
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
gtk_container_add (GTK_CONTAINER (swindow), app.text_view);
gtk_source_view_set_show_line_numbers (GTK_SOURCE_VIEW((app.text_view)), TRUE);
gtk_widget_show_all (win);
gtk_main();
}
There are generally two possibilities.
The typical way this is done is not by changing colors on the GtkSourceView, but to instead use a style scheme with gtk_source_buffer_set_style_scheme(). The style scheme has a "line-number" and "current-line-number" style which can have a color associated with it.
Another way, that is typically only used to show information about marks, is to have a GtkSourceMark with GtkSourceMarkAttributes:background set. Then you can show marks in the gutter.
Generally speaking, when you get to certain levels of complexity, it's just easier to write your own gutter renderer to optimize for the problem space.

Setting a custom GtkAccelLabel

I am trying to set a custom GtkAccelLabel to my GtkMenuItem, though I cant figure out how to use that widget ... for me just nothing is displayed.
Why are the following calls wrong / not sufficient ?
...
fileMi = gtk_menu_item_new_with_label("File");
label = gtk_accel_label_new ("Strg+X");
gtk_accel_label_set_accel_widget (label, quitMi);
...
Here a complete reproducer:
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *menubar;
GtkWidget *fileMenu;
GtkWidget *fileMi;
GtkWidget *quitMi;
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_default_size(GTK_WINDOW(window), 300, 200);
gtk_window_set_title(GTK_WINDOW(window), "Simple menu");
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
GtkAccelGroup *accel_group;
// Create a GtkAccelGroup and add it to the window.
accel_group = gtk_accel_group_new ();
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
menubar = gtk_menu_bar_new();
fileMenu = gtk_menu_new();
fileMi = gtk_menu_item_new_with_label("File");
quitMi = gtk_menu_item_new_with_label("Quit");
gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileMi), fileMenu);
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), quitMi);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fileMi);
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
GtkWidget *label = gtk_accel_label_new ("Strg+X");
gtk_accel_label_set_accel_widget (label, quitMi);
gtk_accel_label_refetch (label);
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(quitMi), "activate",
G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
Hah, I found a solution .. though no idea if it actually should be done like that.
The key is, that there is already a gtk_accel_label on the MenuItem, and I can modify it:
for (GList* lp = gtk_container_get_children (quitMi); lp != NULL; lp = lp->next)
{
if (GTK_IS_ACCEL_LABEL (lp->data))
gtk_accel_label_set_accel (lp->data, GDK_KEY_0, GDK_MOD1_MASK);
}

How to hide a .ui file and show another .ui file in GTK+

I have a button on my window on GTK+ 3. When the button is clicked, a window from another ui file should be opened and the current window's ui should be deleted (Hide). But I don't know how to do so.I am really new to Gtk+ programming on linux.
this is my .c file:
#include <gtk/gtk.h>
static void
buttonClicked(GtkWidget *widget,
gpointer data)
{
//here I need to open another window and close the current one
}
int main (int argc, char *argv[])
{
GtkBuilder *builder;
GObject *window;
GObject *button;
GError *error = NULL;
gtk_init (&argc, &argv);
builder = gtk_builder_new();
if(gtk_builder_add_from_file(builder, "main-window.ui", &error) == 0)
{
g_printerr ("Error loading file: %s\n", error->message);
g_clear_error (&error);
return 1;
}
window = gtk_builder_get_object (builder, "window");
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
button = gtk_builder_get_object (builder, "buttonOpen");
g_signal_connect (button, "clicked", G_CALLBACK (buttonClicked), NULL);
gtk_main ();
return 0;
}
Use gtk_widget_show_all () and gtk_widget_hide ().
#include <gtk/gtk.h>
static void
buttonClicked(GtkWidget *widget, GObject* window)
{
GtkBuilder *builder;
GObject *window2;
GError *error = NULL;
builder = gtk_builder_new();
if(gtk_builder_add_from_file(builder, "second-window.ui", &error) == 0)
{
g_printerr ("Error loading file: %s\n", error->message);
g_clear_error (&error);
return;
}
window2 = gtk_builder_get_object (builder, "window");
gtk_widget_show_all(GTK_WIDGET(window2));
gtk_widget_hide(GTK_WIDGET(window));
}
int main (int argc, char *argv[])
{
GtkBuilder *builder;
GObject *window;
GObject *button;
GError *error = NULL;
gtk_init (&argc, &argv);
builder = gtk_builder_new();
if(gtk_builder_add_from_file(builder, "main-window.ui", &error) == 0)
{
g_printerr ("Error loading file: %s\n", error->message);
g_clear_error (&error);
return 1;
}
window = gtk_builder_get_object (builder, "window");
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
button = gtk_builder_get_object (builder, "buttonOpen");
g_signal_connect (button, "clicked", G_CALLBACK (buttonClicked), window);
//some widgets don't draw if their parent window was not "show alled"
gtk_widget_show_all(GTK_WIDGET(window));
gtk_main ();
return 0;
}
Note that gpointer is actually a void* so you can pass to your function whatever you like.

Printing value of entry box in a dialog in gtk c

I have worked recently with gtk+ in c language.
I have tried to communicate between two callbacks in a dialog and not in the main window (like here). But, unlike the solutions in the link, the program crushes (in the second callback when I try to use the widget I get from the parameters).
This is my code for This:
#include <gtk/gtk.h>
#include <stdlib.h>
#include <stdio.h>
static void print_text (GtkWidget *widget, gpointer data)
{
GtkEntry* entry = data;
printf("%s", gtk_entry_get_text(entry));
}
static void open_dialog (GtkWidget *widget, gpointer data)
{
GtkWidget *window = data;
GtkWidget *dialog;
GtkWidget *content_area;
GtkWidget *grid;
GtkWidget *label;
GtkWidget *button;
static GtkEntry *textbox;
dialog = gtk_dialog_new_with_buttons ("Get Text",
window,
GTK_DIALOG_MODAL,
GTK_STOCK_OK,
GTK_RESPONSE_OK,
NULL);
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
grid = gtk_grid_new();
gtk_container_add (GTK_CONTAINER (content_area), grid);
label = gtk_label_new("Value: ");
gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1);
textbox = gtk_entry_new();
gtk_entry_set_text(textbox, "<Value>");
gtk_grid_attach(GTK_GRID(grid), textbox, 1, 0, 1, 1);
gtk_widget_show_all (dialog);
g_signal_connect (GTK_DIALOG (dialog), "response", G_CALLBACK (print_text), textbox);
}
static void activate (GtkApplication *app, gpointer user_data)
{
GtkWidget *window;
GtkWidget *button;
GtkWidget *entry;
GtkWidget *grid;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
grid = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (window), grid);
button = gtk_button_new_with_label ("Print Text");
g_signal_connect (button, "clicked", G_CALLBACK (open_dialog), window);
gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 1, 1);
gtk_widget_show_all (window);
}
int main (int argc, char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
The program should have printed the value of the entry box which in the dialog after closing the dialog. Note: in the main window there is a button that opens the dialog.
Thanks for helping!
Problem is on the print_text function. The prototype for GtkDialog response signal is:
void user_function (GtkDialog *dialog,
gint response_id,
gpointer user_data)
So you must change your function to:
static void print_text (GtkWidget *widget, gint response_id, gpointer data)
{
GtkEntry* entry = data;
printf("%s", gtk_entry_get_text(entry));
gtk_widget_destroy (widget); // This will close the dialog
}

Menu doesn't display while creating it in GTK+ 3 C

Screenshot of the output
i am new with gtk+. while learning to create menus in gtk+ i simply copy paste the following code and when i run it....i don't know what is the problem but only it shows window. it does not show any menus or menu bar... help me if anyone has been through this problem...
#include <gtk/gtk.h>
GdkPixbuf *create_pixbuf(const gchar * filename)
{
GdkPixbuf *pixbuf;
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_file(filename, &error);
if (!pixbuf) {
fprintf(stderr, "%s\n", error->message);
g_error_free(error);
}
return pixbuf;
}
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *icon;
GtkWidget *vbox;
GtkWidget *menubar;
GtkWidget *fileMenu;
GtkWidget *fileMi;
GtkWidget *quitMi;
GtkWidget *text_view;
GtkWidget *buffer;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Write Pad");
gtk_window_set_default_size(GTK_WINDOW(window), 500, 400);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
icon = create_pixbuf("Web.png");
gtk_window_set_icon(GTK_WINDOW(window), icon);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
text_view = gtk_text_view_new ();
gtk_box_pack_start (GTK_BOX (vbox), text_view, 1, 1, 0);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
menubar = gtk_menu_bar_new();
fileMenu = gtk_menu_new();
fileMi = gtk_menu_item_new_with_label("File");
quitMi = gtk_menu_item_new_with_label("Quit");
gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileMi), fileMenu);
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), quitMi);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fileMi);
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(quitMi), "activate", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
There are a few problems with the code. All of the variables you declare use the GtkWidget * type, while the functions create_pixbuf and gtk_text_view_get_buffer return data of the GdkPixbuf * and GtkTextBuffer * types. You also use a deprecated function.
Moreover, you call the menu related functions after the GtkTextView related functions, thereby placing the menu at the bottom of the window.
Here is the working code:
#include <gtk/gtk.h>
GdkPixbuf *
create_pixbuf (const gchar *filename)
{
GdkPixbuf *pixbuf;
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_file (filename, &error);
if (!pixbuf) {
fprintf (stderr, "%s\n", error->message);
g_error_free (error);
}
return pixbuf;
}
int
main (int argc, char *argv[])
{
GtkWidget *window;
GdkPixbuf *icon;
GtkWidget *vbox;
GtkWidget *menubar;
GtkWidget *fileMenu;
GtkWidget *fileMi;
GtkWidget *quitMi;
GtkWidget *text_view;
GtkTextBuffer *buffer;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
icon = create_pixbuf ("Web.png");
gtk_window_set_title (GTK_WINDOW (window), "Write Pad");
gtk_window_set_default_size (GTK_WINDOW (window), 500, 400);
gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
gtk_window_set_icon (GTK_WINDOW (window), icon);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
menubar = gtk_menu_bar_new ();
fileMenu = gtk_menu_new ();
fileMi = gtk_menu_item_new_with_label ("File");
quitMi = gtk_menu_item_new_with_label ("Quit");
gtk_menu_item_set_submenu (GTK_MENU_ITEM (fileMi), fileMenu);
gtk_menu_shell_append (GTK_MENU_SHELL (fileMenu), quitMi);
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), fileMi);
gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
text_view = gtk_text_view_new ();
gtk_box_pack_start (GTK_BOX (vbox), text_view, TRUE, TRUE, 0);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (G_OBJECT (quitMi), "activate", G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}

Resources