Spinner¶
The Gtk.Spinner
displays an icon-size spinning animation.
It is often used as an alternative to a Gtk.ProgressBar
for displaying indefinite activity, instead of actual progress.
To start the animation, use Gtk.Spinner.start()
,
to stop it use Gtk.Spinner.stop()
.
Example¶
![../../../_images/spinner.png](../../../_images/spinner.png)
1import gi
2
3gi.require_version('Gtk', '4.0')
4from gi.repository import Gtk
5
6
7class SpinnerAnimation(Gtk.ApplicationWindow):
8 def __init__(self, **kargs):
9 super().__init__(**kargs, title='Spinner Demo')
10
11 button = Gtk.ToggleButton(label='Start Spinning')
12 button.connect('toggled', self.on_button_toggled)
13 button.props.active = False
14
15 self.spinner = Gtk.Spinner()
16
17 box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, homogeneous=True)
18 box.append(button)
19 box.append(self.spinner)
20 self.set_child(box)
21
22 def on_button_toggled(self, button):
23 if button.props.active:
24 self.spinner.start()
25 button.set_label('Stop Spinning')
26
27 else:
28 self.spinner.stop()
29 button.set_label('Start Spinning')
30
31
32def on_activate(app):
33 win = SpinnerAnimation(application=app)
34 win.present()
35
36
37app = Gtk.Application(application_id='com.example.App')
38app.connect('activate', on_activate)
39
40app.run(None)
Extended example¶
An extended example that uses a timeout function to start and stop
the spinning animation.
The on_timeout()
function is called at regular intervals
until it returns False
, at which point the timeout is automatically
destroyed and the function will not be called again.
Example¶
![../../../_images/spinner_ext.png](../../../_images/spinner_ext.png)
1import gi
2
3gi.require_version('Gtk', '4.0')
4from gi.repository import Gtk, GLib
5
6
7class SpinnerAnimation(Gtk.ApplicationWindow):
8 def __init__(self, **kargs):
9 super().__init__(**kargs, title='Spinner Demo')
10
11 main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
12 self.set_child(main_box)
13
14 self.spinner = Gtk.Spinner()
15 main_box.append(self.spinner)
16
17 self.label = Gtk.Label()
18 main_box.append(self.label)
19
20 self.entry = Gtk.Entry()
21 self.entry.props.text = '10'
22 main_box.append(self.entry)
23
24 self.button_start = Gtk.Button(label='Start timer')
25 self.button_start.connect('clicked', self.on_button_start_clicked)
26 main_box.append(self.button_start)
27
28 self.button_stop = Gtk.Button(label='Stop timer')
29 self.button_stop.props.sensitive = False
30 self.button_stop.connect('clicked', self.on_button_stop_clicked)
31 main_box.append(self.button_stop)
32
33 self.timeout_id = None
34 self.connect('unrealize', self.on_window_destroy)
35
36 def on_button_start_clicked(self, _widget):
37 '''Handles 'clicked' event of button_start.'''
38 self.start_timer()
39
40 def on_button_stop_clicked(self, _widget):
41 '''Handles 'clicked' event of button_stop.'''
42 self.stop_timer('Stopped from button')
43
44 def on_window_destroy(self, _widget):
45 '''Handles unrealize event of main window.'''
46 # Ensure the timeout function is stopped
47 if self.timeout_id:
48 GLib.source_remove(self.timeout_id)
49 self.timeout_id = None
50
51 def on_timeout(self):
52 '''A timeout function.
53 Return True to stop it.
54 This is not a precise timer since next timeout
55 is recalculated based on the current time.
56 '''
57 self.counter -= 1
58 if self.counter <= 0:
59 self.stop_timer('Reached time out')
60 return False
61 self.label.props.label = f'Remaining: {str(int(self.counter / 4))}'
62 return True
63
64 def start_timer(self):
65 '''Start the timer.'''
66 self.button_start.props.sensitive = False
67 self.button_stop.props.sensitive = True
68 # time out will check every 250 milliseconds (1/4 of a second)
69 self.counter = 4 * int(self.entry.props.text)
70 self.label.props.label = f'Remaining: {str(int(self.counter / 4))}'
71 self.spinner.start()
72 self.timeout_id = GLib.timeout_add(250, self.on_timeout)
73
74 def stop_timer(self, label_text):
75 '''Stop the timer.'''
76 if self.timeout_id:
77 GLib.source_remove(self.timeout_id)
78 self.timeout_id = None
79 self.spinner.stop()
80 self.button_start.props.sensitive = True
81 self.button_stop.props.sensitive = False
82 self.label.props.label = label_text
83
84
85def on_activate(app):
86 win = SpinnerAnimation(application=app)
87 win.present()
88
89
90app = Gtk.Application(application_id='com.example.App')
91app.connect('activate', on_activate)
92
93app.run(None)