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

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

  




 

 

Gtk+/Gnome Application Development
Prev Home Next

Widget Concepts

This section discusses concepts that apply to all widgets, including memory management and certain special states widgets can be in. It's a "conceptual" section; however, the concepts are very important to practical topics covered later in the book.

Widget Life Cycle

Widget resource and memory management is mostly automatic. However, there are a couple of "gotchas" to keep in mind if you're doing more complicated things.

#include <gtk/gtkwidget.h>

void gtk_widget_destroy(GtkWidget* widget);

Figure 21. Widget Destruction

A widget can be destroyed at any time by calling gtk_widget_destroy() (shown in Figure 21); destroying a widget frees any associated memory and other resources. If the widget is inside a container, it is automatically removed from the container before it's destroyed. It's worth noting that gtk_widget_destroy() is simply another name for gtk_object_destroy(); GtkObjects have "virtual destructors" so gtk_object_destroy() will always do the right thing.

Internally, a reference count is maintained for all widgets (actually, all GtkObjects). Objects begin their life with a reference count of 1, even though they have not yet been referenced. At this stage the object is said to be floating and is flagged as such. It is possible to remove the object's initial reference; this is called sinking the floating object and will destroy the object if the floating reference was the only one.

Containers first reference and then sink any floating widgets that are added to them. By sinking a widget, a container "takes ownership" of it for resource management purposes. Thus, the reference count of the widget remains 1, but the object is no longer flagged as floating. When a widget is removed from a container---or the container is destroyed---the reference count is decremented to 0. When an object's reference count reaches 0, it is destroyed.

In practice, this means that you only have to destroy toplevel widgets; any widgets that are inside a container will be destroyed along with the container.

There's a danger here, however. Sometimes you want to remove a widget from a container; perhaps some element of your interface is optional or only appears under certain circumstances. When you remove the widget (using gtk_container_remove()), it will be unreferenced, its reference count will drop to 0, and it will be destroyed. To avoid this situation, you should add a reference to the widget before you remove it. Figure 22 lists the functions to manipulate reference counts.

#include <gtk/gtkobject.h>

void gtk_object_ref(GtkObject* object);

void gtk_object_unref(GtkObject* object);

void gtk_object_sink(GtkObject* object);

Figure 22. Reference Counting

gtk_object_ref() and gtk_object_unref() have widget-specific variants (gtk_widget_ref(), etc.) but the object and widget versions are completely synonymous. The widget-specific versions are leftovers from earlier versions of GTK+.

So to safely remove a widget from a container, you might do this:


  gtk_widget_ref(widget);
  gtk_container_remove(container, widget);

The widget now has one reference, held by your code. At some point you'll need to release the reference, destroying the widget. (It would make sense to do so after re-adding the widget to some other container, for example.)

It's worth pointing out that removing widgets from containers is uncommon; in general it's faster to simply hide the widget with gtk_widget_hide(), then gtk_widget_show() it at some later time.

gtk_object_sink() is used almost exclusively in widget implementations, when you expect to be the primary "owner" of an object. If an object is not "floating", gtk_object_sink() has no effect. To claim ownership of a widget, do this:


  gtk_widget_ref(widget);
  gtk_object_sink(GTK_OBJECT(widget));

This code adds one reference to the widget; if the widget was "floating," it also subtracts one reference. If the widget was not floating, gtk_widget_sink() has no effect.

It's important to understand the details because in some cases they can be important. But most of the time, you can get by with a few simple rules:

  • You must destroy any toplevel widgets when you are done with them, but child widgets are destroyed automatically.

  • If you want to remove a widget from a container without destroying it, you must first add a reference to the widget.

  • If you add a reference to a widget, you are responsible for unreferencing the widget again when you're done with it.

Gtk+/Gnome Application Development
Prev Home Next

 
 
  Published under free license. Design by Interspire