I have an application that is attempting to do the following:
- Create a
GTK2
top level main window - Add a fixed frame into the main window for absolute positioning of widgets
- Create a matrix of
GtkImages
that will be used to display animatedGIFS
and staticJPEGS
- On start-up the static
JPEGS
picked randomly from a list will fill the matrix - When an event happens the matrix will be filled with animated
GIFS
- When the animation is over possibly different
JPEGS
will again be displayed in the matrix
Run time errors are happening only when two or more of the randomly selected JPEGS
are placed in a row of the matrix.
Here is an example of such a run time error:
(wrong:3909): Gtk-WARNING **: Can't set a parent on widget which has a parent
If each image of the row are unique no run time errors occur.
Code snippets and run time output are as follows:
/*
* Compile me with:
* gcc -Wall -o wrong wrong.c $(pkg-config --cflags --libs gtk+-2.0 gmodule-2.0)
*/
/* header includes */
/**** prototypes ****/
/********************/
typedef struct
{
unsigned int pixel_width, pixel_height;
gchar fileName[20];
GtkWidget *image;
}symbol_t;
symbol_t symbols[] =
{
{ 118, 107, "images/LO.jpg", NULL },
{ 118, 107, "images/L1.jpg", NULL },
{ 118, 107, "images/L2.jpg", NULL },
{ 118, 107, "images/L3.jpg", NULL },
{ 118, 107, "images/H1.jpg", NULL },
{ 118, 107, "images/H2.jpg", NULL },
{ 118, 107, "images/H3.jpg", NULL },
{ 118, 107, "images/H4.jpg", NULL },
{ 118, 107, "images/H5.jpg", NULL }
};
GtkWidget *frame; /* for absolute positioning of widgets */
GtkWidget *window;
int Init( void )
{
/* initialize random number generator */
}
static void destroy (GtkWidget *window, gpointer data)
{
gtk_main_quit ();
}
GtkWidget *SetupWindow(gchar *data, const gchar *filename)
{
/* setup top-level window setting the background to the image contained
in *filename and return window widget
*/
return(window);
}
int main (int argc, char *argv[])
{
unsigned int y, i, pos_x, pos_y;
gtk_init (&argc, &argv);
Init(); // init random number generator
window = SetupWindow("Broken", "images/background.jpg");
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL);
frame = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(window), frame);
/* setup symbol jpgs */
for( i = 0; i < 9; i++ )
{
/* load each symbol image into memory */
symbols[i].image = gtk_image_new_from_file( symbols[i].fileName );
}
/* display some symbols */
pos_y = 150;
pos_x = 187;
for( y = 0; y < 5 ; y++ ) /* first row - 5 symbols */
{
i = (unsigned int)(random()%9);
printf("Symbol[%d] [%s]\n", i, symbols[i].fileName);
gtk_fixed_put(GTK_FIXED(frame), symbols[i].image, pos_x, pos_y);
pos_x += symbols[i].pixel_width;
}
gtk_widget_show_all(window);
gtk_main ();
return 0;
}
Run time errors when two or more matching symbols ( images ) are placed on the row:
[chim] ~/source/matrix > ./wrong Symbol[1] [images/L1.jpg] Symbol[7] [images/H4.jpg] Symbol[0] [images/LO.jpg] Symbol[7] [images/H4.jpg] (wrong:3909): Gtk-WARNING **: Can't set a parent on widget which has a parent Symbol[5] [images/H2.jpg] (wrong:3909): Gtk-CRITICAL **: gtk_widget_destroy: assertion `GTK_IS_WIDGET (widget)' failed (wrong:3909): Gtk-CRITICAL **: gtk_widget_destroy: assertion `GTK_IS_WIDGET (widget)' failed
When this occurs some of the images in the row are empty ( white ).
Output when no matching symbols ( images ) are placed on the row:
[chim] ~/source/matrix > ./wrong Symbol[1] [images/L1.jpg] Symbol[6] [images/H3.jpg] Symbol[3] [images/L3.jpg] Symbol[0] [images/LO.jpg] Symbol[4] [images/H1.jpg]
And in this case all images are displayed properly.
Any suggestions about how to fix and what I might be doing wrong?
Once you place the image into another widget, it becomes owned and managed by that (parent) widget -- you can't add it to more than one widget.
The simple way to get this to work is to load the image with
gtk_image_new_from_file()
each time you want to add it to the window. If you don't want to do that, maybe you can use something likegtk_image_new_from_image()
to copy the image prior to adding it to the widget.