crystal-gobject
crystal-gobject copied to clipboard
How can I use Glade templates?
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
tofoo=
, so you'd be looking fortemplate=
ortemplate_from_resource=
here.
good to know :+1:
It would be interesting to see a corresponding C example.
There is some code examples here : https://developer.gnome.org/gtk3/stable/ch01s04.html
Ruby implementation : https://github.com/ruby-gnome/ruby-gnome/blob/dde8c4fdabeadc6d9c8e4ca345aace535853deb6/gtk3/lib/gtk3/widget.rb
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 :
- Gtk3 (or something) calls
Class.init
-
Class.init
sets the template by callingset_template
-
set_template
calls the C method (https://github.com/ruby-gnome/ruby-gnome/blob/dde8c4fdabeadc6d9c8e4ca345aace535853deb6/gtk3/lib/gtk3/widget.rb#L33) - the object is instantiated with
Class.new
andinitialize_post
is called (https://github.com/ruby-gnome/ruby-gnome/blob/dde8c4fdabeadc6d9c8e4ca345aace535853deb6/gtk3/lib/gtk3/widget.rb#L148) -
initialize_post
calls the C methodinit_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.
Does this help https://github.com/ruby-gnome/ruby-gnome/blob/dde8c4fdabeadc6d9c8e4ca345aace535853deb6/gtk3/ext/gtk3/rb-gtk3.c#L577 ? Below you have the call to initialize_post
.
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
In Rust : https://github.com/gtk-rs/gtk-rs/blob/8a4c2d25e2cd40a6399e919908cde97ea0e93c1f/glib/src/subclass/mod.rs#L101
Gir-FFI :
- https://github.com/mvz/gir_ffi/blob/master/lib/ffi-gobject_introspection/i_object_info.rb
- https://github.com/mvz/gir_ffi/blob/master/lib/ffi-gobject_introspection/i_object_info.rb#L118
Hi there! Any news? :smiley:
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 oftemplate.size
, since due to UTF-8 encoding these are not always the same.
Good catch, thanks! I changed it above for reference.
It would be interesting to see a corresponding C example.
https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-22/examples/application2/exampleappwin.c
FYI: Almost 1.5 years later, in a different shard but it's finally possible to use glade template in Crystal-GTK :smiley:
https://github.com/hugopl/gtk4.cr/commit/c93354e5c181890cca686d258b180fcd63bb88c4
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.
@hugopl Thank you! It works! https://github.com/jbox-web/ssh-tunnel.cr