MichiB
(Michael Buzgaru)
February 28, 2020, 4:09pm
1
I would like to know how do I find programmatically information about which Signals are available for an Object.
For example, if I need to find out which properties are available for an object and for its child (if is the case), I use the following two functions:
g_object_class_list_properties()
gtk_container_class_list_child_properties
Putting them in some functions I have the following (lets take a GRID as example):
void list_object_properties( GObject *object )
{
GParamSpec **list_prop;
guint n_prop;
guint count = 1;
list_prop = g_object_class_list_properties( G_OBJECT_GET_CLASS( object ), &n_prop );
for ( guint i = 0 ; i < n_prop ; i++ )
{
const gchar *const prop_name = g_param_spec_get_name( list_prop[i] );
g_print( "property[%u] = %s\n", count++, prop_name );
}
}
void list_child_properties ( GObject *object )
{
GParamSpec **list_prop;
guint n_prop = 0;
guint count = 1;
list_prop = gtk_container_class_list_child_properties( G_OBJECT_GET_CLASS( object ), &n_prop );
for ( guint i = 0 ; i < n_prop ; i++ )
{
const gchar *const prop_name = g_param_spec_get_name( list_prop[i] );
g_print( "property[%u] = %s\n", count++, prop_name );
}
}
And Outpus:
Object Properties
property[1] = orientation
property[2] = name
property[3] = parent
property[4] = width-request
property[5] = height-request
property[6] = visible
property[7] = sensitive
property[8] = app-paintable
property[9] = can-focus
property[10] = has-focus
property[11] = is-focus
property[12] = focus-on-click
property[13] = can-default
property[14] = has-default
property[15] = receives-default
property[16] = composite-child
property[17] = style
property[18] = events
property[19] = no-show-all
property[20] = has-tooltip
property[21] = tooltip-markup
property[22] = tooltip-text
property[23] = window
property[24] = opacity
property[25] = double-buffered
property[26] = halign
property[27] = valign
property[28] = margin-left
property[29] = margin-right
property[30] = margin-start
property[31] = margin-end
property[32] = margin-top
property[33] = margin-bottom
property[34] = margin
property[35] = hexpand
property[36] = vexpand
property[37] = hexpand-set
property[38] = vexpand-set
property[39] = expand
property[40] = scale-factor
property[41] = border-width
property[42] = resize-mode
property[43] = child
property[44] = row-spacing
property[45] = column-spacing
property[46] = row-homogeneous
property[47] = column-homogeneous
property[48] = baseline-row
Child Properties
property[1] = left-attach
property[2] = top-attach
property[3] = width
property[4] = height
How do I find out information about signals, which reports something like this:
Object Signals
Signal[1] = ??????
Signal[2] = ??????
Signal[3] = ??????
Signal[4] = ??????
Signal[5] = ??????
Child Signals
Signal[1] = ??????
Signal[2] = ??????
ebassi
(Emmanuele Bassi)
February 28, 2020, 4:16pm
2
You will need to call g_signal_list_ids()
to gather all the signal identifiers for a given GType, and then call g_signal_query()
for each identifier to gather the signal metadata .
MichiB
(Michael Buzgaru)
February 28, 2020, 4:27pm
3
Well I was close, but it is now what I was needing:
guint n_signals;
guint *signals = g_signal_list_ids( g_type_from_name( "GtkWidget" ), &n_signals );
for ( guint i = 0 ; i < n_signals ; i++ )
{
g_print( "Signal = %s\n", g_signal_name( signals[i] ) );
}
I will give a try, Thank you.
ebassi
(Emmanuele Bassi)
February 28, 2020, 4:29pm
4
Remember that this will ever only work for:
GTypes registered by GTK itself or
GTypes that have been instantiated
If a GType hasn’t been registered yet, you won’t be able to get the type from the type name.
MichiB
(Michael Buzgaru)
February 28, 2020, 4:32pm
5
Yes, and I notices once that I used:
g_type_from_name( "GtkGrid" )
Or:
g_type_from_name( gtk_widget_get_name( grid ) )
Both did not worked.
ntd
(Nicola Fontana)
February 28, 2020, 4:37pm
6
I suppose this is why g_type_ensure
has been exposed.
ebassi
(Emmanuele Bassi)
February 28, 2020, 4:38pm
7
Getting the type from GtkGrid
should always work after calling gtk_init()
because GTK registers all its types on initialization.
This line is non-sensical. The name of the widget could be any random string, and will fall back to the type name if one isn’t set.
In general, you can only ever use g_type_from_name()
when debugging and you already know what kind of types you have. You cannot rely on the type name for anything else—especially for introspection.
It seems you’re doing a lot of introspection work; why not use the introspection data provided by GTK itself, through gobject-introspection instead of reimplementing it from first principles (and probably badly)?
ebassi
(Emmanuele Bassi)
February 28, 2020, 4:39pm
8
Kind of. We have g_type_ensure()
because calling something like:
GType unused = some_class_get_type ();
or:
(void) some_class_get_type ();
will either produce a warning, or might be optimised away by the compiler.
MichiB
(Michael Buzgaru)
February 28, 2020, 4:52pm
9
I am doing something wrong in here, because the following does not work for grid:
guint n_signals;
guint *signals_id = g_signal_list_ids ( G_TYPE_FROM_INSTANCE ( grid ), &n_signals );
for ( guint i = 0 ; i < n_signals ; i++ )
{
GSignalQuery query;
g_signal_query( signals_id[i], &query );
g_print ( "Signal[%u] = %s\n",i , query.signal_name );
}
and for “window” it returns: (with G_TYPE_FROM_INSTANCE ( window ) )
Signal[0] = keys-changed
Signal[1] = set-focus
Signal[2] = activate-focus
Signal[3] = activate-default
Signal[4] = enable-debugging
So I cannot figure out why is now working on grid.
ebassi
(Emmanuele Bassi)
February 28, 2020, 4:55pm
10
GtkGrid
doesn’t have any signal by itself, so of course you won’t get any signal from its type.
If you want to get all the signals registered by a type, including its ancestor types, you’ll have to traverse the type hierarchy.
MichiB
(Michael Buzgaru)
February 28, 2020, 5:04pm
11
Yes you are right, my bad explanation.
Lets put it in a different way.
The GtkGrid si derived from GtkContainer, which in terms means that it inherits its properties and signals (of GtkContainer).
What I was trying to achieve was to get those Signals as well (available for GtkContainer and so on… ).
The GtkContainer has 4 Signals ( “add, check-resize, remove, set-focus-child”) and I thought that I can get them through the GtkGrid object.
In other words GtkGrid has only 5 Properties, but avaible (because it inherits…) are 48 ( from its ancestor types) available.
I hope you understand what I am trying here to achieve.
Here is a demo of the “add” signal:
#include <gtk/gtk.h>
void child_added ( GtkGrid *grid );
void child_added ( GtkGrid *grid )
{
g_return_if_fail ( GTK_IS_GRID ( grid ) );
g_print ( "child added\n" );
}
int main ( void )
{
GtkWidget *window;
GtkWidget *grid;
GtkWidget *button;
/// ***
gtk_init ( NULL, NULL );
/// *** Create a Window
window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
/// *** Create a Grid
grid = gtk_grid_new();
gtk_container_add ( GTK_CONTAINER ( window ), grid );
/// *** Catch the ADD signal from GtkContainer
g_signal_connect_swapped ( grid, "add", G_CALLBACK ( child_added ), grid );
/// *** Create and Add the button Child
button = gtk_button_new_with_label( "click" );
gtk_container_add ( GTK_CONTAINER( grid ), button );
gtk_widget_show_all ( window );
gtk_main ();
}
If you want to get all the signals registered by a type, including its ancestor types, you’ll have to traverse the type hierarchy
This was my Question, how do I do that? How do I find out all available Signals (including its ancestor types) which one can use them on an Object?
chrisaw
(Chris Williams)
February 28, 2020, 6:00pm
12
1 Like
ebassi
(Emmanuele Bassi)
February 28, 2020, 6:03pm
13
Start from the GType you have, get the list of signals and query them.
Get the parent GType, using g_type_parent()
, get the list of signals, and query them.
Continue upwards on the type hierarchy until you hit G_TYPE_OBJECT
.
1 Like
system
(system)
Closed
March 13, 2020, 6:03pm
14
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.