Menu doesn't display while creating it in GTK+ 3 C - 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;
}

Related

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);
}

initialization of GtkImage in c

I'm encountering a Segmentation Fault when I try to make a Gtkwidget point to a memory address where I've load a png from file. I want card[6].image to display the image I've loaded in card[0].image and the I'd like to remove the same image from card[0].image.
struct my_image {
const char *path;
GtkWidget *image;
};
void create_window() {
GtkWidget *window;
GtkWidget *headbar;
GtkWidget *vbox;
GtkWidget *hbox_3;
GtkWidget *hbox_table;
GtkWidget *hbox_1;
GtkWidget *hbox_2;
GtkWidget *about_button;
GtkWidget *event_box1, *event_box2, *event_box3;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
headbar = gtk_header_bar_new();
about_button = gtk_button_new_with_mnemonic("CLick");
event_box1 = gtk_event_box_new ();
event_box2 = gtk_event_box_new ();
event_box3 = gtk_event_box_new ();
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 50);
hbox_3 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 35);
hbox_table = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 35);
hbox_2= gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
hbox_1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 35);
gtk_header_bar_set_title (GTK_HEADER_BAR (headbar), "Myprogram");
gtk_window_set_title (GTK_WINDOW (window), "Myprogram");
gtk_window_set_titlebar (GTK_WINDOW (window), headbar);
gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (headbar), TRUE);
gtk_window_maximize (GTK_WINDOW (window));
card[0].path = pile[0];
card[1].path = pile[1];
card[2].path = pile[2];
card[0].image = gtk_image_new_from_file (card[0].path);
card[1].image = gtk_image_new_from_file (card[1].path);
card[2].image = gtk_image_new_from_file (card[2].path);
card[3].path = "c/fort.png";
card[4].path = "c/fort.png";
card[5].path = "c/fort.png";
card[3].image = gtk_image_new_from_file (card[3].path);
card[4].image = gtk_image_new_from_file (card[4].path);
card[5].image = gtk_image_new_from_file (card[5].path);
card[6].image = gtk_image_new ();
card[7].image = gtk_image_new ();
printf("card 0 address = %u\n", card[0].image);
printf("card 6 address = %u\n", card[6].image);
card[8].path = pile[39];
card[9].path = "c/mazzo.png";
card[8].image = gtk_image_new_from_file (card[8].path);
card[9].image = gtk_image_new_from_file (card[9].path);
g_signal_connect (about_button, "clicked", G_CALLfort (activate_about), NULL);
g_signal_connect (G_OBJECT (event_box1), "button_press_event", G_CALLfort (card1_clicked), card);
g_signal_connect (G_OBJECT (event_box2), "button_press_event", G_CALLfort (card2_clicked), card);
g_signal_connect (G_OBJECT (event_box3), "button_press_event", G_CALLfort (card3_clicked), card);
g_signal_connect (G_OBJECT (window), "destroy", G_CALLfort (destroy), NULL);
gtk_container_add(GTK_CONTAINER (headbar), about_button);
gtk_container_add(GTK_CONTAINER (window), vbox);
gtk_container_add(GTK_CONTAINER (vbox), hbox_3);
gtk_container_add(GTK_CONTAINER (vbox), hbox_table);
gtk_container_add(GTK_CONTAINER (vbox), hbox_2);
gtk_container_add(GTK_CONTAINER (vbox), hbox_1);
gtk_container_add(GTK_CONTAINER (hbox_2), card[8].image);
gtk_container_add(GTK_CONTAINER (hbox_2), card[9].image);
gtk_container_add(GTK_CONTAINER (hbox_1), event_box1);
gtk_container_add(GTK_CONTAINER (hbox_1), event_box2);
gtk_container_add(GTK_CONTAINER (hbox_1), event_box3);
gtk_container_add(GTK_CONTAINER (event_box1), card[0].image);
gtk_container_add(GTK_CONTAINER (event_box2), card[1].image);
gtk_container_add(GTK_CONTAINER (event_box3), card[2].image);
gtk_container_add(GTK_CONTAINER (hbox_3), card[3].image);
gtk_container_add(GTK_CONTAINER (hbox_3), card[4].image);
gtk_container_add(GTK_CONTAINER (hbox_3), card[5].image);
gtk_container_add(GTK_CONTAINER (hbox_table), card[6].image);
gtk_container_add(GTK_CONTAINER (hbox_table), card[7].image);
gtk_widget_show_all (window);
gtk_main();
}
void card1_clicked (GtkWidget *window, struct my_image *card)
{
printf("%s\n", card[0].path);
card[6].image = card[0].image;
/*gtk_image_set_from_file(GTK_IMAGE(card[6].image), card[0].path);*/
}
the images initially are displayed correclty but when trigger card1_clciked this line card[6].image = card[0].image; produces a Segmentation Fault.
I'm not sure if I'm loading the image correctly and how to load another image using the same widget; I've also tried to use the function /*gtk_image_set_from_file(GTK_IMAGE(card[6].image), card[0].path);* with the same effect.
Your callback function for button_press_event signal is not defined properly.
The manual tells us how it shall look like:
// The “button-press-event” signal
gboolean
user_function (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
In your function you are missing one parameter:
void card1_clicked (GtkWidget *window, struct my_image *card)
This means you are using the event pointer to read your card array which causes some illegal read access.
Besides that you do not provide the required boolean return value.

How to add css style context providers for all labels in a grid?

I am trying to set the background color of all labels in GtkGrid. Here is a simplified example:
#include <gtk/gtk.h>
static void activate (GtkApplication* app, gpointer user_data)
{
GtkWidget *window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window1");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
GtkWidget *grid = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (window), grid);
GtkWidget *label1 = gtk_label_new("Hello world!");
gtk_widget_set_hexpand( label1, TRUE);
gtk_grid_attach(GTK_GRID (grid), label1, 0,0,1,1);
GtkWidget *label2 = gtk_label_new("Simple Gtk example");
gtk_widget_set_hexpand( label2, TRUE);
gtk_grid_attach(GTK_GRID (grid), label2, 0,1,1,1);
GtkCssProvider *provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (
provider, "label {background-color: #AAAAAA;}", -1, NULL);
GtkStyleContext *context = gtk_widget_get_style_context (grid);
gtk_style_context_add_provider(
context, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_USER);
gtk_widget_show_all (window);
}
int main (int argc, char **argv) {
GtkApplication *app = gtk_application_new(
"org.gtk.example", G_APPLICATION_FLAGS_NONE );
g_signal_connect( app, "activate", G_CALLBACK(activate), NULL);
int status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref (app);
return status;
}
However, adding the style context provider to the grid's context (as shown above) does not work.
I've modified your code, this will change the background of the labels:
#include <gtk/gtk.h>
static void activate (GtkApplication* app, gpointer user_data)
{
GtkWidget *window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window1");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
GtkWidget *grid = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (window), grid);
GtkWidget *label1 = gtk_label_new("Hello world!");
gtk_widget_set_hexpand( label1, TRUE);
gtk_grid_attach(GTK_GRID (grid), label1, 0,0,1,1);
GtkWidget *label2 = gtk_label_new("Simple Gtk example");
gtk_widget_set_hexpand( label2, TRUE);
gtk_grid_attach(GTK_GRID (grid), label2, 0,1,1,1);
GtkCssProvider *provider = gtk_css_provider_new ();
GdkDisplay *display = gdk_display_get_default();
GdkScreen *screen = gdk_display_get_default_screen (display);
gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_USER);
gtk_css_provider_load_from_data (
provider, "GtkLabel { background-color: #AAAAAA;}", -1, NULL);
gtk_widget_show_all (window);
}
int main (int argc, char **argv) {
GtkApplication *app = gtk_application_new(
"org.gtk.example", G_APPLICATION_FLAGS_NONE );
g_signal_connect( app, "activate", G_CALLBACK(activate), NULL);
int status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref (app);
return status;
}
Result:

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

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

How to make gtk_window_set_position of gtk work?

I want to set the position of the window using gtk_window_set_position
but it seems that after the window is created, the gtk_window_set_position will not take effect.
I'm wondering how to call gtk_window_set_position after the window shows up, i.e. a button event?
I just wrote a minimal working example that implements two approaches. One approach uses gtk_window_move and the other gtk_window_set_position.
If you have the gtk+ reference at hand the code should be self explanatory.
#include <gtk/gtk.h>
#include <glib.h>
void
button1_clicked_cb (GtkWidget * widget, GtkWindow * window)
{
GdkWindow *root;
gint width, height, rwidth, rheight;
gtk_window_get_size (window, &width, &height);
root = gtk_widget_get_root_window (GTK_WIDGET (window));
gdk_window_get_geometry (root, NULL, NULL, &rwidth,
&rheight);
gtk_window_move (window, (rwidth - width) / 2,
(rheight - height) / 2);
}
void
button2_clicked_cb (GtkWidget * widget, GtkWindow * window)
{
gtk_widget_hide (GTK_WIDGET (window));
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_widget_show_all (GTK_WIDGET (window));
}
int
main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *box;
GtkWidget *button1;
GtkWidget *button2;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
button1 = gtk_button_new_with_label ("approach 1");
button2 = gtk_button_new_with_label ("approach 2");
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
gtk_box_pack_start (GTK_BOX (box), button1, TRUE, TRUE,
10);
gtk_box_pack_start (GTK_BOX (box), button2, TRUE, TRUE,
10);
gtk_container_add (GTK_CONTAINER (window), box);
gtk_widget_show_all (window);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (button1, "clicked",
G_CALLBACK (button1_clicked_cb),
window);
g_signal_connect (button2, "clicked",
G_CALLBACK (button2_clicked_cb),
window);
gtk_main ();
return 0;
}

Resources