How to start and stop GtkImage gifs in GTK +

I have a GTK+ application written in C that loads a matrix of animated GIF . These GtkImages automatically start the animation when they load, and then stop when the animation is complete. How to restart the animation of each GtkImage containing a GIF , and will signals be generated when the animation is complete?

Thanks.

EDIT:
Will using gdk_pixbuf_animation_get_iter() described here make this possible?

The full code is given below.

 /* * Compile me with: * gcc -o reels reels.c $(pkg-config --cflags --libs gtk+-2.0 gmodule-2.0) */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <time.h> /* GTK */ #include <gdk/gdkx.h> #include <gtk/gtk.h> /**** prototypes ****/ static void destroy (GtkWidget*, gpointer); GdkPixbuf *create_pixbuf(const gchar * filename); GtkWidget *SetupWindow(gchar *data, const gchar *filename); static void destroy (GtkWidget *window, gpointer data); void btnSpin_clicked(GtkWidget *button, gpointer data); void btnExit_clicked(GtkWidget *button, gpointer data); /********************/ GtkWidget *images[3][5]; static void destroy (GtkWidget *window, gpointer data) { gtk_main_quit (); } void btnSpin_clicked(GtkWidget *button, gpointer data) { printf("Spin Button pressed.\n"); return; } void btnExit_clicked(GtkWidget *button, gpointer data) { gtk_main_quit(); return; } GtkWidget *SetupWindow(gchar *data, const gchar *filename) { GdkPixmap *background; GdkPixbuf *pixbuf; GdkScreen *ourscreen; GdkColormap *colormap; GtkStyle *style; GdkColor fg; GdkColor bg; GError *error = NULL; GdkRectangle *rect; GtkWidget *window; pixbuf = gdk_pixbuf_new_from_file (filename,&error); if (error != NULL) { if (error->domain == GDK_PIXBUF_ERROR) { g_print ("Pixbuf Related Error:\n"); } if (error->domain == G_FILE_ERROR) { g_print ("File Error: Check file permissions and state:\n"); } g_printerr ("%s\n", error[0].message); } gdk_pixbuf_render_pixmap_and_mask (pixbuf, &background, NULL, 0); style = gtk_style_new (); style->bg_pixmap[0] = background; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), data); // gtk_window_maximize(GTK_WINDOW(window)); gtk_window_set_modal (GTK_WINDOW (window),TRUE); gtk_window_set_default_size(GTK_WINDOW(window),628,530); gtk_widget_set_style (GTK_WIDGET(window), GTK_STYLE(style)); gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER_ALWAYS); gtk_container_set_border_width(GTK_CONTAINER(window), 0); //gtk_window_set_resizable(GTK_WINDOW(window), (gboolean) FALSE); gtk_window_set_decorated( GTK_WINDOW(window), FALSE ); return(window); } int main (int argc, char *argv[]) { GdkPixbufAnimation *animation; GtkWidget *image; int x,y; GdkPixbuf *pixBuf; GdkPixmap *pixMap; gchar filename[20]; GtkWidget *btnSpin, *btnExit; GtkWidget *frame; /* for absolute positionining of widgets */ GtkWidget *window; int posx, posy; gtk_init (&argc, &argv); window = SetupWindow("Demo", "background.gif"); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL); frame = gtk_fixed_new(); gtk_container_add(GTK_CONTAINER(window), frame); btnSpin = gtk_button_new_with_label("Spin"); gtk_widget_set_size_request(btnSpin, 80, 35); gtk_fixed_put(GTK_FIXED(frame), btnSpin, 229, 485); g_signal_connect(G_OBJECT( btnSpin ), "clicked", G_CALLBACK(btnSpin_clicked), NULL ); btnExit = gtk_button_new_with_label("Exit"); gtk_widget_set_size_request(btnExit, 80, 35); gtk_fixed_put(GTK_FIXED(frame), btnExit, 320, 485); g_signal_connect(G_OBJECT( btnExit ), "clicked", G_CALLBACK(btnExit_clicked), NULL ); /* setup animated gifs */ for( y = 0; y < 3; y++ ) { posy = (y*120) + 20; for( x = 0; x < 5; x++ ) { posx = (x*120) + 20; /* set each Image widget to spin GIF */ sprintf( filename,"%d-%d.gif", y+1,x+1 ); images[y][x] = gtk_image_new_from_file(filename); gtk_fixed_put(GTK_FIXED(frame), images[y][x], posx, posy); } } gtk_widget_show_all(window); gtk_main (); return 0; } 
+4
source share
2 answers

Looking at the source code of GtkImage , I am afraid that there is no signal that is generated when the animation ends. However, you can restart the animation by calling gtk_image_set_from_file() or gtk_image_set_from_animation() .

To completely solve your original problem, I suggest creating a subclass of GtkImage. It should behave exactly like GtkImage, except that animation_timeout should send a signal if delay < 0 around line 1315 .

Information on creating a subclass of GObject (note that GtkImage is GObject) can be found here .

+4
source

Based on user1202136, answer the following code snippets. I publish this if others find it useful.

The main idea is to use GdkPixbufAnimation , gdk_pixbuf_animation_new_from_file and gtk_image_set_from_animation

The following code snippet shows how to do this.

 GtkWidget *images[3][5]; GdkPixbufAnimation *animations[3][5]; /* Initial setup of animated gifs */ for( y = 0; y < 3; y++ ) { for( x = 0; x < 5; x++ ) { /* set each Image widget to spin GIF */ sprintf( filename,"%d-%d.gif", y+1,x+1 ); images[y][x] = gtk_image_new(); animations[y][x] = gdk_pixbuf_animation_new_from_file ( filename , &error); gtk_image_set_from_animation (GTK_IMAGE(images[y][x]), animations[y][x]); gtk_fixed_put(GTK_FIXED(frame), images[y][x], (x*120) + 20, (y*120) + 20); } } /* now to restart the animations use the images and animations array already stored in memory, no need to re-read the animations from disk so this happens quickly */ /* restart animated gifs */ for( y = 0; y < 3; y++ ) { for( x = 0; x < 5; x++ ) { gtk_image_set_from_animation(GTK_IMAGE(images[y][x]), animations[y][x]); } } 
0
source

Source: https://habr.com/ru/post/1415445/


All Articles