且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在一个固定的布局GTK2放置图片

更新时间:2023-01-27 15:36:09

一旦你将图像放置到另一个窗口小部件

,它成为拥有和由(父)部件管理 - 你可以把它添加到一个以上的小部件

最简单的方式得到这个工作是装入图像gtk_image_new_from_file()您想将它添加到窗口各一次。如果你不想这样做,也许你可以将它添加到窗口小部件之前,使用类似 gtk_image_new_from_image()来复制图像。

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 animated GIFS and static JPEGS
  • 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 like gtk_image_new_from_image() to copy the image prior to adding it to the widget.