Reputation: 35
I have written a simple code to display a raw image buffer in a window using gtk:
#include <gtk/gtk.h>
int main (int argc, char *argv[])
{
const int Width = 1920, Height = 1080;
char *buffer = (char*)malloc(3 * Width * Height);
// Read a raw image data from the disk and put it in the buffer.
// ....
GtkWidget *window;
GtkWidget* image;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data (buffer, GDK_COLORSPACE_RGB,
FALSE, 8, Width, Height, Width*3, NULL, NULL);
gtk_window_set_title (GTK_WINDOW (window), "Image Viewer");
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
image = gtk_image_new_from_pixbuf (pixbuf);
gtk_container_add(GTK_CONTAINER (window), image);
gtk_widget_show_all (window);
gtk_main ();
free (buffer);
return 0;
}
How can I change this code to display a sequence of N
images like a movie (i.e. continuous playback, not by choosing images manually using an image dialog box)? The main display loop is controlled by gtk_main()
which ends when the user closes the window. I think the loop to assign the images to the image gadget should be inside an event handler of the image gadget, but I do not know that event handler.
Upvotes: 1
Views: 3011
Reputation: 11454
In fact, this is trivial ;).
You need to understand that once you call gtk_main
, everything is ruled by the GLib "main loop", which is an event loop like in pretty much all GUI toolkits. GTK will then react to events it receives.
So you need a way to create those events. If for example you want to perform an action periodically (the action here being "display a new picture"), you'd just call g_timeout_add
and pass it a callback to call every second for example. Use the user_data
parameter to pass a pointer a structure where you'll easily find your GtkImage
as well as the list of images you want to display). In the callback, you will just change the image displayed, most likely using gtk_image_set_from_pixbuf
.
g_timeout_add_seconds
does the same thing as g_timeout_add
, but with less precision (second instead of millisecond), but it has the advantage of being more battery friendly (less CPU wakeups = more energy saved).
You may also want to trigger an action on a different way that a timer. For that you have g_idle_add
which will call your callback when the program is idle (no event to process).
Read the documentation of these functions in the documentation of the GLib main event loop.
Upvotes: 2