Re: gtk_container_remove() and pack later again
- From: David NeÄas <yeti physics muni cz>
- To: "fkater googlemail com" <fkater googlemail com>
- Cc: gtk-app-devel-list gnome org
- Subject: Re: gtk_container_remove() and pack later again
- Date: Fri, 22 Jan 2010 15:50:44 +0100
On Fri, Jan 22, 2010 at 03:13:58PM +0100, fkater googlemail com wrote:
I have some strange effects: Nearly all displayed text in
widgets (labels, buttons etc) is *sometimes* suddenly
replaced by squares. I suspect the bug is somewhere around
gtk_container_remove().
So, could anyone please confirm if this is correctly coded:
(1) To remove a child for possible later usage I do:
g_object_ref(G_OBJECT(child));
gtk_container_remove(
GTK_CONTAINER(container),GTK_WIDGET(child));
/* it is unclear at coding time if the wiget will ever
* be needed again or not, so: */
g_object_force_floating(child));
(2) To later re-pack the child
/* I hope this does internally g_object_ref_SINK() ...: */
gtk_box_pack_start/end(
GTK_BOX(container), child, ...);
(3) Before the child is destroyed (app closed) I do: */
...
if( g_object_is_floating( G_OBJECT(child) ))
{
g_object_ref_sink( G_OBJECT(child) );
g_object_unref( G_OBJECT(child) );
}
In any case, it's overengineered. Containers do not require the widgets
put to them to have floating references; they do g_object_ref_sink()
which either adds a reference or changes the floating reference to
normal one. So, you can do
0) When you create the child widget:
g_object_ref(child);
1) When you remove the child from its container:
nothing special
2) When you repack the child elsehwere
nothing special
3) When you are definitely done with the child widget:
g_object_unref(child);
See the attached demo.
Yeti
====================================================================
#include <gtk/gtk.h>
static void
swallow(GtkWidget *button,
GtkWidget *label)
{
GtkWidget *parent_b, *parent_l;
parent_b = gtk_widget_get_parent(button);
parent_l = gtk_widget_get_parent(label);
if (parent_l == parent_b)
return;
gtk_container_remove(GTK_CONTAINER(parent_l), label);
gtk_box_pack_end(GTK_BOX(parent_b), label, TRUE, TRUE, 12);
}
static void
construct(GtkWidget *label, gboolean pack_here)
{
GtkWidget *window, *vbox, *button;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
button = gtk_button_new_with_label("Swallow Label");
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
g_signal_connect(button, "clicked", G_CALLBACK(swallow), label);
if (pack_here)
gtk_box_pack_end(GTK_BOX(vbox), label, TRUE, TRUE, 12);
gtk_widget_show_all(window);
}
static void
finalized(G_GNUC_UNUSED gpointer unused,
G_GNUC_UNUSED GObject *label)
{
g_print("Label finalized.\n");
}
int
main(int argc, char *argv[])
{
GtkWidget *label;
gtk_init(&argc, &argv);
label = gtk_label_new("Label");
g_object_ref(label);
g_object_weak_ref(G_OBJECT(label), finalized, NULL);
construct(label, TRUE);
construct(label, FALSE);
construct(label, FALSE);
gtk_main();
g_object_unref(label);
return 0;
}
====================================================================
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]