自定义 Gtk.CellRenderer 只渲染第一行?
Custom Gtk.CellRenderer just rendering the first row?
我无法理解为什么我的自定义 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()
对于您通过的每个项目,您都将星星渲染到开罗表面的同一位置,并且不遵守您应该使用的 cell_area
。正在替换
cr.move_to (i*(self.font_size+1), cell_area.y)
在您的代码中将产生您期望的结果。但是 the documentation for do_render()
为您提供了有关要使用的间距的更多信息:
Invokes the virtual render function of the Gtk.CellRenderer
. The three passed-in rectangles are areas in cr
. Most renderers will draw within cell_area
; the xalign, yalign, xpad, and ypad fields of the Gtk.CellRenderer
should be honored with respect to cell_area
. background_area
includes the blank space around the cell, and also the area containing the tree expander; so the background_area
rectangles for all cells tile to cover the entire window
.
此外,'destroy'
信号有一个 window
参数,因此您应该定义 on_quit(self, window)
或类似的参数。
我无法理解为什么我的自定义 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()
对于您通过的每个项目,您都将星星渲染到开罗表面的同一位置,并且不遵守您应该使用的 cell_area
。正在替换
cr.move_to (i*(self.font_size+1), cell_area.y)
在您的代码中将产生您期望的结果。但是 the documentation for do_render()
为您提供了有关要使用的间距的更多信息:
Invokes the virtual render function of the
Gtk.CellRenderer
. The three passed-in rectangles are areas incr
. Most renderers will draw withincell_area
; the xalign, yalign, xpad, and ypad fields of theGtk.CellRenderer
should be honored with respect tocell_area
.background_area
includes the blank space around the cell, and also the area containing the tree expander; so thebackground_area
rectangles for all cells tile to cover the entirewindow
.
此外,'destroy'
信号有一个 window
参数,因此您应该定义 on_quit(self, window)
或类似的参数。