Search code examples
pythongtkpygobjectgobject

How to inherit from GObject class?


I want to write application with a tree view widget in witch I will store my objects of class 'Item'.

I know that in order to do so my 'Item' class must inherit from GObject class. Unfortunately something is wrong and I don't see text of items on my tree. I only get this warning:

Warning: unable to set property 'text' of type 'gchararray' from value of type '__main__+Item'

What I will have to do to fix this?

This sample program is demonstrates problem and it's ready to test fixes:

#!/usr/bin/env python3

from gi.repository import Gtk
from gi.repository import GObject


class Item(GObject.GObject):
    text = GObject.property(type=str, default='item', flags=GObject.PARAM_READWRITE)

    def __init__(self, title):
        GObject.GObject.__init__(self)
        self.__title = title

    def __str__(self):
        return self.__title

GObject.type_register(Item)


class MainWindow(Gtk.Window):
    def __init__(self):
        super().__init__(Gtk.WindowType.TOPLEVEL)
        self.connect('destroy', self.on_destroy)
        tree_model = Gtk.TreeStore(Item.__gtype__)
        # tree_model = Gtk.TreeStore(str)
        text_renderer = Gtk.CellRendererText()
        text_column = Gtk.TreeViewColumn(None, text_renderer)
        text_column.add_attribute(text_renderer, 'text', 0)
        tree_view = Gtk.TreeView(tree_model)
        tree_view.append_column(text_column)
        self.add(tree_view)
        self.show_all()
        tree_model.append(None, (Item('test'),))
        # tree_model.append(None, ('It works!',))

    def on_destroy(self, e):
        Gtk.main_quit()


if __name__ == '__main__':
    MainWindow()
    Gtk.main()

Solution

  • GtkCellRendererText requires string (gchararray) data for its text property, and it is receiving custom GObject values. The __str__ function works on the Python level and is never invoked by GObject.

    Fortunately, what you want to achieve doesn't require subclassing GObject. You need to do the following:

    • Specify the tree store column as GObject.TYPE_PYOBJECT. This will allow you to append your instances to the tree store without inheritance from GObject or special properties.

    • Use set_cell_data_func on the tree view columns to extract textual data from your instances stored in the model.

    See this answer for a working example of this technique.