在Gtk.TreeView中只创建一些粗体行

时间:2018-04-14 21:47:12

标签: python python-3.x gtk3 pygobject

我想通过制作文本(行中的列)粗体来显示行的状态读取未读

行的状态(或模型中的数据)可以是模型的一部分或其他位置。我现在很灵活。

如何根据底层(动态)数据使特定单元格的文本变为粗体,在此示例中为值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()

2 个答案:

答案 0 :(得分:2)

经过与Gtk维护人员的简短讨论后,我发现有另一种更清洁的方法可以做到这一点。由于这两个答案都有效,我决定将其作为单独的答案。

另一个答案的问题是每一行都会调用cell_data_func。随着时间的推移,如果你有很多行,这将变得非常慢。

此处的解决方案是在模型中添加另一列,然后将其绑定到相关属性。

目前,您执行以下操作:

col = Gtk.TreeViewColumn(
            'Text', renderer, text=0, weight_set=True)

这会将text的{​​{1}}属性绑定到模型的第0列。

现在,我们也可以将它绑定到任何其他属性。例如,将列1绑定到CellRenderer属性:

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]) ... 属性(将字符串解析为pango标记,并允许您更改文本某些部分的字体,颜色等)和markup属性,您可以使用pango.AttrList类型一次设置多个样式属性。

答案 1 :(得分:1)

通常在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)

正如您所看到的,它会收到所涉及的TreeViewColumnCellRendererTreeModelTreeIter以及我已经忽略的自定义数据。

第一步是获取当前列的值。为此,我们为模型提供了treeiter(保存了“当前行”,有点)和我们想要的列ID(在本例中是第二列1)。

其余的很简单,我们使用该值来决定是否需要在CellRenderer上设置“weight”属性。

您在这里使用了700,但为了清晰起见,我建议您使用Pango.Weight.BOLD。当然,这需要from gi.repository import Pango