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!