Skip to main content

Facilities to load simple GTK '.ui' files

Project description

Simple facilities to load GTK '.ui' files in Python

The 'gtk_simple_loader' package provides very simple facilities to load '.ui' files like the ones exported by Cambalache. This module works with GTK 4.0 and higher.

Overview

This module simplifies the loading of simple GTK widgets from '.ui' files. It automatizes some common tasks like load the objects from the '.ui' file and connect the 'activate' signal to the 'on_activate_handler' method.

With the default approach, when loading the GTK widgets from '.ui' files with Gtk.Builder, you need to manually add the files to the Gtk.Builder instance and get each widget object with Gtk.Builder.get_object(). If the user interface file contains multiple widgets, this can be a tedious task and result in a large code like the following:

class App(Gtk.Application):
    def __init__(self, **kwargs: Unpack[AppKwargsTypes]) -> None:
        super().__init__(**kwargs)
        self.connect("activate", self.on_activate_handler)

    def on_activate_handler(self, app: Gtk.Application) -> None:  # noqa: ARG002
        # Configures the bulder to get the objects from the '.ui' file
        self._builder = Gtk.Builder(self)
        self._builder.add_from_file("examples/interface.ui")

        # Gets the objects from the '.ui' file
        self.main_window = self._builder.get_object("main_window")
        self.box_1 = self._builder.get_object("box_1")
        self.entry_1 = self._builder.get_object("entry_1")
        self.scale_1 = self._builder.get_object("scale_1")
        self.button_1 = self._builder.get_object("button_1")
        self.switch_1 = self._builder.get_object("switch_1")
        self.button_2 = self._builder.get_object("button_2")

        # Configures the main window and the shows it
        self.main_window.set_application(self)
        self.main_window.present()

With 'gtk_simple_loader' module, you can replace the above code by the following:

@gtk_simple_loader.builder.load_from_files(["examples/interface.ui"])
class App(Gtk.Application):
    def on_activate_handler(self, app: Gtk.Application) -> None:  # noqa: ARG002
        self.main_window.present()

Because the first core has many lines that load objects, and this module automatizes it, the reduction was significant. With codes that have fewer objects and more callbacks, this reduction will not be so significant.

Static typing

You can apply static typing to the above examples. In these case, you will need to manually add the Type Hints to the objects. So code without 'gtk_simple_loader' and with it will look similar and rave a similar number of lines.

Without 'gtk_simple_loader':

class AppKwargsTypes(TypedDict):
    """Types for the Application keyword arguments."""

    application_id: str


class App(Gtk.Application):
    """Simple example that shows how to load a '.ui' file and create a window."""

    def __init__(self, **kwargs: Unpack[AppKwargsTypes]) -> None:
        """Initialize the application."""
        super().__init__(**kwargs)
        self.connect("activate", self.on_activate_handler)

    def on_activate_handler(self, app: Gtk.Application) -> None:  # noqa: ARG002
        """Show the window.

        Called when the application is launched.

        Parameters
        ----------
        app : Gtk.Application
            The application object (equal to *self* in this context).

        """
        # Configures the bulder to get the objects from the '.ui' file
        self._builder = Gtk.Builder(self)
        self._builder.add_from_file("examples/interface.ui")

        # Gets the objects from the '.ui' file
        self.main_window = cast(Gtk.Window, self._builder.get_object("main_window"))
        self.box_1 = cast(Gtk.Box, self._builder.get_object("box_1"))
        self.entry_1 = cast(Gtk.Entry, self._builder.get_object("entry_1"))
        self.scale_1 = cast(Gtk.Scale, self._builder.get_object("scale_1"))
        self.button_1 = cast(Gtk.Button, self._builder.get_object("button_1"))
        self.switch_1 = cast(Gtk.Switch, self._builder.get_object("switch_1"))
        self.button_2 = cast(Gtk.ToggleButton, self._builder.get_object("button_2"))

        # Configures the main window and the shows it
        self.main_window.set_application(self)
        self.main_window.present()

With 'gtk_simple_loader':

@gtk_simple_loader.builder.load_from_files(["examples/interface.ui"])
class App(Gtk.Application):
    """Simple example that shows how to load a '.ui' file and create a window."""

    def on_activate_handler(self, app: Gtk.Application) -> None:  # noqa: ARG002
        """Show the window.

        Called when the application is launched.

        Parameters
        ----------
        app : Gtk.Application
            The application object (equal to *self* in this context).

        """
        self.main_window: Gtk.Window
        self.box_1: Gtk.Box
        self.entry_1: Gtk.Entry
        self.scale_1: Gtk.Scale
        self.button_1: Gtk.Button
        self.switch_1: Gtk.Switch
        self.button_2: Gtk.ToggleButton

        self.main_window.present()

In terms of code, there are a little less lines, but is more readable. Does not use the cast function or the Unpack type hinting.

A complete example of these codes can be found in the examples/ folder.

Signal handlers

This module does not affect the signal handlers of the source code. This part of the code is equal to a code with 'gtk_simple_loader' and without it. The only facility is that the 'activate' signal will be automatically connected to the 'on_activate_handler' method.

With GTK 4.0 and higher, the Gtk.BUilder automatically connects the signal handlers of the interfaces files to the application instance. You only need to provide it when creating the builder:

self._builder = Gtk.Builder(self)                     # Providing the Gtk.Application instance to the builder
self._builder.add_from_file("examples/interface.ui")  # Loading the interface (signals are connected automatically)

Building

The building process use some bash scripts and Makefile, these will work fine a practically every Linux distribution. If you use Windows, maybe you will need to adjust the scripts/ and the Makefile to your environment.

Otherwise, just run:

make build

Installation

You need to install PyGObject by yourself. There are not an official PyPI package to it.

Local installation

Just run:

make install

Creating interfaces

This module works fine with the user interface files generated by Cambalache. The object name is retrieved from the id attribute of the widget in the interface using the get_buildable_id() method. This will get the 'id' attribute of the <object> tag. In a Cambalache project, you only need to set the 'Object id' in the interface.

This example will load the window with the 'main_window' id as 'self.main_window' in the application instance:

Cambalache-example

A more complex example is available at examples/ folder.

Development

This project uses Python LSP Server with the Mypy plugin for PYLSP and python-lsp-ruff plugins. I could not set up Pyright to work fine with GTK. Maybe because the GTK module makes some manipulation to be possible to load different GTK versions.

The HTML documentation is build with Sphinx and its configuration is available at the sphinx/ folder. In the docstrings of the source code, you can add these extra field lists:

"""
:issue:`1234` -> Shows the issue 1234 in the generated documentation (creates a hyperlink).
:pull:`1234` -> Shows the pull request 1234 in the generated documentation (creates a hyperlink).
"""

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gtk_simple_loader-0.0.1.tar.gz (10.0 kB view details)

Uploaded Source

Built Distribution

gtk_simple_loader-0.0.1-py3-none-any.whl (8.5 kB view details)

Uploaded Python 3

File details

Details for the file gtk_simple_loader-0.0.1.tar.gz.

File metadata

  • Download URL: gtk_simple_loader-0.0.1.tar.gz
  • Upload date:
  • Size: 10.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.0 CPython/3.10.12

File hashes

Hashes for gtk_simple_loader-0.0.1.tar.gz
Algorithm Hash digest
SHA256 15f639b10e29afc995a6584bdfa07208c71dda7492d90c211eb8164ba5c55966
MD5 0750d94181eec166e360b3271e0a23fc
BLAKE2b-256 c376a124fc8f0921e35df4eeba29d9eaf19af0c90d5a65351905104426f5d804

See more details on using hashes here.

File details

Details for the file gtk_simple_loader-0.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for gtk_simple_loader-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 46ca535977d9655a5944b2a77dd1faee6392fd188958c9d6d457017968e5febf
MD5 4c75dd7a107f4bfcc9e60e66671861a7
BLAKE2b-256 3e26ba95d2e86a05360f0d7910a41ceafd8e42f3dcefac91fcad3dcc7b9dc9ea

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page