Is it possible to pass data in signals made in XML?

66 views Asked by At

Sorry if the title is a bit awkward, I wasn't sure how to phrase it. Anyway...

When creating a signal in code it's possible to set it up so that additional information is sent to the handler when the signal is called:

GtkWidget *window;
GtkWidget *button;
g_signal_connect(button, "clicked", G_CALLBACK(example_pressed), window);

So when the button is pressed, it calls this function:

void example_pressed(GtkButton *self, GtkWindow *window){
    gtk_window_close(window);
}

All this function does is receive a GtkWindow and then close it, and it works perfectly fine if I only use code.

However, I wanted to replicate this behavior using GtkBuilder and a XML file. Creating the signal and pointing it to the appropiate function is easy enough, and explained in the API documentation for the GtkBuilder class:

<signal name="clicked" handler="example_pressed"/>

However, the documentation does not explain how I'd pass more data to the function. Here, it's not enough to create the signal, I also need to pass the window over to it. I've looked around and I couldn't find answers, or example projects that did this.

But the fact that, as mentioned, the documentation does not say anything about this, makes me wonder if it's possible at all. It wouldn't be a big problem if it turned out to be impossible, since I can use gtk_builder_get_object to retrieve the button from the XML file and create the signal in code just as before, but I'd like confirmation if it really is impossible or maybe there's something I'm not seeing.

1

There are 1 answers

0
Maf95 On BEST ANSWER

Thanks to Cambalache, I found the answer.

The documentation for the GtkBuilder class mentions an additional attribute that can be given to the <signal> tag, that is object. The docs describe it as "will bind the signal handler to the lifetime of the object referenced by the attribute", which is no help at all, but through Cambalache I discovered that it is indeed what I was looking for.

I changed the XML line from the OP to

<signal name="clicked" handler="example_pressed" swapped="no" object="window"/>

(where "window" is the id of the GtkApplicationWindow object in the same file) and was able to confirm that both the button and the window got sent to the example_pressed function in the OP. The window now closes when the button is pressed. Problem solved!

An additional note: When creating signals that send objects in XML like this, the default behavior (at least in GTK4) is to behave as if the swapped attribute is present and set to "yes". This causes the window to be sent to the signal handler as the first argument and the button as the second argument. This causes the example_pressed function, as written in the OP, to give an error and not perform any actions, as it would see I'm calling gtk_window_close on an object that is not a window. Hence why I added swapped="no" to the line, so that the objects are sent to the handler in the order matching the documentation for the "clicked" signal. Button first as self, window second as window.