0

次のことを行おうとしているアプリケーションがあります。

  • GTK2トップレベルのメインウィンドウを作成する
  • ウィジェットを絶対的に配置するために、メインウィンドウに固定フレームを追加します
  • GtkImagesアニメーションGIFSと静的を表示するために使用されるマトリックスを作成しますJPEGS
  • 起動時にJPEGS、リストからランダムに選択されたスタティックがマトリックスを埋めます
  • イベントが発生すると、マトリックスはアニメーションで埋められますGIFS
  • アニメーションが終了すると、おそらく異なるものJPEGSがマトリックスに再び表示されます

実行時エラーは、ランダムに選択された2つ以上がJPEGSマトリックスの行に配置されている場合にのみ発生します。

このような実行時エラーの例を次に示します。

(wrong:3909): Gtk-WARNING **: Can't set a parent on widget which has a parent

行の各イメージが一意である場合、実行時エラーは発生しません。

コードスニペットと実行時の出力は次のとおりです。

/*
 * 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;
}

2つ以上の一致するシンボル(画像)が行に配置された場合の実行時エラー:

[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

これが発生すると、行の一部の画像が空になります(白)。

一致する記号(画像)が行に配置されていない場合に出力します。

[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]

この場合、すべての画像が正しく表示されます。

修正方法と私が間違っている可能性があることについての提案はありますか?

4

1 に答える 1

1

画像を別のウィジェットに配置すると、その (親) ウィジェットによって所有および管理されるようになります。複数のウィジェットに追加することはできません。

gtk_image_new_from_file()これを機能させる簡単な方法は、ウィンドウに追加するたびに画像をロードすることです。それをしたくない場合はgtk_image_new_from_image()、ウィジェットに追加する前に画像をコピーするなどの方法を使用できます。

于 2012-07-31T05:37:30.480 に答える