GTK Glade C Example Text Reader Program

Build a text reader application in this simple GTK Glade C example tutorial. A GTK tutorial that goes a step beyond an easy hello world example program.

This tutorial shows how create a GUI windowed application using GTK, Glade and C code. The application is a simple text reader that can open a text file and display its contents in the application window. Below is an image of the application built in this tutorial. As can be seen in the image, the application has been used to open a C source file.

GTK Glade C Example Program that Reads Text Files
GTK Glade C Example Program that Reads Text Files

Part 22 of GTK 3 Programming with C and Glade Tutorial

See the full GTK3 tutorial index

GTK Glade C Example Overview

This tutorial shows how to place the following widgets and objects in the Glade user interface designer.

  • GtkMenuBar – a menu bar at the top of the application window
  • GtkImageMenuItem – a menu item with image in a menu bar
  • GtkScrolledWindow – adds scroll bars to the text view area automatically when needed
  • GtkTextView – an area for displaying text in the app window
  • GtkTextBuffer – holds the text displayed in GtkTextView
  • GtkFileChooserDialog – a dialog box for opening files

More information on how the GTK text widgets work can be found in the text widget overview article on the Gnome developer website.

In the C code the application uses a library function from GLib called g_file_get_contents() which reads the entire contents of a file in one go. No need to get a handle to the file then call open, read and close functions.

Text Reader GTK Glade C Example Tutorial Steps

Follow the tutorial steps below to create the text reader application using GTK, Glade and C code.

1. Start a New GTK Glade C Project

Copy the template files to start a new project. Give the new project a name, as described in the next steps.

1.1 Copy the Template Files

Copy the template files from part 4 of this tutorial series and rename the copied folder to text_reader.

1.2 Modify the Make File

Name the project text_reader in the make file found in the project folder. This is done by changing the TARGET name as can be seen in the listing that follows.

makefile

# change application name here (executable output name)
TARGET=text_reader

# 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. Lay Out the Application Window in Glade

It is assumed that you have been following this tutorial series and know the basics of using Glade. Steps to build the GUI for this GTK Glade C example in Glade follow.

2.1 Open the Glade File and Edit the Main Window

Open the file window_main.glade in the Glade editor. It is found in the glade folder of the project.

Click the main window in Glade to select it. Make the following changes to the main window attributes.

  • Change the title to Text Reader
  • Default width: 640
  • Default height: 480

2.2 Place a GtkBox Container

Place a GtkBox in the main window. Reduce the number of items to 2.

2.3 Place a GtkMenuBar

Find the GtkMenuBar under Containers in Glade. Place a GtkMenuBar in the top open box of the GtkBox.

2.4 Edit the GtkMenuBar

The GtkMenuBar comes with some items already on the menu. We need to remove the unwanted items.

Right-click the Edit item and remove it by clicking Delete from the menu that pops up.

Remove the View item in the same way.

2.5 Edit the File Menu

The File menu contains 5 menu items by default. We must remove 3 of these items and add 1.

Right-click the File item in the GtkMenuBar and select Edit… from the menu that pops up.

2.5.1 Remove Unwanted Menu Items

Use the Edit Menu Bar dialog box to delete the gtk-new, gtk-save and gtk-save-as image items. This is done by selecting each item in the left pane of the dialog box and then clicking the minus button at the bottom right of the pane. To see the image item names, scroll down in the right pane, or resize the dialog box.

2.5.2 Add a Close Menu Item

Still in the Edit Menu Bar dialog box, in the left pane, click the plus button at the bottom of the pane. Delete the Label text in the right pane. Change the Type from Normal Item to Image Item.

Change the Stock Item to Close, which will become gtk-close after selection.

Drag the gtk-close Image Item under gtk-open in the left pane of the dialog box. Close the dialog box when done.

2.5.3 Add Menu Item ID and Handler Function

Give each of the GtkImageMenuItem widgets an ID and handler function as shown in the following table. The handler functions are added for the activate signal.

Stock ItemStock ItemSignal Handler Function
gtk-openmenuitm_openon_menuitm_open_activate
gtk-closemenuitm_closeon_menuitm_close_activate
gtk-quitmenuitm_quiton_menuitm_quit_activate

2.6 The Help Menu

The Help menu is not used in this part of the tutorial series. It will be used in the next part to add an About box to the application.

2.7 Place a GtkScrolledWindow

Under Containers in Glade, find a GtkScrolledWindow in the second box of the GtkBox.

Under the Packing tab of the GtkScrolledWindow, switch on the Expand button.

2.8 Place a GtkTextView

In Glade, under the Display button, find GtkTextView. Place a GtkTextView in the GtkScrolledWindow that was just placed.

2.9 Change GtkTextView Attributes

Change the following GtkTextView Attributes.

  • Make the ID txtvw_main under the General tab
  • Switch on the Monospace switch
  • Uncheck Editable and Cursor Visible
  • Under the Common tab, change Border width to 10

2.10 Add a GtkTextBuffer to the GtkTextView

With the GtkTextView still selected, under the General tab, click the pencil icon at the right of the Buffer box.

In the dialog box that pops up , click the New button.

Find the new GtkTextBuffer in the left pane of Glade and click it to select it. Change its ID to textbuffer_main.

Add some default text for the text buffer to the Text field under the General tab: Use the menu to open a file.

2.11 Place a GtkFileChooserDialog

Under the Toplevels button in Glade, find the GtkFileChooserDialog item and click it to place it.

2.12 Change the GtkFileChooserDialog Attributes

Change the ID of the GtkFileChooserDialog to dlg_file_choose under the General tab.

Click the pencil icon at the right of the Transient For box. In the dialog box that pops up, click the radio button next to window_main. Click the OK button.

Change the Title to Open Text File.

2.13 Add an Open Button to the Dialog Box

An Open button and then a Cancel button must be added to the GtkFileChooserDialog in the two open spaces at the bottom right. The image that follows shows the buttons after being added to the dialog box.

Add Buttons to the GtkFileChooserDialog Dialog Box
Add Buttons to the GtkFileChooserDialog Dialog Box
  • Place a GtkButton in the left open slot at the bottom of the dialog box
  • Change the Response ID of the button to OK using the drop-down list
  • Change the button label to Open
  • Under the Common tab, check the Can default item

2.14 Add a Cancel Button to the Dialog Box

  • Place a GtkButton in the bottom right open box of the dialog box
  • Change the Response ID of the button to Cancel using the drop-down list
  • Change the button label to Cancel

3. Write the C Code

Finally add the C code for this GTK Glade C example to main.c in the src folder as shown in the listing that follows.

main.c

#include <gtk/gtk.h>

typedef struct {
    GtkWidget *w_txtvw_main;            // Pointer to text view object
    GtkWidget *w_dlg_file_choose;       // Pointer to file chooser dialog box
    GtkTextBuffer *textbuffer_main;     // Pointer to text buffer
} 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"));
    // Get pointers to widgets
    widgets->w_txtvw_main = GTK_WIDGET(gtk_builder_get_object(builder, "txtvw_main"));
    widgets->w_dlg_file_choose = GTK_WIDGET(gtk_builder_get_object(builder, "dlg_file_choose"));
    widgets->textbuffer_main = GTK_TEXT_BUFFER(gtk_builder_get_object(builder, "textbuffer_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
    gchar *file_contents = NULL;    // For reading contents of file
    gboolean file_success = FALSE;  // File read status
    
    // Show the "Open Text File" dialog box
    gtk_widget_show(app_wdgts->w_dlg_file_choose);
    
    // Check return value from Open Text File 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) {
            // Copy the contents of the file to dynamically allocated memory
            file_success = g_file_get_contents(file_name, &file_contents, NULL, NULL);
            if (file_success) {
                // Put the contents of the file into the GtkTextBuffer
                gtk_text_buffer_set_text(app_wdgts->textbuffer_main, file_contents, -1);
            }
            g_free(file_contents);
        }
        g_free(file_name);
    }

    // Finished with the "Open Text File" dialog box, so hide it
    gtk_widget_hide(app_wdgts->w_dlg_file_choose);
}

// File --> Close
void on_menuitm_close_activate(GtkMenuItem *menuitem, app_widgets *app_wdgts)
{
    // Clear the text from window "Close the file"
    gtk_text_buffer_set_text(app_wdgts->textbuffer_main, "", -1);
}

// File --> Quit
void on_menuitm_quit_activate(GtkMenuItem *menuitem, app_widgets *app_wdgts)
{
    gtk_main_quit();
}

// called when window is closed
void on_window_main_destroy()
{
    gtk_main_quit();
}

For an explanation of how the GTK Glade C example project code works, watch the video embedded near the top of this page. Alternatively, study the code, read the comments and refer to the GTK 3 documentation for functions used.

Leave a Reply

Your email address will not be published. Required fields are marked *