0

It is not clear for me how to use Gtk.SpinnerCellRenderer in a Gtk.TreeView with a Gtk.ListStore as model.

In this example the spinner is shown but it is inactive. It doesn't spin.

#!/usr/bin/env python3
import random
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

class TreeView(Gtk.TreeView):
    def __init__(self):
        # model
        self.model = Gtk.ListStore.new([bool, int])
        for i in range(5):
            self.model.append([random.choice([True, True, False]), i])

        # view
        Gtk.TreeView.__init__(self, self.model)

        # column bool (as spinner)
        self.spinner_renderer = Gtk.CellRendererSpinner.new()
        col_bool = Gtk.TreeViewColumn('bool',
                                      self.spinner_renderer,
                                      active=0)
        self.append_column(col_bool)

        # column int
        col_int = Gtk.TreeViewColumn('int',
                                     Gtk.CellRendererText(),
                                     text=1)
        self.append_column(col_int)


class Window(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title='Mein Gtk-Fenster')
        self.set_default_size(100, 120)

        self.view = TreeView()
        self.add(self.view)

        self.connect('destroy', Gtk.main_quit)
        self.show_all()

if __name__ == '__main__':
    win = Window()
    Gtk.main()
buhtz
  • 10,774
  • 18
  • 76
  • 149
  • 1
    It would be nice if you can make your program as simple as possible. 1, five rows aren't necessary. 2, Use a single class. Anyway, I have a minimum working example, https://gist.github.com/mywtfmp3/1d50c8f722b0f2729c7adaf61e06dc06. You need to increase "pulse" value of cellrendererspinner, and do increment repeatedly with `GObject.timeout` function. – MaxPlankton May 10 '18 at 07:21
  • I thought it is a MWE. Please give me an example of a PyGObject based MWE. Maybe you can edit my question. I don't see how to make this code more simple and more readable. – buhtz May 10 '18 at 07:37
  • Please add your link as an answer. btw: I think it is unworthy for a GUI lib like Gtk to force the user to spin such a widget by her/himself! – buhtz May 10 '18 at 07:40
  • 1
    I think it's awkward the default behavior of a spinner is to not spin. But who knows. – MaxPlankton May 10 '18 at 08:08

2 Answers2

1
#!/usr/bin/env python3
import random
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GObject

class TreeView(Gtk.TreeView):
    def __init__(self):
        # model
        self.model = Gtk.ListStore.new([bool, int])
        for i in range(5):
            self.model.append([random.choice([True, True, False]), i])

        # view
        Gtk.TreeView.__init__(self, self.model)

        # column bool (as spinner)
        self.spinner_renderer = Gtk.CellRendererSpinner()
        col_bool = Gtk.TreeViewColumn('bool', self.spinner_renderer, active=0)
        self.append_column(col_bool)

        # column int
        col_int = Gtk.TreeViewColumn('int', Gtk.CellRendererText(), text=1)
        self.append_column(col_int)

    def on_spinner_pulse(self):
        for row in self.model:
            if row[0]:
                if row[1] == 150:
                    row[1] = 0
                else:
                    row[1] += 1
        self.spinner_renderer.set_property("pulse", row[1])
        return True

class Window(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title='CellRendererSpinner')
        self.set_default_size(200, 400)

        self.view = TreeView()
        self.add(self.view)

        self.connect('destroy', Gtk.main_quit)
        self.show_all()

if __name__ == '__main__':
    win = Window()
    GObject.timeout_add(100, win.view.on_spinner_pulse)
Gtk.main()

increment the Gtk.CellRendererSpinner :pulse property at regular intervals

  1. Increase "pulse" value of cellrendererspinner by calling self.spinner_renderer.set_property("pulse", newValue) in a method

  2. Call that method repeatedly with GObject.timeout_add(milliseconds, method) function

MaxPlankton
  • 1,158
  • 14
  • 28
  • Why is there the `pulse` limit of `150`? Where in the docs are this limit? – buhtz May 10 '18 at 10:56
  • Your code works fine. But please add more then two columns and there are problems: Sometimes they spin, sometimes they don't. I expanded your code to explain this https://gist.github.com/buhtz/81526447695fa7dc7d31259e8617aff1 – buhtz May 10 '18 at 10:57
  • 1
    The limt 150 is just a random value I choose. If you change the line `row[1] += 1` t o`row[1] += -1`. You will see a warning issued, `OverflowError: -1 not in range 0 to 4294967295`. – MaxPlankton May 10 '18 at 14:25
  • When they don't spin (in my gist-example code) it depends on some drawing issues. It is hard to reproduce. But when I move the mouse they spin. – buhtz May 10 '18 at 19:56
  • I don't know why it doesn't work sometimes. I translate this program to D programming language. It always spins(even for 10 rows). https://gist.github.com/mywtfmp3/0ded49c3646b2dddcc098c782cfef7e5 – MaxPlankton May 11 '18 at 08:47
0

From the docs:

To start the animation in a cell, set the Gtk.CellRendererSpinner :active property to True and increment the Gtk.CellRendererSpinner :pulse property at regular intervals. The usual way to set the cell renderer properties for each cell is to bind them to columns in your tree model using e.g. Gtk.TreeViewColumn.add_attribute().

Alexander Dmitriev
  • 2,483
  • 1
  • 15
  • 20
  • _increment ... :pulse property at regular intervals_? What does it mean in code? I have to spin it manualy? I imagine an on/off switch like `active`. – buhtz May 10 '18 at 07:18