如何在树视图中动态调整pixbuf cellrenderer的大小?

时间:2013-11-04 21:58:42

标签: python python-2.7 gtk gtk3

pic

我正在使用如上所示的Gtk3 TreeView。该模型是Gtk.TreeStore

  • Gtk.TreeStore(str,GdkPixbuf.Pixbuf)

对于图片,我可以通过以下方式将正确大小的图像添加到模型中:

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

然而,我也在其他地方使用该模型以不同的方式显示pixbuf,pixbuf也可以是各种尺寸。

我想要做的是强制在运行时显示图片的大小。问题是 - 我该怎么做?

我尝试强制GtkCellRendererPixbuf为固定大小,但这只显示正确大小的图像 - 但只有图像部分对应于固定大小

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

我想过使用TreeViewColumn的set_cell_data_func

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

我也通过调整treemodel pixbuf而不是cell.props.pixbuf来尝试替代方案,但这也给出了与上面相同的错误。

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

所以显然这不是正确的做法 - 所以任何想法如何处理这个?任何基于C ++ / Python的示例代码Gtk3的链接都是最受欢迎的。

我正在使用Gtk + 3.6 / python 2.7

1 个答案:

答案 0 :(得分:2)

老问题,但遗憾的是仍然相关 - 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

此解决方案的一个问题是,只要TreeStore的内容发生变化,您就必须从dict中删除存储的Pixbuf,否则它们将永远存在,并且您的程序将消耗超过必要的内存。