как мне динамически изменять размер сотового рендерера pixbuf в древовидной структуре?

pic

Я использую Gtk3 TreeView, как показано выше. Модель представляет собой Gtk.TreeStore.

  • Gtk.TreeStore(str, GdkPixbuf.Pixbuf)

Для изображения я мог добавить к модели изображения правильного размера с помощью:

  • pixbuf.scale_simple(48,48,GdkPixbuf.InterpType.BILINEAR)

Однако я также использую модель в другом месте, показывающую пиксбуфы по-другому, и пиксбуфы также могут быть разных размеров.

То, что я хотел бы сделать, это принудительно установить размер изображения, отображаемого во время выполнения. Вопрос - как мне это сделать?

Я попытался заставить GtkCellRendererPixbuf иметь фиксированный размер, но это просто отображает изображение правильного размера, но только часть изображения, соответствующую фиксированному размеру.

pixbuf = Gtk.CellRendererPixbuf()
pixbuf.set_fixed_size(48,48)

Я подумал об использовании set_cell_data_func из TreeViewColumn:

col = Gtk.TreeViewColumn('', pixbuf, pixbuf=1)
col.set_cell_data_func(pixbuf, self._pixbuf_func, None)

def _pixbuf_func(self, col, cell, tree_model, tree_iter, data):
    cell.props.pixbuf = cell.props.pixbuf.scale_simple(48,48,GdkPixbuf.InterpType.BILINEAR)

Это делает динамическое изменение размера изображения во время выполнения, НО в терминале я получаю сотни ошибок, таких как это:

sys:1: RuntimeWarning: Expecting to marshal a borrowed reference for <Pixbuf object at 0x80acbe0 (GdkPixbuf at 0x87926d0)>, but nothing in Python is holding a reference to this object. See: https://bugzilla.gnome.org/show_bug.cgi?id=687522

Я также попробовал альтернативу, изменив размер pixbuf модели дерева вместо cell.props.pixbuf, но это также дает ту же ошибку, что и выше.

cell.props.pixbuf = tree_model.get_value(tree_iter,1).scale_simple(48,48,GdkPixbuf.InterpType.BILINEAR)

Так что, очевидно, это неправильный способ сделать это - так что есть мысли, как еще подойти к этому? Приветствуются любые ссылки на пример кода Gtk3 на основе C++/Python.

Я использую Gtk+3.6/python 2.7.


person fossfreedom    schedule 04.11.2013    source источник


Ответы (1)


Старый вопрос, но, к сожалению, все еще актуальный - эта ошибка в Gtk все еще существует. К счастью, есть довольно простой обходной путь. Все, что вам нужно сделать, это сохранить ссылку на масштабированный pixbuf.

Я изменил функцию _pixbuf_func, чтобы она принимала словарь, в котором она хранит маленькие файлы pixbuf. Это избавляет от надоедливого предупреждающего сообщения, а также предотвращает уменьшение масштаба pixbuf при каждом вызове _pixbuf_func.

def pixbuf_func(col, cell, tree_model, tree_iter, data):
    pixbuf= tree_model[tree_iter][1] # get the original pixbuf from the TreeStore. [1] is
                                     # the index of the pixbuf in the TreeStore.
    try:
        new_pixbuf= data[pixbuf] # if a downscaled pixbuf already exists, use it
    except KeyError:
        new_pixbuf= pixbuf.scale_simple(48,48,GdkPixbuf.InterpType.BILINEAR)
        data[pixbuf]= new_pixbuf # keep a reference to this pixbuf to prevent Gtk warning
                                 # messages
    cell.set_property('pixbuf', new_pixbuf)

renderer = Gtk.CellRendererPixbuf()
col = Gtk.TreeViewColumn('', renderer)
col.set_cell_data_func(renderer, pixbuf_func, {}) # pass a dict to keep references in

Проблема с этим решением заключается в том, что вы должны удалять сохраненные Pixbuf из dict всякий раз, когда содержимое вашего TreeStore изменяется, иначе они останутся навсегда, и ваша программа будет потреблять больше памяти, чем необходимо.

person Aran-Fey    schedule 29.05.2016