12. Spinner

The Gtk.Spinner displays an icon-size spinning animation. It is often used as an alternative to a GtkProgressBar for displaying indefinite activity, instead of actual progress.

To start the animation, use Gtk.Spinner.start(), to stop it use Gtk.Spinner.stop().

12.1. Beispiel

_images/spinner_example.png
 1import gi
 2
 3gi.require_version("Gtk", "3.0")
 4from gi.repository import Gtk
 5
 6
 7class SpinnerAnimation(Gtk.Window):
 8    def __init__(self):
 9
10        Gtk.Window.__init__(self, title="Spinner")
11        self.set_border_width(3)
12        self.connect("destroy", Gtk.main_quit)
13
14        self.button = Gtk.ToggleButton(label="Start Spinning")
15        self.button.connect("toggled", self.on_button_toggled)
16        self.button.set_active(False)
17
18        self.spinner = Gtk.Spinner()
19
20        self.grid = Gtk.Grid()
21        self.grid.add(self.button)
22        self.grid.attach_next_to(
23            self.spinner, self.button, Gtk.PositionType.BOTTOM, 1, 2
24        )
25        self.grid.set_row_homogeneous(True)
26
27        self.add(self.grid)
28        self.show_all()
29
30    def on_button_toggled(self, button):
31
32        if button.get_active():
33            self.spinner.start()
34            self.button.set_label("Stop Spinning")
35
36        else:
37            self.spinner.stop()
38            self.button.set_label("Start Spinning")
39
40
41myspinner = SpinnerAnimation()
42
43Gtk.main()

12.2. Erweitertes Beispiel

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.

12.2.1. Beispiel

_images/spinner_ext_example.png
 1import gi
 2
 3gi.require_version("Gtk", "3.0")
 4from gi.repository import Gtk, GLib
 5
 6
 7class SpinnerWindow(Gtk.Window):
 8    def __init__(self, *args, **kwargs):
 9        Gtk.Window.__init__(self, title="Spinner Demo")
10        self.set_border_width(10)
11
12        mainBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
13        self.add(mainBox)
14
15        self.spinner = Gtk.Spinner()
16        mainBox.pack_start(self.spinner, True, True, 0)
17
18        self.label = Gtk.Label()
19        mainBox.pack_start(self.label, True, True, 0)
20
21        self.entry = Gtk.Entry()
22        self.entry.set_text("10")
23        mainBox.pack_start(self.entry, True, True, 0)
24
25        self.buttonStart = Gtk.Button(label="Start timer")
26        self.buttonStart.connect("clicked", self.on_buttonStart_clicked)
27        mainBox.pack_start(self.buttonStart, True, True, 0)
28
29        self.buttonStop = Gtk.Button(label="Stop timer")
30        self.buttonStop.set_sensitive(False)
31        self.buttonStop.connect("clicked", self.on_buttonStop_clicked)
32        mainBox.pack_start(self.buttonStop, True, True, 0)
33
34        self.timeout_id = None
35        self.connect("destroy", self.on_SpinnerWindow_destroy)
36
37    def on_buttonStart_clicked(self, widget, *args):
38        """ Handles "clicked" event of buttonStart. """
39        self.start_timer()
40
41    def on_buttonStop_clicked(self, widget, *args):
42        """ Handles "clicked" event of buttonStop. """
43        self.stop_timer("Stopped from button")
44
45    def on_SpinnerWindow_destroy(self, widget, *args):
46        """ Handles destroy event of main window. """
47        # ensure the timeout function is stopped
48        if self.timeout_id:
49            GLib.source_remove(self.timeout_id)
50            self.timeout_id = None
51        Gtk.main_quit()
52
53    def on_timeout(self, *args, **kwargs):
54        """ A timeout function.
55
56        Return True to stop it.
57        This is not a precise timer since next timeout
58        is recalculated based on the current time."""
59        self.counter -= 1
60        if self.counter <= 0:
61            self.stop_timer("Reached time out")
62            return False
63        self.label.set_label("Remaining: " + str(int(self.counter / 4)))
64        return True
65
66    def start_timer(self):
67        """ Start the timer. """
68        self.buttonStart.set_sensitive(False)
69        self.buttonStop.set_sensitive(True)
70        # time out will check every 250 miliseconds (1/4 of a second)
71        self.counter = 4 * int(self.entry.get_text())
72        self.label.set_label("Remaining: " + str(int(self.counter / 4)))
73        self.spinner.start()
74        self.timeout_id = GLib.timeout_add(250, self.on_timeout, None)
75
76    def stop_timer(self, alabeltext):
77        """ Stop the timer. """
78        if self.timeout_id:
79            GLib.source_remove(self.timeout_id)
80            self.timeout_id = None
81        self.spinner.stop()
82        self.buttonStart.set_sensitive(True)
83        self.buttonStop.set_sensitive(False)
84        self.label.set_label(alabeltext)
85
86
87win = SpinnerWindow()
88win.show_all()
89Gtk.main()