Interfaces#

GObject interfaces are a way of ensuring that objects passed to C code have the right capabilities.

When a GObject implements an interface it should implement an expected set of methods, properties and signals. In the Python sense, an interface is another class that is inherited.

For example in GTK, Gtk.Image supports various sources for the image that it will display. Some of these sources can be a Gio.Icon or a Gdk.Paintable, both are actually interfaces so you don’t pass a direct instance of these, instead you should use some of the gobjects that implement the interface. For Gio.Icon those can be Gio.ThemedIcon that represents an icon from the icon theme, or Gio.FileIcon that represents an icon created from an image file.

Another important interface of reference is Gio.ListModel. It represents a mutable list of GObject.Objects. If you want to implement Gio.ListModel you must implement three methods, these are Gio.ListModel.get_item_type(), Gio.ListModel.get_n_items() and Gio.ListModel.get_item(). The interfaces methods that you should implement are exposed as virtual methods. With these methods any consumer can iterate the list and use the objects for any purpose.

Tip

A generic implementation of Gio.ListModel is Gio.ListStore. It allows you to set the GObject.Object type that it will store and provides methods to append, insert, sort, find and remove gobjects.

Example#

In this examples we’ll be implementing a Gio.ListModel in Python. It will store a custom GObject.Object and provide some helper methods for it.

 1from gi.repository import Gio, GObject
 2
 3
 4class Person(GObject.Object):
 5    __gtype_name__ = 'Person'
 6
 7    name = GObject.Property(type=str)
 8
 9    def __init__(self, name):
10        super().__init__()
11
12        self.name = name
13
14
15class PersonsModel(GObject.GObject, Gio.ListModel):
16    __gtype_name__ = 'PersonsModel'
17
18    def __init__(self):
19        super().__init__()
20
21        # Private list to store the persons
22        self._persons = []
23
24    '''
25    Interface Methods
26    '''
27
28    def do_get_item(self, position):
29        return self._persons[position]
30
31    def do_get_item_type(self):
32        return Person
33
34    def do_get_n_items(self):
35        return len(self._persons)
36
37    '''
38    Our Helper Methods
39    '''
40
41    def add(self, person):
42        self._persons.append(person)
43
44        '''
45        We must call Gio.ListModel.items_changed() every time we change the list.
46
47        It's a helper to emit the "items-changed" signal, so consumer can know
48        that the list changed at some point. We pass the position of the change,
49        the number of removed items and the number of added items.
50        '''
51        self.items_changed(len(self._persons) - 1, 0, 1)
52
53    def remove(self, position):
54        del self._persons[position]
55        self.items_changed(position, 1, 0)
56
57    def get_index_by_name(self, name):
58        for i, person in enumerate(self._persons):
59            if person.name == name:
60                return i
61
62        return None