Background image isn't persisting after gtk_container_remove/add



My program sets the background image of widgets from a pixmap with
style->bg_pixmap[GTK_STATE_NORAL].  The background image shows up
correctly when I draw the window.  However, if I remove any widget
with a background pixmap style with g_object_ref() followed by
gtk_container_remove(), and then I re-add the widget to the container,
the background image does not show up.  All I get is a grey background
on the widget when I re-add it.

I think that gtk_container_remove() is destroying the style I've set
because it also unrefs my background image pixmap.

Can I stop this behavior?  I'd like to be able to remove a widget and
re-add it without having to mess with the style again.  I think I can
work around this issue by ref'ing the background pixmap before
removing the widget and then re-applying the style after re-adding the
widget to the container.  But doing this makes me think I'm doing
something wrong...

Here is a sample program to demonstrate.  To build it, I run the
following command:
g++ -Wall -g bgtest.cpp -o bgtest `pkg-config --cflags --libs gtk+-2.0`

To execute it, I just run ./bgtest.  That brings up a window with 2
buttons, one which has a red background.  If you click the "Remove
button" button, the button with the red background will go away.  If
you click that button again, the button will come back but it won't
have a red background anymore.

#include <gtk/gtk.h>

GtkWidget *window = NULL;
GtkWidget *container = NULL;
GtkWidget *button = NULL;
GtkWidget *bgButton = NULL;
GdkPixbuf *myBgPixbuf = NULL;
GdkPixmap *myBgPixmap = NULL;
bool removed = false;
extern const guint8 my_pixbuf[] __attribute__ ((__aligned__ (4)));

static void onClick(GtkWidget *widget, gpointer data)
{
	GtkWidget *container = GTK_WIDGET(data);

	removed = !removed;
	if( !removed ) {
		// The bgButton is not in the container.  So we'll add it to the container
		// and change the other button text to "Remove button" indicating the
		// action that will happen if the user clicks it.
		gtk_box_pack_start(GTK_BOX(container), bgButton, FALSE, FALSE, 0);
		gtk_button_set_label(GTK_BUTTON(widget), "Remove button");
		g_object_unref(bgButton);
	}
	else {
		// The bgButton is in the container.  Reference it to prevent it from
		// being destroyed when we remove it from the container, and then remove
		// it.
		g_object_ref(bgButton);
		gtk_container_remove(GTK_CONTAINER(container), bgButton);
		gtk_button_set_label(GTK_BUTTON(widget), "Add button");
	}
}

int main(int argc, char *argv[])
{

	gtk_init(&argc, &argv);
	
	container = gtk_vbox_new(FALSE, 0);

	button = gtk_button_new_with_label("Remove button");
	bgButton = gtk_button_new_with_label("bg image");
	g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(onClick), container);

	myBgPixbuf = gdk_pixbuf_new_from_inline(-1, my_pixbuf, FALSE, NULL);
	gdk_pixbuf_render_pixmap_and_mask(myBgPixbuf, &myBgPixmap, NULL, 255);

	GtkStyle *bgStyle = gtk_style_copy(gtk_widget_get_style(bgButton));
	bgStyle->bg_pixmap[GTK_STATE_NORMAL] = myBgPixmap;
	gtk_widget_set_style(bgButton, bgStyle);

	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

	gtk_box_pack_start(GTK_BOX(container), button, FALSE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX(container), bgButton, FALSE, FALSE, 0);
	gtk_container_add(GTK_CONTAINER(window), container);

	gtk_widget_show_all(window);
	gtk_main();

	return 0;
}

const guint8 my_pixbuf[] __attribute__ ((__aligned__ (4))) =
{ ""
 /* Pixbuf magic (0x47646b50) */
 "GdkP"
 /* length: header (24) + pixel_data (316) */
 "\0\0\1T"
 /* pixdata_type (0x2010001) */
 "\2\1\0\1"
 /* rowstride (300) */
 "\0\0\1,"
 /* width (100) */
 "\0\0\0d"
 /* height (100) */
 "\0\0\0d"
 /* pixel_data: */
 "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377"
 "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377"
 "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0"
 "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377"
 "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377"
 "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0"
 "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377"
 "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377"
 "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0"
 "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377"
 "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377"
 "\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0"
 "\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377"
 "\0\0\377\377\0\0\377\377\0\0\377\377\0\0\377\377\0\0\336\377\0\0"
};


Thanks,
Jason M.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]