0

これが私のコードです:ループを使用して複数のカードを画面に配置しようとすると、最後のカードしか配られません。ループを使用せずに1枚のカードのみを配ろうとすると、問題なく配られます。私のコードの一部は Stack Overflow からのもので、一部は他のソースからのものです。「デックのセットアップ」、「デックのシャッフル」、およびハンド ルーチンのほとんどのプレイは完了しましたが、これは私を困惑させました。

#include <cairo.h>
#include <gtk/gtk.h>

/*  Global Structure to hold
1. The image to be moved across the screen
2. The main window
3. The fixed surface so that I can place event boxes on it
4. The Start and End locations for the image
5. a counter
6. an animation counter
7. a boolean timer
8. a tid for the timeout
*/
struct {
    GtkWidget   *image;
    GtkWidget   *window;
    GtkWidget   *fixed;
    gint        initC, initR;
    gint        endC, endR;
    gint        count;
    gint        animations;
    gboolean    timer;
    guint       tid;
} glob;

// finalizes g_object_weak_ref for images

static void finalized(G_GNUC_UNUSED gpointer unused, G_GNUC_UNUSED GObject *Data)
{
g_print("Card finalized.\n");
}

// my drawing routine from Stack OverFlow

static void do_drawing()
{
  gint x, y;
  gdouble scale;

        // The scale tells us where to place the image

        scale = (gdouble) glob.count / (gdouble) glob.animations;

        // The new position adds the progress to the initial
        x = (scale * (glob.endC - glob.initC)) + glob.initC;
        y = (scale * (glob.endR - glob.initR)) + glob.initR;
        g_object_ref(glob.image);
        g_object_weak_ref(G_OBJECT(glob.image), finalized, NULL);
        if(glob.count == 0 )
           { gtk_fixed_put ((GtkFixed *)glob.fixed, glob.image, x, y); }
        gtk_fixed_move ((GtkFixed *)glob.fixed, glob.image , x, y);
        gtk_widget_show(glob.image);
        glob.count++;
        // If this has run 'animations' times, remove
        // the timeout by returning FALSE
    if(glob.count >= glob.animations)
    glob.timer = FALSE;

  // Otherwise, continue running the timeout

}
// time handler for g_timeout_add

static gboolean time_handler()
{
  if (glob.timer == FALSE) return FALSE;
    do_drawing();
  return TRUE;
}

static void deal()
{
//  Initialize the cards to deal
    gchar   *names[7] = { "Card1.png", "Card2.png", "Card3.png", "Card4.png", "Card5.png", "Card6.png", "Card7.png" };
    guint   i = 0;

//  Initialize the global holder for the animation
//  with the start location and end location
//  initC = initial Column, initR = initial Row
    glob.timer = TRUE;
    glob.count = 0;
    glob.initC = 500;
    glob.initR = 15;
    glob.endC = 5;
    glob.endR = 495;
    glob.animations = 50;

    /*  This does not work it only shows
    the last iteration of the images (Card7)
    if I do not use a loop and only do
    one, it works just fine but only for one card
*/
       do
        {
            glob.image = gtk_image_new_from_file(names[ i ]);
            glob.tid = g_timeout_add( 530, (GSourceFunc) time_handler, NULL);
            g_print("Tid = %d \n", glob.tid);
            glob.endC = glob.endC + 70;
            i++;
/*  If I try to use g_source_remove nothing works
//            g_source_remove(glob.tid);
*/
        } while( i < 7 );

}

int main(int argc, char *argv[])
{
    GtkWidget *bkgd;
     gint    i;

    gtk_init(&argc, &argv);

    glob.fixed = gtk_fixed_new();
    bkgd  = gtk_image_new_from_file ( "BackGround.jpg");
    gtk_container_add(GTK_CONTAINER(glob.fixed), bkgd);

    glob.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_container_add(GTK_CONTAINER(glob.window), glob.fixed);
    g_signal_connect(glob.window, "destroy",
        G_CALLBACK (gtk_main_quit), NULL);

    gtk_window_set_position(GTK_WINDOW(glob.window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(glob.window), 1000, 550);
    gtk_window_set_title(GTK_WINDOW(glob.window), "Image");

        deal();

    gtk_widget_show_all(glob.window);

    gtk_main();

//    Apparently not needed
//    g_object_unref(glob.image);

  return 0;
}
4

2 に答える 2

0

GtkFixed はウィジェットを固定位置に配置するために使用されますが、必要なのはおそらくキャンバス ウィジェットです。利用可能なものはいくつかありますが、コミュニティはまだ可能な限り最良の設計についてコンセンサスに達していません (理想的には GTK+ 自体に入る)。または、 GtkDrawingAreacairoを使用してすべての描画を自分で行うこともできます。

于 2013-10-14T23:13:29.923 に答える
0

あなたのループでは、あなたは持っています

glob.image = gtk_image_new_from_file(names[i]);
glob.tid = g_timeout_add( 530, (GSourceFunc) time_handler, NULL);

530 ミリ秒後、time_handler()関数は 7 回実行されます。ただし、この時点で、グローバルglob.imageはカード 7 の画像に設定されているため、描画関数は毎回カード 7 の画像を描画するだけです。

代わりに、ロードしたばかりの画像をタイムアウト関数に渡す必要があります。次のようなもの:

GtkWidget *image = gtk_image_new_from_file(names[i]);
g_object_ref_sink(image);
g_timeout_add(530, (GSourceFunc) time_handler, image);

動作するはずです。time_hander()また、関数を次のように変更する必要があります。

static gboolean time_handler(gpointer data)
{
    GtkImage *image = GTK_IMAGE(data);
    if (glob.timer == FALSE) return FALSE;
        do_drawing(image);
    g_object_unref(image);
    return TRUE;
}

グローバルではなくdo_drawing()渡されたものを描画するように関数を変更します。GtkImage*glob.image

于 2013-10-09T08:56:22.907 に答える