GTK4 + Python Gtk.template not found my .ui file

Hi there, i’m working on ZeroTier-GTK app but I have a problem removing the flatpak from the repo.

(Why removing flatpak?)
It’s quite complicate to develop a program that needs to read some library token that it’s not user readable.

(Problems with code)
One of the windows.py

from gi.repository import Adw
from gi.repository import Gtk
from zerotierlib import *


@Gtk.Template(resource_path='window.ui')
class ZerotierGtkWindow(Adw.ApplicationWindow):
    __gtype_name__ = 'ZerotierGtkWindow'

    my_infobar = Gtk.Template.Child()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.ztlib = ZeroTierNetwork()

    def on_check_lib(self):
        if self.ztlib.zt_status():
            self.my_infobar.set_visible(False)
            return True
        else:
            self.my_infobar.set_visible(True)
            return False

    def on_service_set(self, status):
        status = self.ztlib.service(status)
        self.on_check_lib()
        return status

    def get_service_status(self):
        return self.ztlib.zt_enable_status()

Throws back this traceback

Traceback (most recent call last):
  File "/home/renkuramori/PycharmProjects/zerotierGTK/venv/lib64/python3.11/site-packages/gi/_gtktemplate.py", line 227, in validate_resource_path
    Gio.resources_get_info(path, Gio.ResourceLookupFlags.NONE)
gi.repository.GLib.GError: g-resource-error-quark: El recurso en «/home/renkuramori/PycharmProjects/zerotierGTK/window.ui» no existe (0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/renkuramori/PycharmProjects/zerotierGTK/main.py", line 29, in <module>
    from window import ZerotierGtkWindow
  File "/home/renkuramori/PycharmProjects/zerotierGTK/window.py", line 25, in <module>
    @Gtk.Template(resource_path='/home/renkuramori/PycharmProjects/zerotierGTK/window.ui')
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/renkuramori/PycharmProjects/zerotierGTK/venv/lib64/python3.11/site-packages/gi/_gtktemplate.py", line 294, in __call__
    validate_resource_path(self.resource_path)
  File "/home/renkuramori/PycharmProjects/zerotierGTK/venv/lib64/python3.11/site-packages/gi/_gtktemplate.py", line 232, in validate_resource_path
    Gio.resources_lookup_data(path, Gio.ResourceLookupFlags.NONE)
gi.repository.GLib.GError: g-resource-error-quark: 
The resource at "/home/renkuramori/PycharmProjects/zerotierGTK/window.ui" does not exist (0)

The file window.ui it’s on the same directory as the file window.py, so I don’t get why this doesn’t work.

The window.ui file

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk" version="4.0"/>
  <requires lib="Adw" version="1.0"/>
  <template class="ZerotierGtkWindow" parent="AdwApplicationWindow">
    <property name="default-width">800</property>
    <property name="default-height">600</property>
    <property name="title">ZeroTier</property>
    <child>
      <object class="GtkBox">
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkHeaderBar" id="header_bar">
            <child type="end">
              <object class="GtkMenuButton">
                <property name="icon-name">open-menu-symbolic</property>
                <property name="menu-model">primary_menu</property>
              </object>
            </child>
            <child>
              <object class="GtkButton" id="addnetwork">
                <property name="icon-name">list-add</property>
                <property name="focusable">true</property>
              </object>
            </child>
            <child>
              <object class="GtkButton" id="refresh">
                <property name="icon-name">view-refresh</property>
                <property name="focusable">true</property>
              </object>
            </child>
          </object>
        </child>
        <child>
          <object class="GtkInfoBar" id="my_infobar">
            <property name="visible">True</property>
            <property name="message-type">info</property>
            <child>
              <object class="GtkLabel" id="my_label_infobar">
                <property name="visible">True</property>
                <property name="label">Warning: You need to start zerotier service,you could start at Settings/ZeroTier One, otherwise, this app will not work.</property>
              </object>
            </child>
          </object>
        </child>
        <child>
          <object class="GtkScrolledWindow">
            <property name="hexpand">TRUE</property>
            <property name="vexpand">TRUE</property>
            <child>
          <object class="AdwPreferencesGroup" id="action_row">
            <property name="title">Networks: </property>
            <property name="margin-bottom">15</property>
            <property name="margin-end">35</property>
            <property name="margin-start">35</property>
            <property name="margin-top">25</property>
            <style>
              <class name="boxed-list"></class>
            </style>
            <child>
              <object class="AdwActionRow">
                <property name="icon-name">dialog-error</property>
                <property name="title">Sleepy_Heatherrington</property>
                <property name="subtitle">NetID: a9ld6679agpgc4te Status: Disconnected</property>
                <property name="activatable">True</property>
                <signal name="activate" handler="on_copy_item_activate"/>
                <child>
                  <object class="GtkSwitch">
                    <property name="halign">end</property>
                    <property name="valign">center</property>
                  </object>
                </child>
                <child>
                  <object class="GtkButton">
                    <property name="icon-name">preferences-system</property>
                    <property name="valign">center</property>
                  </object>
                </child>
              </object>
            </child>
            <child>
              <object class="AdwActionRow">
                <property name="icon-name">emblem-default</property>
                <property name="title">Sleepy_Heatherrington</property>
                <property name="subtitle">NetID: a9ld6679agpgc4te Status:OK</property>
                <property name="activatable">True</property>
                <child>
                  <object class="GtkSwitch">
                    <property name="halign">end</property>
                    <property name="valign">center</property>
                  </object>
                </child>
                <child>
                  <object class="GtkButton">
                    <property name="icon-name">preferences-system</property>
                    <property name="valign">center</property>
                  </object>
                </child>
              </object>
            </child>
            <child>
              <object class="AdwActionRow">
                <property name="icon-name">emblem-important</property>
                <property name="title">Sleepy_Heatherrington</property>
                <property name="subtitle">NetID: a9ld6679agpgc4te Status: ACCESS_DENIED</property>
                <property name="activatable">True</property>
                <child>
                  <object class="GtkSwitch">
                    <property name="halign">end</property>
                    <property name="valign">center</property>
                  </object>
                </child>
                <child>
                  <object class="GtkButton">
                    <property name="icon-name">preferences-system</property>
                    <property name="valign">center</property>
                  </object>
                </child>
                </object>
              </child>
              </object>
            </child>
          </object>
        </child>
      </object>
    </child>
  </template>
  <menu id="primary_menu">
    <section>
      <item>
        <attribute name="label" translatable="yes">_Preferences</attribute>
        <attribute name="action">app.preferences</attribute>
      </item>
      <item>
        <attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
        <attribute name="action">win.show-help-overlay</attribute>
      </item>
      <item>
        <attribute name="label" translatable="yes">_About Zerotier-gtk</attribute>
        <attribute name="action">app.about</attribute>
      </item>
    </section>
  </menu>
</interface>

Hi,

You probably want to use “filename” instead of “resource_path” here:

@Gtk.Template(filename='window.ui')

Use “resource_path” when you want to bundle a set of data files in an application through GResource, more info here:

I tried that, but it gives me the same error

the path of the window.ui file, both in import and in gresource, must be relative to the location of the gresource file, and not relative to the location of the window.py file.

If your gresource file is not in the same directory as window.py (it probably isn’t), this import is incorrect.

In other words, you should be using absolute paths.

from pathlib import Path
directory = Path(__file__).absolute().parent

# OR

from importlib import resources
directory = resources('retrotierGTK')

# And Then
@Gtk.Template(filename=directory / 'window.ui')
class ZerotierGtkWindow(Gtk.ApplicationWindow):
...

What is a gresourcefile??, it’s the first time I know about it.
And thanks @mazharhussain I’ll give it a try.

It’s a GLib concept: a bundle of files, each accessible through a “resource path”, embedded into a single resource file. It’s the second link from @gwillems: Gio.Resource

GTK-based applications typically use resource files to bundle extra assets, like UI definition files, CSS, and icons. Both GTK and libadwaita can automatically look inside resource data loaded into your application:

1 Like

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