Using GTK template and builder to get object

I’m trying to create a GTK app with Python using libAdwaita where I can to draw a figure with Cairo. To do this I have to create a drawing area. When I try to get the object for the drawing area it returns None.

My code looks like this:

@Gtk.Template(resource_path='/com/domain/finset/window.ui')
class FinsetWindow(Adw.Window):
    __gtype_name__ = 'FinsetWindow'


    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.builder = Gtk.Builder()
        self.graphDrawingArea = self.builder.get_object('graphDrawingArea')
        
        pprint(vars(self))

And my .ui file starts

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk" version="4.0"/>
  <requires lib="libadwaita" version="1.0"/>
  <template class="FinsetWindow" parent="AdwWindow">
    <property name="default-width">640</property>
    <property name="default-height">480</property>

And further down I have a child for the drawing area where I later will draw the figure:

                <child>
                  <object class="GtkStackPage">
                    <property name="title" translatable="yes">Graph</property>
                    <property name="child">
                      <object class="GtkDrawingArea" id="graphDrawingArea">
                      </object>
                    </property>
                  </object>
                </child>

When building the application it renders fine

image

But self.builder.get_object('graphDrawingArea') returns None.

{'__gtktemplate_handlers__': set(),
 'builder': <Gtk.Builder object at 0x7fb3031fbf80 (GtkBuilder at 0x560a719e6f20)>,
 'graphDrawingArea': None,
 'init_template': <function init_template.<locals>.<lambda> at 0x7fb304296b80>}

What am I doing wrong when I try to get the object graphDrawingArea?

You’re not parsing anything and you’re trying to extract a widget out of nothing—because this is not how you deal with templates.

If you want to access a template child widget, you need to use the Gtk.Template.Child() constructor in the class itself:

@Gtk.Template(resource_path='/com/domain/finset/window.ui')
class FinsetWindow(Adw.Window):
    __gtype_name__ = 'FinsetWindow'

    graphDrawingArea = Gtk.Template.Child()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        # Now you can use self.graphDrawingArea
        self.graphDrawingArea.set_content_width(100)
        self.graphDrawingArea.set_content_height(100)
        self.graphDrawingArea.set_draw_func(self._on_draw)

    def _on_draw(self, area, cr, width, height)
        pass

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