Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Gtk+/Gnome Application Development
Prev Home Next

More on Signals and Callbacks

If either of the signals the program connects to is emitted, the corresponding callback is called. Our "delete_event" callback ends the gtk_main() event loop by calling gtk_main_quit(); this causes gtk_main() to return, ending the program. The "clicked" callback replaces the text from the label with the same text in reverse. Notice that the label was passed to the callback as the user_data parameter to gtk_signal_connect().

A common mistake is to assume that all signals use the same kind of callback---not true. Each signal requires a callback with a particular type signature and particular behavior. The "clicked" signal has a very common callback type; its callback receives a pointer to the widget emitting the signal and any user_data provided by the programmer. This callback must return void or memory corruption is likely to occur.

"delete_event", on the other hand, is something of a special case. It accepts three arguments; the first and last are analagous to "clicked", while the second is a pointer to the event which triggered the signal (events are messages from X to the application, reporting mouse movements, key presses, and the like). The "delete_event" callback returns a "magic" value---if FALSE is returned, GTK+ will destroy the window; if TRUE is returned, GTK+ will do nothing. Return TRUE if you need to do something other than destroy the window; for example, you might want to warn the user about an unsaved document.

Widget header files are the best quick reference for callback signatures. The "class structure" for the widget will have a space for a default signal handler; your handler should be modeled on the default one. For example, in gtk/gtkbutton.h the GtkButton class struct looks like this:


struct _GtkButtonClass
{
  GtkBinClass        parent_class;
  
  void (* pressed)  (GtkButton *button);
  void (* released) (GtkButton *button);
  void (* clicked)  (GtkButton *button);
  void (* enter)    (GtkButton *button);
  void (* leave)    (GtkButton *button);
};

the chapter called The GTK+ Object and Type System explains exactly what a class struct is for; for now, just pay attention to the function pointers, and note that they correspond to signals. To get from this:


  void (* clicked)  (GtkButton *button);

to this:


  static void button_click_cb(GtkWidget* w, gpointer data);

simply add a gpointer data to the class struct function's signature. In Hello, World I've also changed the type from GtkButton* to GtkWidget*; this is common, since it can be more convenient to have a GtkWidget*. The argument will always be the GtkButton emitting the signal.

Another example may be useful; here is "delete_event" from gtk/gtkwidget.h:


  gint (* delete_event)            (GtkWidget          *widget,
                                    GdkEventAny        *event);

and the callback from Hello, World:


static gint delete_event_cb(GtkWidget* w, GdkEventAny* e, gpointer data);

That's all there is to it. You can write simple GTK+ applications using only the information presented in this section. GTK+ and Gnome are powerful application development tools because you can think about real functionality, instead of struggling to get a window on the screen.

Gtk+/Gnome Application Development
Prev Home Next

 
 
  Published under free license. Design by Interspire