自定义Gtk.CellRenderer只渲染第一行?

时间:2016-01-10 09:57:31

标签: python python-3.x gtk3 pygobject

我无法理解为什么我的自定义Gtk.CellRenderer仅渲染Gtk.ListStore的第一行。

我一直在阅读许多文档并尝试cellrenderer.set_visible(True)这样的内容,但我仍然不知道为什么会这样。

以下是一个完整的例子:

from gi.repository import Gtk, Gdk, cairo, Pango, PangoCairo, GObject
import time

class CellRenderer5Stars(Gtk.CellRenderer):
    __gproperties__ = {
        'rating': ( int, # type
                    "integer prop", # nick
                    "A property that contains an integer", # blurb
                    0, # min
                    5, # max
                    0, # default
                    GObject.PARAM_READWRITE # flags
                    ),
    }

    def __init__(self):
        super().__init__()
        self.font_size=15
        self.font="Sans Bold {}".format(self.font_size)
        self.rating = 5

    def do_set_property(self, pspec, value):
        setattr(self, pspec.name, value)

    def do_get_property(self, pspec):
        return getattr(self, pspec.name)

    def do_get_size(self, widget, cell_area):
        return (0, 0, self.font_size*5, self.font_size+5)

    def do_render(self, cr, widget, background_area, cell_area, flags):
        cr.translate (0, 0)
        layout = PangoCairo.create_layout(cr)
        desc = Pango.font_description_from_string (self.font)
        layout.set_font_description(desc)

        stars_var = self.rating

        for i in range(5):
            if i < stars_var:
                layout.set_text("★", -1)
            else:
                layout.set_text("☆", -1)

            cr.save()
            PangoCairo.update_layout (cr, layout)
            cr.move_to (i*(self.font_size+1), 0)
            PangoCairo.show_layout (cr, layout)
            cr.restore()

GObject.type_register(CellRenderer5Stars)


class Window(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.connect('destroy', self.on_quit)

        liststore = Gtk.ListStore(int)
        liststore.append([3])
        liststore.append([2])
        liststore.append([1])

        treeview = Gtk.TreeView(liststore)

        treeviewcolumn = Gtk.TreeViewColumn("Rating")
        treeview.append_column(treeviewcolumn)
        cellrenderer = CellRenderer5Stars()
        treeviewcolumn.pack_start(cellrenderer, True)
        treeviewcolumn.add_attribute(cellrenderer, "rating", 0)

        self.add(treeview)
        self.show_all()

    def on_quit(self):
        Gtk.main_quit()

w = Window()
Gtk.main()

1 个答案:

答案 0 :(得分:0)

对于您传递的每件物品,您都会将星星渲染到开罗表面的同一位置,并且不遵守您应该使用的cell_area。替换

cr.move_to (i*(self.font_size+1), cell_area.y)
代码中的

将产生您期望的结果。但the documentation for do_render()为您提供了有关使用间距的更多信息:

  

调用Gtk.CellRenderer的虚拟渲染功能。三个传入的矩形是cr中的区域。大多数渲染器将在cell_area内绘制; Gtk.CellRenderer的xalign,yalign,xpad和ypad字段应该尊重cell_areabackground_area包括单元格周围的空白区域,以及包含树形扩展器的区域;所以所有单元格的background_area矩形都会覆盖整个window

此外,'destroy'信号的参数为window,因此您应该定义on_quit(self, window)或类似信号。