Loading GTK UI files

Hi everyone,

I’m learning GTK development with C and I’m trying to figure out how to properly load UI files.

All of the examples I see simply pass the file name (with no path) to gtk_builder_new_from_file or add_from_file. This works fine when I compile the application into the same directory as the UI file and run it from there.

However, I’m using GNOME Builder and Meson.

My meson.build file is as follows:

project('example1', 'c')

executable(
	meson.project_name(),
	sources: [
		'main.c',
	],
	dependencies: [
		dependency('gtk+-3.0')
  	],
	install: true
)
install_data('builder.ui')

With this file, I can build and run the application from GNOME Builder. However, it crashes with a Failed to open file “builder.ui”: No such file or directory message. The only workaround I’ve found is to specify an absolute path instead of a file name, but that doesn’t feel right. Surely, I don’t want absolute paths in my code? Or should I always install the app to /usr/share, even when developing?

Also, I found the following in the GTK Manual:

Other files, such as GtkBuilder ui files, are best loaded from resources stored in the application binary itself. This eliminates the need for most of the files that would traditionally be installed in an application-specific location in /usr/share .

But I have no idea how to do this.

So what’s the preferred way of loading UI files in real-world GTK app?

1 Like

The easy way to do this, is to define a symbol that is filled out by the build system, e.g.

pkgdatadir = get_option('prefix') / get_option('datadir') / meson.project_name()

install_data('builder.ui', install_dir: pkgdatadir)

executable(
  ...,
  c_args: [ '-DPKGDATADIR="@0@"'.format(pkgdatadir) ],
  ...,
)

Then, in your application, you can use PKGDATADIR:

GError *error = NULL;
GtkBuilder *builder =
  gtk_builder_new_from_file (PKGDATADIR "/builder.ui", &error);

The way to bundle ancillary data files in your application is to use GResource. You list your files in an XML manifest, call the glib-compile-resources tool, and load the resources when starting your application. Now, every time you wish to load a bundled resource, you can use the path of the resource as specified in the manifest file.

You can easily deal with building resources with Meson.

Many GNOME applications do this, in various languages, so it should be easy for you to find examples.

1 Like

Thanks @ebassi, I’ll take a look at GResource!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.