LINUX.ORG.RU

[pygtk] Динамическая генерация полей gtk.ListStore

 


0

1

Приветствую.

Имеется список питоновских объектов с кучей полей внутри. Необходимо отобразить значения некоторых полей объектов из этого списка в gtk.TreeView.

В самом начале я создал наследника gtk.ListStore с первым полем содержащим мой пайтоноский объект и кучей дополнительных полей отражающих данные из полей этого объекта. Решение простое, но неэффективно и громоздкое — надо дублировать данные (соответственно растет объем занимаемой памяти), следить за тем чтоб в полях модели и полях объекта были одни и те же данные и т.д.

Сейчас у меня возникло желание генерировать часть полей, которые содержат данные из пайтоновского объекта, динамически. Соответственно возможно ли это и какие методы требуется переопределить в моем наследнике gtk.ListStore?

★★★★★

Ответ на: комментарий от baverman

А просто get()? И еще, как я недавно узнал, с gtk.TreeModel можно работать как с обычным пайтоновским списком, поэтомы всякие __getitem__(), __setitem__() и прочая переопределять не надо?

fat_angel ★★★★★
() автор топика
Ответ на: комментарий от fat_angel

А просто get()?

Насколько знаю, он рендерерами не вызывается.

всякие __getitem__(), __setitem__()

Они должны использовать get_value.

baverman ★★★
()

Нифига не работает

import os
import mutagen
import gtk
import gobject
import pango


(TAG_EDIT_COLUMN_PATH, TAG_EDIT_COLUMN_FILE, TAG_EDIT_COLUMN_TITLE,
 TAG_EDIT_COLUMN_ARTIST, TAG_EDIT_COLUMN_ALBUM, TAG_EDIT_COLUMN_TRACK,
 TAG_EDIT_COLUMN_DATE, TAG_EDIT_COLUMN_GENRE,
 TAG_EDIT_COLUMN_COMMENT) = range(9)

class TagEditView(gtk.TreeView):
    def __init__(self, column_order=(TAG_EDIT_COLUMN_FILE,
      TAG_EDIT_COLUMN_TITLE, TAG_EDIT_COLUMN_ARTIST, TAG_EDIT_COLUMN_ALBUM,
      TAG_EDIT_COLUMN_TRACK, TAG_EDIT_COLUMN_DATE, TAG_EDIT_COLUMN_GENRE,
      TAG_EDIT_COLUMN_COMMENT)):
        super(TagEditView, self).__init__()
        self.set_columns(column_order)
        self.set_column_width(-1, 100)

    def __create_column(self, title, data_column, callback=None):
        renderer = gtk.CellRendererText()
        renderer.set_property("ellipsize", pango.ELLIPSIZE_END)
        renderer.set_property("editable", True)
        if callback is not None:
            renderer.connect("edited", callback)
        column = gtk.TreeViewColumn(title, renderer)
        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        column.set_resizable(True)
        column.set_attributes(renderer, text=data_column)
        self.append_column(column)

    def set_columns(self, column_order=(TAG_EDIT_COLUMN_FILE,
      TAG_EDIT_COLUMN_TITLE, TAG_EDIT_COLUMN_ARTIST, TAG_EDIT_COLUMN_ALBUM,
      TAG_EDIT_COLUMN_TRACK, TAG_EDIT_COLUMN_DATE, TAG_EDIT_COLUMN_GENRE,
      TAG_EDIT_COLUMN_COMMENT)):
        # First of all remove exist columns from view if any
        for i in self.get_columns():
            self.remove_column(i)
        for i in column_order:
            if i == TAG_EDIT_COLUMN_PATH:
                self.__create_column("File path", 1, None)
            elif i == TAG_EDIT_COLUMN_FILE:
                self.__create_column("File name", 2, None)
            elif i == TAG_EDIT_COLUMN_TITLE:
                self.__create_column("Title", 3, None)
            elif i == TAG_EDIT_COLUMN_ARTIST:
                self.__create_column("Artist", 4, None)
            elif i == TAG_EDIT_COLUMN_ALBUM:
                self.__create_column("Album", 5, None)
            elif i == TAG_EDIT_COLUMN_TRACK:
                self.__create_column("Track", 6, None)
            elif i == TAG_EDIT_COLUMN_DATE:
                self.__create_column("Year", 7, None)
            elif i == TAG_EDIT_COLUMN_GENRE:
                self.__create_column("Genre", 8, None)
            elif i == TAG_EDIT_COLUMN_COMMENT:
                self.__create_column("Comment", 9, None)
            else:
                continue

    def set_column_width(self, n, width):
        """Set width for column n. If n<0 set given width for all columns."""
        if n < 0:
            for i in self.get_columns():
                i.set_fixed_width(width)
        else:
            self.get_column(n).set_fixed_width(width)

    def set_model(self, model):
        if isinstance(model, TagEditStore):
            super(TagEditView, self).set_model(model)
        else:
            raise TypeError("parameter 'model' must be of type 'TagEditStore'")


class TagEditStore(gtk.ListStore):
    def __init__(self, files=None):
        """Class for storing information about audio files.
        Column order:
        0 - Mutagen object
        1 - Full path to file
        2 - File basename
        3 - Track title
        4 - Artist
        5 - Album
        6 - Track number (can be given in track_number/track_total)
        7 - Date
        8 - Genre
        9 - Comment"""
        super(TagEditStore, self).__init__(gobject.TYPE_PYOBJECT,
                                           gobject.TYPE_STRING)
        if files is not None:
            self.load_files(files)

    def get_value(self, iter, column):
        if column == 0 or column == 1:
            return super(TagEditStore, self).get_value(iter, column)
        elif column == 2:
            return os.path.basename(
                                   super(TagEditStore, self).get_value(iter, 1))
        elif column >= 3 and column <= 9:
            mfile = super(TagEditStore, self).get_value(iter, 0)
            if column == 3:
                return mfile.get("title")
            elif column == 4:
                return mfile.get("artist")
            elif column == 5:
                return mfile.get("album")
            elif column == 6:
                return mfile.get("tracknumber")
            elif column == 7:
                return mfile.get("date")
            elif column == 8:
                return mfile.get("genre")
            else:
                return mfile.get("comment")
        else:
            raise ValueError("column number is out of range")

    def load_files(self, files):
        """Load files from 'files' list. If file does not exists or not
        supported by mytagen library it will be skipped."""
        for i in files:
            try:
                mfile = mutagen.File(i, easy=True)
            except IOError:
                continue
            if mfile is None:
                continue
            self.append((mfile, i))

    def save_files(self):
        """Save changes in previously loaded files."""
        iter = self.get_iter_first()
        while iter:
            mfile = self.get_value(iter, 0)
            mfile.save()
            iter = self.iter_next(iter)

    def set_tag(self, iter, tag_name, value):
        pass


def main():
    import sys
    window = gtk.Window()
    window.set_title("Tag Editor")
    window.set_default_size(600, 400)
    window.connect("destroy", gtk.main_quit)
    model = TagEditStore(sys.argv[1:])
    view = TagEditView()
    view.set_model(model)
    scrollwin = gtk.ScrolledWindow()
    scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    scrollwin.set_shadow_type(gtk.SHADOW_IN)
    scrollwin.add(view)
    window.add(scrollwin)
    window.show_all()
    gtk.main()

if __name__ == '__main__':
    main()

Пишет следующее

nkt@arnor python % ./mutagenlist.py ~/music/Margin_of_Safety/2006_Gonzo_Jazz/*
./mutagenlist.py:190: GtkWarning: gtk_list_store_get_value: assertion `column < list_store->n_columns' failed
  window.show_all()
./mutagenlist.py:190: Warning: g_object_set_property: assertion `G_IS_VALUE (value)' failed
  window.show_all()
./mutagenlist.py:190: Warning: g_value_unset: assertion `G_IS_VALUE (value)' failed
  window.show_all()
./mutagenlist.py:191: GtkWarning: gtk_list_store_get_value: assertion `column < list_store->n_columns' failed
  gtk.main()
./mutagenlist.py:191: Warning: g_object_set_property: assertion `G_IS_VALUE (value)' failed
  gtk.main()
./mutagenlist.py:191: Warning: g_value_unset: assertion `G_IS_VALUE (value)' failed
  gtk.main()
Окно создается но список получается пустым.

fat_angel ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.