GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Fri Oct 31, 2014 8:27 am

All times are UTC




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: Passing structure with a callback
PostPosted: Tue Jul 24, 2012 3:10 am 
Offline

Joined: Tue Jul 24, 2012 12:06 am
Posts: 4
I'm really new to this whole GUI and GTK thing, so I hope I can get away with a few beginner questions, as I'm sure that the answer to what's going wrong here is simple if you understand what's going on (which I don't, yet.)

I'm working on my very first GTK program, mostly as a project/excuse to learn GTK, and am trying to pass a structure containing GtkEntry widgets (and a few other things, but this is enough to demonstrate my problem) to a function via a
callback.

My widgetshare structure gets passed from main() to MainMenu with no apparent problem, but using the same scheme to pass emailshare from MainMenu to Clear segfaults.

Click on Verify, then Clear. Blammo.

What am I doing wrong? What is different about the callback in main() that causes that one to actually work versus the one in MainMenu? This works if I pass only the widget (not in a structure), so I'm baffled.

Code:
#include <gtk/gtk.h>

struct ShareWidgets{
   GtkWidget *vbox;
   GtkWidget *action;
   GtkToolItem *verify;
   };

struct ShareEmail{
   GtkWidget *email;
   };


void MainMenu(GtkWidget *verify, struct ShareWidgets *widgetshare);
void Clear(GtkWidget *button, struct ShareEmail *emailshare);

int main( int argc, char *argv[])
   {
   GtkWidget *window, *icon, *toolbar;
   struct ShareWidgets widgetshare;
   
   gtk_init(&argc, &argv);
   
   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_window_set_default_size(GTK_WINDOW(window), 575, 400);
   g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
   
   widgetshare.vbox = gtk_vbox_new(FALSE, 0);
   gtk_container_add(GTK_CONTAINER(window), widgetshare.vbox);

   toolbar = gtk_toolbar_new();
   
   gtk_container_set_border_width(GTK_CONTAINER(toolbar), 2);
   
   icon=gtk_image_new_from_icon_name(GTK_STOCK_DIALOG_QUESTION,GTK_ICON_SIZE_LARGE_TOOLBAR);
   widgetshare.verify=gtk_tool_button_new(icon,"Verify");
   gtk_toolbar_insert(GTK_TOOLBAR(toolbar), widgetshare.verify, -1);
   g_signal_connect(G_OBJECT(widgetshare.verify), "clicked", G_CALLBACK(MainMenu), (gpointer)&widgetshare);
   gtk_box_pack_start(GTK_BOX(widgetshare.vbox), toolbar, FALSE, FALSE, 0);
   widgetshare.action = gtk_hbox_new(FALSE, 0);
   gtk_container_add(GTK_CONTAINER(widgetshare.vbox), widgetshare.action);
   gtk_widget_show_all(window);
   gtk_main();
   return 0;
   }


void MainMenu(GtkWidget *verify, struct ShareWidgets *widgetshare)
   {
   GtkWidget *table, *buttonbox, *button;
   struct ShareEmail emailshare;
   gtk_widget_destroy(widgetshare->action);
   widgetshare->action = gtk_vbox_new(FALSE, 0);
   gtk_box_pack_start(GTK_BOX(widgetshare->vbox), widgetshare->action, FALSE,FALSE,0);
   table=gtk_table_new(4,3,FALSE);
   gtk_box_pack_start(GTK_BOX(widgetshare->action),table,FALSE,FALSE,0);
   emailshare.email=gtk_entry_new();
   gtk_entry_set_max_length(GTK_ENTRY(emailshare.email),50);
   gtk_entry_set_width_chars(GTK_ENTRY(emailshare.email),50);
   gtk_table_attach(GTK_TABLE(table),emailshare.email,1,3,2,3,GTK_SHRINK,GTK_SHRINK,0,0);

   buttonbox=gtk_hbutton_box_new();
   gtk_table_attach(GTK_TABLE(table),buttonbox,2,3,3,4,GTK_SHRINK,GTK_SHRINK,0,0);
   button=gtk_button_new();
   button=gtk_button_new_from_stock(GTK_STOCK_CLEAR);
   gtk_container_add(GTK_CONTAINER(buttonbox),button);
   g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(Clear), (gpointer)&emailshare);
   gtk_widget_show_all(widgetshare->action);
   return;
   }

void Clear(GtkWidget *button, struct ShareEmail *emailshare)
   {
   gtk_editable_delete_text(GTK_EDITABLE(emailshare->email),0,-1);
   return;
   }


Top
 Profile  
 
 Post subject: Re: Passing structure with a callback
PostPosted: Tue Jul 24, 2012 6:26 am 
Offline

Joined: Tue Jul 24, 2012 12:06 am
Posts: 4
It occurs to me that the problem here may be that all roads lead to gtk_main().

If my current theory is correct, then by creating the emailshare structure in the MainMenu function that structure is not available in main(), and hence is not being passed to the Clear function when the clear icon is clicked. In other words, I'm passing garbage data to Clear because the emailshare structure is local to MainMenu.

I'm not entirely sure of how the flow of a GTK program actually works, but I am under the impression that a running program just sits in gtk_main() and waits for something to happen, when something happens it executes the appropriate callback, and then returns to gtk_main() and waits again. If this flow is accurate, then since the widgetshare structure in my little program is created in main(), it is available to everything that's being called by gtk_main(), which is why passing a pointer to that structure works but passing a pointer to emailshare doesn't. Under this scenario the Clear function is being called from main() and not from MainMenu.

Is my understanding of how this actually works correct? If so, what is the recommended way to deal with structures like this? Set up everything in main()? Use global structs? If I set up everything in main() then things could get really complicated when dealing with nested containers.


Top
 Profile  
 
 Post subject: Re: Passing structure with a callback
PostPosted: Tue Jul 24, 2012 6:45 am 
Offline
Never Seen the Sunlight

Joined: Mon Apr 28, 2008 5:52 am
Posts: 768
Location: UK
Hi Frank,

You are correct in the way GTK+ handles signals and that everything runs from the gtk_main loop. You also do not state which version of GTK+ you are using, as some of the widgets that you are using are now deprecated in GTK+ v3.

One solution you could use is to pass only the pointer to the widget. So in the case of "Clear" you could pass the pointer to the GtkEntry widget as all that function does is clear the entry. In this case the widgets are created on the heap, so will have the life time of the widgets and not the much shorter life of anything created on the stack.

_________________
E.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google Adsense [Bot] and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group