Search code examples
pythonlistboxgtkgtk3

Make a Select All button of multiples CheckButton inside a ListBox


i'm trying to make a list which each row has a checkButton and on top of this list i want a Select/Deselect All option. The problem is that i can't even figure it out how to iterate between the CheckButtons to use something like 'Gtk.CheckButton.Set_activate(True)'. I'm totally lost with this problem.

Here my code so far

class ListChapters(Gtk.Window):

def __init__(self):
    Gtk.Window.__init__(self, title="List of Itens")
    self.set_border_width(10)

    box_outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
    self.add(box_outer)

    listbox = Gtk.ListBox()
    listbox.set_selection_mode(Gtk.SelectionMode.NONE)
    box_outer.pack_start(listbox,False, False, 0)

    row = Gtk.ListBoxRow()
    hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
    row.add(hbox)
    label = Gtk.Label('Marcar/Desmarcar tudo.', xalign=0)
    checkall = Gtk.CheckButton()
    hbox.pack_start(label, True, True, 0)
    hbox.pack_end(checkall, False, True, 0)
    listbox.add(row)
    checkall.connect("toggled", self.mark_all)

    listbox2 = Gtk.ListBox()
    listbox2.set_selection_mode(Gtk.SelectionMode.NONE)
    box_outer.pack_start(listbox2, True, True, 0)

    index = ['Item1','Item2','Item3']

    for i in index:
        row = Gtk.ListBoxRow()
        hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
        row.add(hbox)
        cap = Gtk.Label(i, xalign=0)
        check = Gtk.CheckButton()
        hbox.pack_start(cap, True, True, 0)
        hbox.pack_start(check, False, True, 0)
        listbox2.add(row)
        check.connect("toggled", self.on_check_marked)

Solution

  • Question: Select All button of multiples CheckButton inside a ListBox
    ... i can't even figure it out how to iterate between the CheckButtons

    Basically you can do:

    for boxrow in listbox2:
    

    Gtk 3.0 (3.24.5) Documentation:


    1. Define you own ListBoxRow inheriting from Gtk.ListBoxRow

      class ListBoxRow(Gtk.ListBoxRow):
          def __init__(self, label, **kwargs):
              super().__init__(**kwargs)
      
    2. Define your widgets and make self.check a class attribute.

              hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50)
              self.add(hbox)
      
              cap = Gtk.Label(label, xalign=0)
              hbox.pack_start(cap, True, True, 0)
      
              self.check = check = Gtk.CheckButton()
              hbox.pack_start(check, False, True, 0)
      
              check.connect("toggled", self.on_check_marked)
      
    3. Define a class methode checkbutton(... to set and get the active state of the CheckButton

          def checkbutton(self, state=None):
              print('checkbutton({})'.format(state))
              if state is True:
                  self.check.set_active(state)
              elif state is False:
                  self.check.set_active(state)
              else:
                  return self.check.get_active()
      
    4. To make check.connect(... happy ...

          def on_check_marked(self, event):
              print('on_check_marked({})'.format(event))
      

    Usage:

    1. Add your ListBoxRow(... to listbox2

              for label in ['Item1','Item2','Item3']:
                  row = ListBoxRow(label=label)
                  listbox2.add(row)
      
    2. Iterate ListbBox to set all CheckButton in ListBoxRow according to the passed CheckButton active state.

          def mark_all(self, checkbox):
              for boxrow in self.listbox2:
                  boxrow.checkbutton(state=checkbox.get_active())
      

    Tested with Python: 3.5 - gi.__version__: 3.22.0