Comments (6)
Thanks for the reminder.
It is very easy to implement, actually Gtk.Builder:connect_signals_full() is introspectable and can be used as is. The point is of course whether to build some nice facade over it. One way would be something like
Gtk.Builder:connect_to(target)
where target
is Lua table containing methods named as handlers in builder XML. This would be also very easy to implement in pure Lua (in override/Gtk.lua), but I'm not entirely convinced if this is the right interface to use.
Btw, 'after' is fine and can be easily supported, 'swapped' makes no sense for lgi and should be ignored. I'm not sure how to approach 'object' (don't even know offhand what it means :-)
If you have any comments, suggestions etc. please don't hesitate to share it here.
from lgi.
The "object" attribute is usefull to pass an object as "user_data" parameter to the signal handler. This is edited using the Glade user interface.
When you call gtk_connect_signals_full, the third parameter must be another user_data. Was a headache for me to discover the difference between the two user_data's.
The prototype for the connector function is:
void (*GtkBuilderConnectFunc) (GtkBuilder *builder,
GObject *object,
const gchar *signal_name,
const gchar *handler_name,
GObject *connect_object, <------ THIS IS THE RIGHT ONE, FROM GLADE
GConnectFlags flags,
gpointer user_data); <-------- THIS IS THE "ANOTHER", NOT REALLY USEFULL
;-) Happy hacking!
from lgi.
I'm still a bit skeptical about a real value of all this; the whole GtkBuilder is nice idea at the beginning, but
- glade sucks, always crashes for me and it was a pain for me to have some real work done in it,
- manual builder XML editing is just a pain, it is much easier to use Lua-native table-based UI description (see lgi Gtk manual and samples how to do it).
- autoconnection of signals might be useful for C projects (maybe), but IMHO it brings no advantage to Lua-based development
That said, I've worked on adding this feature. I've modeled it after PyGObject's Gtk.Builder.connect_signals(). Before I submit it, add tests for it and write docs, I'd like you to overview (and possibly also try) it whether it suits your needs (as I explained above, I cannot evaluate it because it is useless for my workflow). The sample including implementation of the feature is here:
t1.lua
local lgi = require 'lgi'
local Gtk = lgi.Gtk
--- ### Once finalized will be moved to lgi.override.Gtk
local log = lgi.log.domain('lgi.Gtk')
function Gtk.Builder._method:connect_signals(obj)
local unconnected
self:connect_signals_full(
function(builder, object, signal, handler, connect_object, flags)
signal = 'on_' .. signal:gsub('%-', '_')
local target = obj[handler]
if not target then
unconnected = unconnected or {}
unconnected[#unconnected + 1] = handler
log.warning("%s: failed to connect to `%s' handler",
signal, handler)
return
end
local f
if connect_object then
f = function(_, ...) return target(connect_object, ...) end
else
f = target
end
object[signal]:connect(f, nil, flags.AFTER)
end)
return unconnected
end
--- ###
local builder = Gtk.Builder()
assert(builder:add_from_file('t1.ui'))
builder:connect_signals {
clicked1_cb = function(...) print('clicked1_cb', ...) end,
clicked2_cb = function(...) print('clicked2_cb', ...) end,
keypress = function(...) print('keypress', ...) end,
}
local w = builder:get_object('window1')
w.on_destroy = Gtk.main_quit
w:show_all()
Gtk.main()
t1.ui
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">label</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">button</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="key-press-event" handler="keypress" swapped="no"/>
<signal name="clicked" handler="clicked1_cb" object="label1" swapped="yes"/>
<signal name="clicked" handler="clicked2_cb" after="yes" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
from lgi.
Just for completness, I attached functionally-identical example written using Lua-table based UI description.
local lgi = require 'lgi'
local Gtk = lgi.Gtk
local w = Gtk.Window {
Gtk.Box {
orientation = 'VERTICAL',
Gtk.Label {
id = 'label',
label = "label",
},
Gtk.Button {
id = 'button',
label = "button",
},
},
}
function w.child.button:on_clicked(...) print('clicked1_cb', w.child.label, ...) end
function w.child.button:on_clicked(...) print('clicked2_cb', self, ...) end
function w.child.button:on_key_press_event(...) print('keypress', ...) end
w.on_destroy = Gtk.main_quit
w:show_all()
Gtk.main()
from lgi.
"connect_object" should replace "object" only if the SWAPPED flag is on.
In this case, "object" should be passed as second argument
Otherwise, "object" should stay as the original object, and "connect_object" should be passed as second argument.
For a behavior like C code, please rewrite the following lines:
if connect_object then
f = function(_, ...) return target(connect_object, ...) end
into:
if connect_object and flags.SWAPPED then
f = function(_, _, ...) return target(connect_object, object, ...) end
elseif connect_object and not flags.SWAPPED then
f = function(_, _, ...) return target(object, connect_object, ...) end
Note: I'm not sure if duplicate underscores is right
from lgi.
I took some time to think about this and decided that I will go with my previous version. all 'swapped' signal business is not supported by lgi, so it would not make much sense to add support for it here. Moreover, the requested effect can be very easily achieved using closures and upvalues, or by rewriting connect_signals method with your custom one (using connect_signals_full
as a base functionality). IMO, all the 'swapped' complexity is poor-man's workaround for C lacking these language features.
Committed to master and closing the issue. Thanks a lot for your input and sorry that I decided to resolve it differently than you recommended.
from lgi.
Related Issues (20)
- Has this been abandoned? For me on v5.3 it doesn't work HOT 6
- Ability to keep out parameter as NULL HOT 8
- Does lgi support Gtk4? HOT 24
- How to emit signals on an object HOT 26
- GVariant dictionnaries returned from GDBus method calls and signals are empty HOT 4
- Errors in callbacks don't terminate the loop HOT 4
- Segmentation fault in Gio.File.copy_async HOT 7
- API reference such as https://lazka.github.io/pgi-docs/? HOT 2
- Misaligned memory accesses in marshal_2c_int and marshal_2lua_int HOT 2
- Building in Windows with meson is looking for luajit-5.1.lib HOT 3
- GtkContainer.child SIGSEGVs on access HOT 5
- How to connect signal on derived class of GstBin? HOT 5
- Segmentation fault when using netwok manager HOT 1
- Segmentation fault when using upower and playerctl interfaces HOT 1
- push to luarocks HOT 14
- Fails to install on fedora 36, Lua 5.4-1 HOT 5
- install error HOT 3
- _resolve can cause luajit to segmentation fault
- Cannot import Glib HOT 1
- Makefile doesn't work on systems with multiple lua versions? HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lgi.