Search code examples
pythongtkpygtkpygobject

Get selected object from ListBox (binded to ListStore) in Python GTK


I have made a simple GTK music player with ListBox (as playlist).

This is GObject class, which i use to bind to ListBox (using bind_model() method) and ListStore.

import eyed3
from gi.repository import Gio, GObject

class Song(GObject.GObject):

    path = GObject.Property(type=str)
    name = GObject.Property(type=str)

    def __init__(self, path):
        GObject.GObject.__init__(self)
        self.path = path
        self.file = eyed3.load(path)
        self.name = self

    def __str__(self):
        return str(self.file.tag.artist) + ' - ' + str(self.file.tag.title)


playlist = Gio.ListStore().new(Song)

And this is how I bind ListStore to ListBox:

play_listbox.connect('row-selected', self.on_row_selected)

playlist.append(Song('/home/user/Downloads/Some album/01 - Song1.mp3'))
playlist.append(Song('/home/user/Downloads/Some album/02 - Song2.mp3'))

play_listbox.bind_model(playlist, self.create_song_label)

def create_song_label(self, song):
    return Gtk.Label(label=song.name)

And so far, everything works like it should.

The question is: Is it possible to retrieve Song object (stored in playlist) based on selection? To retrieve path property stored in that object?

If not, is it possible to at least retrieve selection text? Trying this with

def on_row_selected(self, container, row):
    print(row.widget.label)

Gives a traceback:

Traceback (most recent call last):
  File "/home/user/Documents/App/player.py", line 45, in on_row_selected
    print(row.widget.label) # or data, value, text - nothing works
RuntimeError: unable to get the value

row variable is of type

<Gtk.ListBoxRow object at 0x7f9fe7604a68 (GtkListBoxRow at 0x5581a51ef7d0)>

So above code, I think, should work like a charm... but it doesn't.

Thank you very much for any help provided!


Solution

  • So you need to assign the selection with:

    treeview_selection = treeview.get_selection()    
    

    And connect it with the 'changed' signal:

    treeview_selection.connect('changed', on_tree_selection_changed)
    

    Then you can fetch the required data with:

    def on_tree_selection_changed(self, treeview):
        model, treeiter = treeview.get_selected()
        if treeiter is not None:
            print(model[treeiter][0]) # you should a list index to get the data you require for each row - first column = [0], second column = [1] etc.
    

    I would suggest you read the pgi docs and also the python Gtk docs