Working with UI Files¶
User Interface (UI) files contain descriptions of the application components that the user can interact with. These files are typically created using a Rapid Application Development (RAD) or Graphical User Interface (GUI) tool, such as Glade and imported into applications as resources.
This guide aims to describe these files, cover how they are created, and show how they are packaged and used in applications.
Getting the Example¶
The example application for this guide has a very simple user interface that looks like the following figure.
This application can be obtained from the app-resources-ui repository, which is part of the collection of repositories at the Librem 5 examples project. You can either clone and build the application from the command line or open it in GNOME Builder.
File Format Overview¶
UI files are XML files containing a hierarchy of elements, describing visible components of the user interface and other supporting information. Glade uses this information to create a representation of the user interface. In an application, components like GtkBuilder use this information to create and configure instances of GTK classes.
The example application’s user interface looks like the following figure when viewed in Glade.
This interface is described by the contents of the src/ui/window.ui
file in the repository:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkApplicationWindow" id="window">
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes"><span size='xx-large'>Hello world!</span></property>
<property name="use_markup">True</property>
</object>
</child>
</object>
</interface>
By looking closely at the XML text, we can see that the <object>
elements describe a Gtk.ApplicationWindow widget containing a GtkLabel showing a short text message. Child elements of these, such as <property>
describe how each widget is configured.
Note the id
property on the object describing the Gtk.ApplicationWindow widget:
<object class="GtkApplicationWindow" id="window">
The id
attribute allows the application code to refer to specific widgets. In this case, the main window of the application can be referred to using the window
identifier.
The <requires>
element contains information about the libraries that provide the components specified in the UI file. In the example, all the components can be provided by GTK version 3.20.
Creating UI Files¶
The Glade Tutorials page in the GNOME Wiki contains references to documents that show how to use Glade’s user interface.
Once the UI files required by the application have been created, they can be saved alongside the source code and kept under version control in a repository. Since the files are XML-based, and therefore text-based, changes to them can be reviewed by eye as the user interface evolves.
Packaging UI Files¶
Applications that use UI files can load them at run-time using a number of different methods. Since an application will depend on those files being available, it makes sense to include them alongside executable files as resource bundles. This is done by listing the UI files in a resource description XML file.
The app_resources_ui.gresource.xml
file in the application’s src
directory refers to the window.ui
file in the application’s src/ui
directory, using a relative path from the directory containing the XML file:
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/com/example/app_resources_ui">
<file>ui/window.ui</file>
</gresource>
</gresources>
The <gresource>
element defines the prefix that the application will use to locate these files at run-time. This is described in more detail below.
This file is compiled to a binary bundle using the glib-compile-resources tool. When GNOME Builder is used to build an application, this step is taken care of automatically. However, if you use Meson to describe the build process for a command line build, this process can be automated with a build action like the following one from the src/meson.build
file:
gnome = import('gnome')
gnome.compile_resources('app_resources_ui',
'app_resources_ui.gresource.xml',
gresource_bundle: true,
install: true,
install_dir: pkgdatadir,
)
Where pkgdatadir
is typically defined like this:
pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name())
See the Application Resources guide for a more general description of resource bundles.
Reading UI Files in Applications¶
There are two ways for applications to load and construct the contents of UI files. Applications written in C typically use GtkBuilder. Python applications can use the corresponding Gtk.Builder class or the new Gtk.Template
mechanism instead.
Using Gtk.Builder¶
User interfaces can be loaded from UI files and used when they are required. This can be done in the application’s own do_startup
or do_activate
methods, or when a window needs to be created based on a definition in a UI file.
The example uses Gtk.Builder to load the UI file from the resource bundle in the application’s do_activate
method, using the full resource path to the window.ui
file embedded within. This path is the combination of the /com/example/app_resources_ui
prefix in the XML resource description and the ui/window.ui
path to the file within:
def do_activate(self):
builder = Gtk.Builder()
builder.add_from_resource('/com/example/app_resources_ui/ui/window.ui')
window = builder.get_object("window")
Using the builder’s get_object
method, we can refer to objects in the UI file that have id
attributes. In this case, we refer to the object with the window
identifier, which is a Gtk.ApplicationWindow instance.
Once the window has been obtained in this way, it can be used like any other widget.
More Examples¶
The user interface of the Treasure example application is based on a UI file. Gtk.Builder is used to construct the user interface and application menu, as described in the User Interface section of the example’s documentation.