从Python GTK中的ListBox(绑定到ListStore)中获取选定的对象

时间:2019-01-07 16:50:59

标签: python gtk pygtk pygobject

我用ListBox(作为播放列表)制作了一个简单的GTK音乐播放器。

这是GObject类,我使用它来绑定到ListBox(使用bind_model()方法)和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)

这是我将ListStore绑定到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)

到目前为止,一切正常。

问题是:是否可以根据选择检索(存储在播放列表中的)Song对象?要检索存储在该对象中的路径属性?

如果没有,是否至少可以检索选择文本?

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

提供回溯:

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

行变量的类型

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

因此,我认为上面的代码应该像一种魅力一样工作……但事实并非如此。

非常感谢您提供的任何帮助!

2 个答案:

答案 0 :(得分:1)

因此,您需要为选择分配以下内容:

treeview_selection = treeview.get_selection()    

并将其与“更改的”信号连接:

treeview_selection.connect('changed', on_tree_selection_changed)

然后,您可以使用以下方法获取所需的数据:

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.

我建议您阅读pgi docspython Gtk docs

答案 1 :(得分:0)

  

是否可以根据选择检索Song对象(存储在播放列表中)?要检索存储在该对象中的路径属性?

def on_row_selected(self, container, row):
    song = playlist.get_item(row.get_index())
  

如果没有,是否至少可以检索选择文本?

def on_row_selected(self, container, row):
    name = row.get_child().get_text()

这里是一个例子。如果必须处理多个选择,也可以使用selected-rows-changed信号:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gio, GObject
import sys

class Song(GObject.GObject):

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

    def __init__(self, path, name):
        GObject.GObject.__init__(self)
        self.path = path
        self.name = name
class GUI:

    def __init__(self):        
        self.playlist = Gio.ListStore()
        self.playlist.append(Song("path1", "name1"))
        self.playlist.append(Song("path2", "name2"))
        self.playlist.append(Song("path3", "name3"))

        play_listbox = Gtk.ListBox()
        play_listbox.set_selection_mode(Gtk.SelectionMode.SINGLE)
        play_listbox.bind_model(self.playlist, self.create_widget_func)
        play_listbox.connect('row-selected', self.on_row_selected_1)
        play_listbox.connect('row-selected', self.on_row_selected_2)
        play_listbox.connect('selected-rows-changed', self.on_selected_rows_changed)

        window = Gtk.Window()
        window.add(play_listbox)
        window.connect("destroy", self.on_window_destroy)
        window.show_all()

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

    def on_row_selected_1(self ,container, row):
        print("on_row_selected_1")
        song = self.playlist.get_item(row.get_index())
        print(song.path)

    def on_row_selected_2(self ,container, row):
        print("on_row_selected_2")
        print(row.get_child().get_text())

    def on_selected_rows_changed(self, container):      
        print("on_selected_rows_changed", len(container.get_selected_rows()), "item(s) selected")
        for row in container.get_selected_rows():
            song = self.playlist.get_item(row.get_index())
            print(song.name, song.path)
        print("---")

    def on_window_destroy(self, window):
        Gtk.main_quit()

def main():

    app = GUI()
    Gtk.main()

if __name__ == "__main__":
    sys.exit(main())