Make a GTK image viewer using GTK+ 3, Glade and the C programming language. GTK image viewer example project and tutorial. This is a very simple example that opens and displays an image full size.
The image below shows the application built in this part of the tutorial series.

Part 25 of GTK 3 Programming with C and Glade Tutorial
See the full GTK3 tutorial index
About this GTK Image Viewer Tutorial
This tutorial is very similar to the text reader example program from part 22 of this tutorial series. It uses the same basic menu system and file chooser dialog box. The difference is that it uses a GtkImage widget instead of GtkTextView widget. Another difference is that the GtkImage is placed in a GtkViewport widget. These widgets are placed in the main window using Glade user interface designer.
GTK Image Viewer Tutorial Steps
Follow the steps below to create the GTK image viewer project and build the GTK image viewer application.
1. Create a New GTK Glade Project
Copy the new template files folder from part 14 of this tutorial series.
Rename the root folder of the copy of the template files to image_viewer.
Open the make file and change the target name to image_viewer. A full listing of the make file is included below.
# change application name here (executable output name)
TARGET=image_viewer
# compiler
CC=gcc
# debug
DEBUG=-g
# optimisation
OPT=-O0
# warnings
WARN=-Wall
PTHREAD=-pthread
CCFLAGS=$(DEBUG) $(OPT) $(WARN) $(PTHREAD) -pipe
GTKLIB=`pkg-config --cflags --libs gtk+-3.0`
# linker
LD=gcc
LDFLAGS=$(PTHREAD) $(GTKLIB) -export-dynamic
OBJS= main.o
all: $(OBJS)
$(LD) -o $(TARGET) $(OBJS) $(LDFLAGS)
main.o: src/main.c
$(CC) -c $(CCFLAGS) src/main.c $(GTKLIB) -o main.o
clean:
rm -f *.o $(TARGET)
2. Edit the Glade File
Open the window_main.glade Glade file from the glade folder of the template files for editing in Glade. Make the following changes to the Glade file.
2.1 Change the Main Window Title and Size
Give the main window a title of Image Viewer.
Change the default width and height to 800 and 600 respectively.
2.2 Place a GtkBox
Place a GtkBox in the main window. Reduce the Number of items to 2. Leave the remaining settings at their defaults.
2.3 Place a GtkMenuBar and Edit It
Place a GtkMenuBar in the top box of the GtkBox.
Delete Unwanted Menu Items
Leave only the File and Help menu on the menu bar. Delete the other menu items.
Leave only Open and Quit on the File menu. Delete the other menu items on the File menu.
Add Menu Item ID and Handler
Change the ID of the Open menu item to menuitm_open.
Add a signal handler to the Open menu item for the activate signal called on_menuitm_open_activate.
Change the ID of the Quit menu item to menuitm_close.
Add a signal handler to the Quit menu item for the activate signal called on_menuitm_close_activate.
2.4 Place a GtkScrolledWindow
Place a GtkScrolledWindow in the second open box of the GtkBox.
Under the Packing tab in the right pane of Glade, switch the Expand switch on.
2.5 Place a GtkViewport
A GtkImage can not be placed directly into a GtkScrolledWindow, so we must place a GtkViewport in the GtkScrolled Window first.
Find the GtkViewport widget under the Containers button in Glade and place it in the GtkScrolledWindow.
2.6 Place a GtkImage
Find the GtkImage widget under the Display button in Glade and place it in the GtkViewport.
Change the ID of the GtkImage to img_main.
Change the Stock ID of the GtkImage to gtk-discard so that no default icon appears in the image window.
2.7 Place a GtkFileChooserDialog and Edit It
Place a GtkFileChooserDialog in Glade. It is found under the Toplevels button.
Edit the File Chooser Dialog Attributes
Change the ID of the GtkFileChooserDialog to dlg_file_choose.
Select window_main for the Transient For parameter.
Change the Title to Open Image.
Add Buttons to the File Chooser Dialog
Place a GtkButton in each of the open boxes of the file chooser dialog.
The button on the left gets and ID of btn_open, a Response ID of OK and a Label of Open. Under the Common tab, check the Can default widget flag.
The button on the right gets and ID of btn_close, a Response ID of Cancel and a Label of Cancel.
3. Edit the C Code
Add the following code to the main.c file to complete the project.
main.c
#include <gtk/gtk.h>
typedef struct {
GtkWidget *w_dlg_file_choose; // Pointer to file chooser dialog box
GtkWidget *w_img_main; // Pointer to image widget
} app_widgets;
int main(int argc, char *argv[])
{
GtkBuilder *builder;
GtkWidget *window;
app_widgets *widgets = g_slice_new(app_widgets);
gtk_init(&argc, &argv);
builder = gtk_builder_new_from_file("glade/window_main.glade");
window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));
widgets->w_dlg_file_choose = GTK_WIDGET(gtk_builder_get_object(builder, "dlg_file_choose"));
widgets->w_img_main = GTK_WIDGET(gtk_builder_get_object(builder, "img_main"));
gtk_builder_connect_signals(builder, widgets);
g_object_unref(builder);
gtk_widget_show(window);
gtk_main();
g_slice_free(app_widgets, widgets);
return 0;
}
// File --> Open
void on_menuitm_open_activate(GtkMenuItem *menuitem, app_widgets *app_wdgts)
{
gchar *file_name = NULL; // Name of file to open from dialog box
// Show the "Open Image" dialog box
gtk_widget_show(app_wdgts->w_dlg_file_choose);
// Check return value from Open Image dialog box to see if user clicked the Open button
if (gtk_dialog_run(GTK_DIALOG (app_wdgts->w_dlg_file_choose)) == GTK_RESPONSE_OK) {
// Get the file name from the dialog box
file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(app_wdgts->w_dlg_file_choose));
if (file_name != NULL) {
gtk_image_set_from_file(GTK_IMAGE(app_wdgts->w_img_main), file_name);
}
g_free(file_name);
}
// Finished with the "Open Image" dialog box, so hide it
gtk_widget_hide(app_wdgts->w_dlg_file_choose);
}
// File --> Quit
void on_menuitm_close_activate(GtkMenuItem *menuitem, app_widgets *app_wdgts)
{
gtk_main_quit();
}
// called when window is closed
void on_window_main_destroy()
{
gtk_main_quit();
}
Watch the video at the top of the article for an explanation of the C code.
Great 😊😊😊😊😊
I think you mean the template files from part 24 of this series rather than part 14. 🙂