jhass / crystal-gobject

gobject-introspection for Crystal

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How can I use Glade templates?

n-rodriguez opened this issue · comments

Hi there!

I'd like to use Glade templates in my Gtk application but I'm stuck with Error: undefined method 'set_template_from_resource' for Gtk::Widget.class.

It seems that Gtk::Widget.class should implement set_template_from_resource or set_template https://lazka.github.io/pgi-docs/Gtk-3.0/classes/WidgetClass.html#Gtk.WidgetClass.set_template_from_resource to get it work.

To give you more context I'm rewriting a Ruby/Gtk3 application to Crystal/Gtk3 (https://github.com/jbox-web/ssh-tunnel) so I'm already using this technique and it works pretty well : https://github.com/jbox-web/ssh-tunnel/blob/master/lib/ssh-tunnel/ui/windows/application_window.rb

Hey!

First of all crystal-gobject rewrites set_foo to foo=, so you'd be looking for template= or template_from_resource= here.

Now we probably should map those Class stuff (I guess it's returned by g_object_info_get_class_struct) into class methods on the wrapper classes somehow. But I'm not sure how to get the particular instance inside those functions at runtime. It would be interesting to see a corresponding C example.

Hi @jhass! Thanks for your quick answer :)

First of all crystal-gobject rewrites set_foo to foo=, so you'd be looking for template= or template_from_resource= here.

good to know 👍

It would be interesting to see a corresponding C example.

There is some code examples here : https://developer.gnome.org/gtk3/stable/ch01s04.html

From Gtk3 doc : (important things are in bold)

To make use of this file in our application, we revisit our GtkApplicationWindow subclass, and call gtk_widget_class_set_template_from_resource() from the class init function to set the ui file as template for this class. We also add a call to gtk_widget_init_template() in the instance init function to instantiate the template for each instance of our class.

That's what you see in Ruby/Gtk3 implementation : https://github.com/jbox-web/ssh-tunnel/blob/master/lib/ssh-tunnel/ui/windows/application_window.rb#L11

Here the workflow in Ruby :

  1. Gtk3 (or something) calls Class.init
  2. Class.init sets the template by calling set_template
  3. set_template calls the C method (https://github.com/ruby-gnome/ruby-gnome/blob/dde8c4fdabeadc6d9c8e4ca345aace535853deb6/gtk3/lib/gtk3/widget.rb#L33)
  4. the object is instantiated with Class.new and initialize_post is called (https://github.com/ruby-gnome/ruby-gnome/blob/dde8c4fdabeadc6d9c8e4ca345aace535853deb6/gtk3/lib/gtk3/widget.rb#L148)
  5. initialize_post calls the C method init_template

Here some Crystal code : https://github.com/jbox-web/ssh-tunnel.cr

To run the app :

  • make ssh-tunnel
  • ./bin/ssh-tunnel

I tried your suggestion but it doesn't work so you will have an error on compilation :

In src/ssh-tunnel/ui/windows/application_window.cr:5:14

 5 | self.template_from_resource = "/com/jbox-web/ssh-tunnel/ui/application_window.glade"
          ^---------------------
Error: undefined method 'template_from_resource=' for SSHTunnel::UI::Windows::ApplicationWindow.class
make: *** [Makefile:18 : ssh-tunnel] Erreur 1

Just comment the line and it will work.

Sorry, I cannot promise I'll find time to look into this myself this year :)

The code that's generating the wrapper classes for objects is at https://github.com/jhass/crystal-gobject/tree/main/src/g_i_repository/info/object_info.cr

Hi there! Any news? 😃

Hey,
I embed glade templates in my application like that:

require "gobject/gtk"

template = {{ `cat #{__DIR__}/window.glade`.stringify }}

builder = Gtk::Builder.new_from_string template, template.bytesize
builder.connect_signals
@window = window = Gtk::Window.cast builder["window"]

That works pretty good, but it's not using GResources. You try to fetch the template from a resource, did you find a way to link your resource file into the executable? I would like to use icons through a GResource file, but found no way to link that into the executable.

Not directly related to the issue, but you must use template.bytesize instead of template.size, since due to UTF-8 encoding these are not always the same.

Not directly related to the issue, but you must use template.bytesize instead of template.size, since due to UTF-8 encoding these are not always the same.

Good catch, thanks! I changed it above for reference.

FYI: Almost 1.5 years later, in a different shard but it's finally possible to use glade template in Crystal-GTK 😃

hugopl/gtk4.cr@c93354e

sorry for the cross-repo post, but I'm very happy it worked and remembered this issue that basically made me knew this feature existed in GTK, otherwise I would still be using Gtk::Builder forever.