在 Gtk.TreeView 中仅将某些行设为粗体
Make only some rows bold in a Gtk.TreeView
我想显示行的状态 已读 或 未读 =21=]是否加粗是否加粗
行(或模型中的数据)的状态可以是模型的一部分或其他地方。在这一点上我很灵活。
如何根据基础(动态)数据将特定单元格的文本加粗,在此示例中为值 1
?
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class View(Gtk.TreeView):
def __init__(self, model):
Gtk.TreeView.__init__(self, model)
col = Gtk.TreeViewColumn('Text',
Gtk.CellRendererText(),
text=0)
self.append_column(col)
# bold text
# Gtk.CellRendererText(weight_set=True, weight=700),
class Model(Gtk.ListStore):
def __init__(self):
Gtk.ListStore.__init__(self, str, int)
self.append(['foo 1', 0])
self.append(['foo 2', 1]) # bold
self.append(['foo 3', 0])
self.append(['foo 4', 0])
self.append(['foo 5', 1]) # bold
class Window(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
self.set_default_size(100, 200)
# model & view
self.model = Model()
self.view = View(self.model)
# layout
self.layout = Gtk.Grid()
self.add(self.layout)
self.layout.attach(self.view, 0, 0, 1, 2)
self.connect('destroy', Gtk.main_quit)
self.show_all()
if __name__ == '__main__':
win = Window()
Gtk.main()
就像 Gtk 中经常出现的那样,这非常非常简单,只是不是很明显。您真的需要知道在哪里查看并仔细阅读相关文档。
class View(Gtk.TreeView):
def __init__(self, model):
Gtk.TreeView.__init__(self, model)
renderer = Gtk.CellRendererText()
col = Gtk.TreeViewColumn(
'Text', renderer, text=0, weight_set=True)
col.set_cell_data_func(renderer, datafunc)
self.append_column(col)
第一个键是TreeViewColumn.set_cell_data_func
method。这允许您设置一个拦截函数,您可以使用该函数在单元格呈现之前修改它的属性。这是我写的一个示例,它可以满足您的要求:
def datafunc(col, renderer, model, titer, data):
val = model.get_value(titer, 1)
if val:
renderer.set_property("weight", 700)
如您所见,它接收了涉及的 TreeViewColumn
、CellRenderer
、TreeModel
和 TreeIter
,以及自定义数据,这些我已经省略了。
第一步是获取当前列的值。为此,我们为模型提供了 treeiter(它保存了 "current row",有点)和我们想要的列 ID(在本例中是第二列,1
)。
剩下的很简单,我们使用该值来决定是否需要在 CellRenderer 上设置 "weight" 属性。
您在这里使用了 700,但为了清楚起见,我建议您改用 Pango.Weight.BOLD
。这当然需要from gi.repository import Pango
。
在与 Gtk 维护者进行简短讨论后,我发现还有另一种更简洁的方法可以做到这一点。由于这两个答案都有效,我决定将其作为单独的答案。
另一个答案的问题是每一行都会调用 cell_data_func
。随着时间的推移,如果你有很多行,这会变得非常慢。
此处的解决方案是向您的模型添加另一列,然后将其绑定到相关属性。
目前,您执行以下操作:
col = Gtk.TreeViewColumn(
'Text', renderer, text=0, weight_set=True)
这会将 CellRenderer
的 text
属性 绑定到模型的第 0 列。
现在,我们也可以将它绑定到任何其他 属性。例如,将第 1 列绑定到 weight
属性:
col = Gtk.TreeViewColumn(
'Text', renderer, text=0, weight=1, weight_set=True)
然后您可以将此列设置为不同的 Pango.Weight
值以更改文本的粗细。
class Model(Gtk.ListStore):
def __init__(self):
...
self.append(['foo 1', Pango.Weight.BOLD])
self.append(['foo 2', Pango.Weight.BOOK])
...
如果你想设置额外的属性,你也可以设置 markup
属性(它将字符串解析为 pango 标记并允许你更改某些部分的字体、颜色等文本的)和 attributes
属性,您可以使用它们一次设置许多样式属性 pango.AttrList 类型。
我想显示行的状态 已读 或 未读 =21=]是否加粗是否加粗
行(或模型中的数据)的状态可以是模型的一部分或其他地方。在这一点上我很灵活。
如何根据基础(动态)数据将特定单元格的文本加粗,在此示例中为值 1
?
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class View(Gtk.TreeView):
def __init__(self, model):
Gtk.TreeView.__init__(self, model)
col = Gtk.TreeViewColumn('Text',
Gtk.CellRendererText(),
text=0)
self.append_column(col)
# bold text
# Gtk.CellRendererText(weight_set=True, weight=700),
class Model(Gtk.ListStore):
def __init__(self):
Gtk.ListStore.__init__(self, str, int)
self.append(['foo 1', 0])
self.append(['foo 2', 1]) # bold
self.append(['foo 3', 0])
self.append(['foo 4', 0])
self.append(['foo 5', 1]) # bold
class Window(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
self.set_default_size(100, 200)
# model & view
self.model = Model()
self.view = View(self.model)
# layout
self.layout = Gtk.Grid()
self.add(self.layout)
self.layout.attach(self.view, 0, 0, 1, 2)
self.connect('destroy', Gtk.main_quit)
self.show_all()
if __name__ == '__main__':
win = Window()
Gtk.main()
就像 Gtk 中经常出现的那样,这非常非常简单,只是不是很明显。您真的需要知道在哪里查看并仔细阅读相关文档。
class View(Gtk.TreeView):
def __init__(self, model):
Gtk.TreeView.__init__(self, model)
renderer = Gtk.CellRendererText()
col = Gtk.TreeViewColumn(
'Text', renderer, text=0, weight_set=True)
col.set_cell_data_func(renderer, datafunc)
self.append_column(col)
第一个键是TreeViewColumn.set_cell_data_func
method。这允许您设置一个拦截函数,您可以使用该函数在单元格呈现之前修改它的属性。这是我写的一个示例,它可以满足您的要求:
def datafunc(col, renderer, model, titer, data):
val = model.get_value(titer, 1)
if val:
renderer.set_property("weight", 700)
如您所见,它接收了涉及的 TreeViewColumn
、CellRenderer
、TreeModel
和 TreeIter
,以及自定义数据,这些我已经省略了。
第一步是获取当前列的值。为此,我们为模型提供了 treeiter(它保存了 "current row",有点)和我们想要的列 ID(在本例中是第二列,1
)。
剩下的很简单,我们使用该值来决定是否需要在 CellRenderer 上设置 "weight" 属性。
您在这里使用了 700,但为了清楚起见,我建议您改用 Pango.Weight.BOLD
。这当然需要from gi.repository import Pango
。
在与 Gtk 维护者进行简短讨论后,我发现还有另一种更简洁的方法可以做到这一点。由于这两个答案都有效,我决定将其作为单独的答案。
另一个答案的问题是每一行都会调用 cell_data_func
。随着时间的推移,如果你有很多行,这会变得非常慢。
此处的解决方案是向您的模型添加另一列,然后将其绑定到相关属性。
目前,您执行以下操作:
col = Gtk.TreeViewColumn(
'Text', renderer, text=0, weight_set=True)
这会将 CellRenderer
的 text
属性 绑定到模型的第 0 列。
现在,我们也可以将它绑定到任何其他 属性。例如,将第 1 列绑定到 weight
属性:
col = Gtk.TreeViewColumn(
'Text', renderer, text=0, weight=1, weight_set=True)
然后您可以将此列设置为不同的 Pango.Weight
值以更改文本的粗细。
class Model(Gtk.ListStore):
def __init__(self):
...
self.append(['foo 1', Pango.Weight.BOLD])
self.append(['foo 2', Pango.Weight.BOOK])
...
如果你想设置额外的属性,你也可以设置 markup
属性(它将字符串解析为 pango 标记并允许你更改某些部分的字体、颜色等文本的)和 attributes
属性,您可以使用它们一次设置许多样式属性 pango.AttrList 类型。