Signals

All this time, the button of our Welcome widget has been sitting there, useless. It’s now time to give it a purpose!

# Connecting a Signal to a Callback

Some GTK widgets emit signals in response to user interaction (and in general, GObjects emit signals in response to state change). Our button has a clicked signal, we’ll connect to it to run some code in our class.

In UI templates, we can use the signal tag, with the signal we want to connect to in the name attribute and the name of callback method of our class in handler.

So, in data/ui/WelcomeWidget.ui, to connect the clicked signal of the button to an onButtonClicked callback:

24<object class="GtkButton">
25	<!-- ... -->
26	<signal name="clicked" handler="onButtonClicked"/>
27</object>

Of course, we have to define the callback function in our WelcomeWidget class in src/WelcomeWidget.js:

18class extends Gtk.Widget {
19	/* ... */
20
21	onButtonClicked(_button) {
22		console.log('Button clicked!');
23	}
24}

The first parameter of a signal callback will always be the object emitting it. Some signals can have additional parameters, the documentation will mention them.

If you run the application and click the button, the console should display “Button clicked!”.

# Emitting Signals

This is nice, but not really useful, as the widget does nothing with the information. It would be great if the window changed to the Files view. The window, however, has no way of knowing that the button has been pressed.

One solution is for our widget to emit another signal that the window can connect to. (Another solution is to use actions, as we’ll see in the next chapter.)

We declare a simple signal in the Signal object of the configuration object of our class:

 4export const WelcomeWidget = GObject.registerClass({
 5	/* ... */
 6	Signals: {
 7		'button-clicked': {},
 8	},
 9}, class extends Gtk.Widget {/* ... */}
10});

Now, instead of logging a message, we emit this signal when we receive the clicked signal from the button:

35onButtonClicked(_button) {
36	this.emit('button-clicked');
37}

In data/ui/Window.ui, we connect to the button-clicked signal of our widget:

20<object class="FbrWelcomeWidget">
21	<!-- ... -->
22	<signal name="button-clicked" handler="onWelcomeButtonClicked"/>
23</object>

And in src/Window.js, we implement the onWelcomeButtonClicked callback function, that will change the view to the Files view:

 4export const Window = GObject.registerClass({
 5	/* ... */
 6	InternalChildren: ['viewStack'],
 7}, class extends Gtk.ApplicationWindow {
 8	/* ... */
 9
10	onWelcomeButtonClicked(_widget) {
11		this._viewStack.visibleChildName = 'files';
12	}
13});

That’s it, now when we run our application and click on the button, the window switches to the Files view!