2013-10-09 44 views
0

这里是我的代码: 如果我尝试使用循环在屏幕上放置多张卡片,我只能获得最后一张 卡片,如果我不使用循环并且只尝试处理它处理的一张卡片正好。 我的一些代码来自Stack Overflow,有些来自其他来源。我已经有了“设置甲板”,“改变甲板”,以及大部分玩惯例的程序,但是这让我很难过。如何在GTK的图形屏幕上处理多个图像?

#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; 
} 

回答

0

在你的循环,你有

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

530ms后,您time_handler()函数运行七次。但是,到目前为止,全球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

0

GtkFixed用于将小部件放置在固定位置,但您需要的更可能是一个画布小部件。有several ones available,社区尚未就最佳设计达成共识(理想地进入GTK +本身)。或者你可以使用GtkDrawingAreacairo自己完成所有绘图。