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 Jul 25, 2014 1:01 pm

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: variable value disappearing
PostPosted: Thu Feb 07, 2008 9:33 pm 
Offline

Joined: Thu Feb 07, 2008 9:19 pm
Posts: 4
Hi there,

I have a little problem with GTK and I am in hopes someone here may be able to help me out. I just started with GTK, and I'm sorry if I missed something obvious.

The problem is, when handing over a variable/pointer from main() to another function, its value gets lost along the way. The function g_signal_connect() seems to be responsible for this, but on the other hand, I doubt there's a problem with a function so essential to GTK, which leaves me kinda clueless.

Here's the code, I removed everything that's not essential and added a couple debug messages. You will notice that when running the program through the terminal and after clicking the button, it will say: "ptr_usr is ", even though it should say "ptr_usr is X".

Thanks for any help you can provide.

Code:
#include <gtk/gtk.h>
#include <string.h>

static void callback(GtkWidget *widget,char *ptr_user)
   {
   g_print("\n#callback\n");
   g_print("ptr_user is %c\n",*ptr_user);
   g_print("ptr_user target address is %p\n",ptr_user);
   g_print("ptr_user address is %p\n",&ptr_user);
   }

static gboolean delete_event(GtkWidget *widget,GdkEvent  *event,gpointer data)
   {
   gtk_main_quit ();
   return FALSE;
   }

int main(int argc, char *argv[])
   {
   GtkWidget *window;
   GtkWidget *button1;
   GtkWidget *box, *box_line1;
   char *ptr_user;
   char user = 'X';
   ptr_user =& user;

   gtk_init (&argc, &argv);
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   gtk_window_set_title (GTK_WINDOW(window), "Hello Buttons!");
   gtk_container_set_border_width(GTK_CONTAINER (window), 10);

   g_signal_connect (G_OBJECT (window), "delete_event",G_CALLBACK (delete_event), NULL);

   box = gtk_vbox_new(FALSE, 0);
   box_line1 = gtk_hbox_new(FALSE, 0);
   button1 = gtk_button_new_with_label(" ");
   gtk_box_pack_start(GTK_BOX(box_line1),button1,TRUE,TRUE,20);
   gtk_box_pack_start(GTK_BOX(box),box_line1,TRUE,TRUE,0);
   gtk_container_add(GTK_CONTAINER (window),box);
   gtk_widget_show_all(window);

   g_print("\n#main\n");
   g_print("user is %c\n",user);
   g_print("user address is %p\n",&user);
   g_print("ptr_user is %c\n",*ptr_user);
   g_print("ptr_user target address is %p\n",ptr_user);
   g_print("ptr_user address is %p\n",&ptr_user);

   user = g_signal_connect(G_OBJECT(button1),"clicked",G_CALLBACK(callback),(gpointer)ptr_user);

   gtk_main();
   return 0;
   }
[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 08, 2008 3:37 am 
Offline
Familiar Face

Joined: Thu Dec 27, 2007 3:49 pm
Posts: 38
You are using a local variable.

_________________
Linux is the best


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 08, 2008 6:03 am 
Offline

Joined: Thu Feb 07, 2008 9:19 pm
Posts: 4
can you be a bit more specific, please?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 08, 2008 7:02 am 
Offline
Familiar Face

Joined: Thu Dec 27, 2007 3:49 pm
Posts: 38
You variable is located on stack and when your program exit from function your values is detroyed, i think, But i dont know if
Code:
g_signal_connect(G_OBJECT(button1),"clicked",G_CALLBACK(callback),(gpointer)ptr_user);


allocates a new memory for your pointer.

_________________
Linux is the best


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 08, 2008 7:33 am 
Offline

Joined: Thu Feb 07, 2008 9:19 pm
Posts: 4
Ok, you seem to be right. Thanks you so far, but now the next question is how do I send my pointer to the callback() function through g_signal_connect() if both, pointers and addresses, don't work?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 08, 2008 4:52 pm 
Offline
Familiar Face

Joined: Wed Dec 19, 2007 5:06 pm
Posts: 13
Using a local variable won't be a problem here, because main() never exits while gtk_main() is running.

Your problem is that you're assigning the return value of g_signal_connect to user. What are you trying to do there? But it's certainly going to overwrite the previous value of 'X', anyway.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 09, 2008 8:40 am 
Offline

Joined: Thu Feb 07, 2008 9:19 pm
Posts: 4
"user =" was a leftover from my experimenting. I got the rest figured out now though, thanks guys.

I am attaching the full source here. It's a very simple version of tic tac toe which was just for getting used to GTK.

I came, however, across another problem when trying to add some sort of victory notifier:

I don't get the idea behind the way g_signal_connect is called. I thought it would be called upon X sending a user action (i.e. a mouse click), but apparently, all g_signal_connect functions are called when the program is launched and from there, only the last one is called (or so it seems).

This results in a very irritating output like this:
(return): button_id 1
(return): button_id 2
(return): button_id 3
(return): button_id 4
(return): button_id 5
(return): button_id 6
(return): button_id 7
(return): button_id 8
(return): button_id 9

upon click on _any_ button GTK always returns the id of the last button:
(tictac): button_id 9
(tictac):
(tictac):
(tictac):
(tictac):

Is there a page where this behavior is explained or can one of you explain it? Again, sorry if it's a stupid question.

Code:
#include <gtk/gtk.h>
#include <string.h>

struct tictacstruct
   {
   char *user;
   GtkWidget *sbar;
   int context_id;
   char *TicTacToe;
   int button_id;
   };

static int *return_ttpass(int button_id,struct tictacstruct *ttpass)
   {
g_print("(return):  button_id %i\n",button_id);
   ttpass->button_id = button_id;
   return (int *)ttpass;
   }

static void tictac(GtkWidget *widget,struct tictacstruct *ttpass)
   {
   if(!strncmp(gtk_button_get_label(GTK_BUTTON(widget))," ",1))
      {
      if(!strncmp(ttpass->user,"X",1))
         {ttpass->user = "O";}
      else
         {ttpass->user = "X";}
      gtk_button_set_label(GTK_BUTTON(widget),ttpass->user);

      if(!strncmp(ttpass->user,"X",1))
         {
         gtk_statusbar_push(GTK_STATUSBAR(ttpass->sbar),ttpass->context_id,"put an O");
         ttpass->TicTacToe[(ttpass->button_id-1)] = 'X';
         }
      else
         {
         gtk_statusbar_push(GTK_STATUSBAR(ttpass->sbar),ttpass->context_id,"put an X");
         ttpass->TicTacToe[(ttpass->button_id-1)] = 'O';
         }

g_print("(tictac):  button_id %i\n",ttpass->button_id);
g_print("(tictac):  %c\n",ttpass->TicTacToe[0]);
g_print("(tictac):  %c\n",ttpass->TicTacToe[1]);
g_print("(tictac):  %c\n",ttpass->TicTacToe[2]);
g_print("(tictac):  %c\n",ttpass->TicTacToe[3]);
      }
   }

static gboolean delete_event(GtkWidget *widget,GdkEvent *event,gpointer data)
   {
   gtk_main_quit();
   return FALSE;
   }

int main(int argc, char *argv[])
   {
   GtkWidget *window;
   GtkWidget *button1, *button2, *button3, *button4, *button5, *button6, *button7, *button8, *button9;
   GtkWidget *box, *box_line1, *box_line2, *box_line3;
   GtkWidget *sbar;
   guint context_id;
   struct tictacstruct ttpass;
   char *user = "O";
   char TicTacToe[9] = {' ',' ',' ',' ',' ',' ',' ',' ',' '};
   

   gtk_init(&argc, &argv);
   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_window_set_title(GTK_WINDOW(window),"Tic Tac Toe");
   gtk_container_set_border_width(GTK_CONTAINER (window),10);

   sbar = gtk_statusbar_new();
   context_id = gtk_statusbar_get_context_id(GTK_STATUSBAR(sbar),"foo");
   gtk_statusbar_push(GTK_STATUSBAR(sbar),context_id,"put an X");
   ttpass.user = user;
   ttpass.sbar = sbar;
   ttpass.context_id = context_id;
   ttpass.TicTacToe =& TicTacToe[0];

   g_signal_connect (G_OBJECT (window), "delete_event",G_CALLBACK (delete_event), NULL);

   box = gtk_vbox_new(FALSE, 0);
   box_line1 = gtk_hbox_new(FALSE, 0);
   box_line2 = gtk_hbox_new(FALSE, 0);
   box_line3 = gtk_hbox_new(FALSE, 0);

   button1 = gtk_button_new_with_label(" ");
   button2 = gtk_button_new_with_label(" ");
   button3 = gtk_button_new_with_label(" ");
   button4 = gtk_button_new_with_label(" ");
   button5 = gtk_button_new_with_label(" ");
   button6 = gtk_button_new_with_label(" ");
   button7 = gtk_button_new_with_label(" ");
   button8 = gtk_button_new_with_label(" ");
   button9 = gtk_button_new_with_label(" ");

   gtk_box_pack_start(GTK_BOX(box_line1),button1,TRUE,TRUE,20);
   gtk_box_pack_start(GTK_BOX(box_line1),button2,TRUE,TRUE,20);
   gtk_box_pack_start(GTK_BOX(box_line1),button3,TRUE,TRUE,20);
   gtk_box_pack_start(GTK_BOX(box_line2),button4,TRUE,TRUE,20);
   gtk_box_pack_start(GTK_BOX(box_line2),button5,TRUE,TRUE,20);
   gtk_box_pack_start(GTK_BOX(box_line2),button6,TRUE,TRUE,20);
   gtk_box_pack_start(GTK_BOX(box_line3),button7,TRUE,TRUE,20);
   gtk_box_pack_start(GTK_BOX(box_line3),button8,TRUE,TRUE,20);
   gtk_box_pack_start(GTK_BOX(box_line3),button9,TRUE,TRUE,20);

   gtk_box_pack_start(GTK_BOX(box),box_line1,TRUE,TRUE,0);
   gtk_box_pack_start(GTK_BOX(box),box_line2,TRUE,TRUE,0);
   gtk_box_pack_start(GTK_BOX(box),box_line3,TRUE,TRUE,0);
   gtk_box_pack_start(GTK_BOX(box),sbar,TRUE,TRUE,0);

   gtk_container_add(GTK_CONTAINER (window),box);

   gtk_widget_show_all(window);

   g_signal_connect(G_OBJECT(button1),"clicked",G_CALLBACK(tictac),return_ttpass(1,&ttpass));
   g_signal_connect(G_OBJECT(button2),"clicked",G_CALLBACK(tictac),return_ttpass(2,&ttpass));
   g_signal_connect(G_OBJECT(button3),"clicked",G_CALLBACK(tictac),return_ttpass(3,&ttpass));
   g_signal_connect(G_OBJECT(button4),"clicked",G_CALLBACK(tictac),return_ttpass(4,&ttpass));
   g_signal_connect(G_OBJECT(button5),"clicked",G_CALLBACK(tictac),return_ttpass(5,&ttpass));
   g_signal_connect(G_OBJECT(button6),"clicked",G_CALLBACK(tictac),return_ttpass(6,&ttpass));
   g_signal_connect(G_OBJECT(button7),"clicked",G_CALLBACK(tictac),return_ttpass(7,&ttpass));
   g_signal_connect(G_OBJECT(button8),"clicked",G_CALLBACK(tictac),return_ttpass(8,&ttpass));
   g_signal_connect(G_OBJECT(button9),"clicked",G_CALLBACK(tictac),return_ttpass(9,&ttpass));

   gtk_main();
   return 0;
   }
[/code]


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 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