自定义Gtk.CellRenderer,在python Gtk 3的True、None(显示为不一致)和False之间循环切换

自定义Gtk.CellRenderer,在python Gtk 3的True、None(显示为不一致)和False之间循环切换,python,toggle,gtk3,gtktreeview,Python,Toggle,Gtk3,Gtktreeview,我需要编写一个自定义的Gtk.CellRenderer(我们称之为cellRenderToogleWithNone),其行为类似于Gtk.cellRenderToggle,但是,除了只支持True和False之外,我还希望它支持None,这应该显示为如下不一致状态: 在切换时,我想按照一些定义的顺序旋转,例如:True->False->None (但这可能是最简单的部分,我仍然认为我提到了这一点) 我也不知道如何使用TreeStore,因为如果我这样做了 self.treestore = Gtk

我需要编写一个自定义的
Gtk.CellRenderer
(我们称之为
cellRenderToogleWithNone
),其行为类似于
Gtk.cellRenderToggle
,但是,除了只支持
True
False
之外,我还希望它支持
None
,这应该显示为如下不一致状态:

在切换时,我想按照一些定义的顺序旋转,例如:True->False->None (但这可能是最简单的部分,我仍然认为我提到了这一点)

我也不知道如何使用TreeStore,因为如果我这样做了

self.treestore = Gtk.TreeStore.new(types = (bool,))
iter = self.treestore.append(parent = None, row = (None,))
它会将任何
None
值转换为
False
,因为
bool
似乎不允许
None

我在网上找不到任何有用的自定义
Gtk.CellRenderer
示例

我想通过继承
Gtk.CellRenderer
而不是
Gtk.CellRendererToggle
来实现这一点,因为这也可以作为实现更多类似这样的单元格渲染器的有用示例

我只能猜测我必须为
TreeStore
定义一些自定义数据类型,比如
bool\u或_none
,而不是
bool
(也不知道如何做),并在自定义
cellRenderToogleWithNone>中保留我自己的
Gtk.ToggleButton

编辑0:

关于如何编写自定义
Gtk.CellRenderer
给出了一些提示,这些提示可能可以重用,但并不能解决我的问题。它没有显示如何使
Gtk.TreeStore
接受
None
变量的
bool
值,我不理解其中的所有内容。它甚至没有使用一个Gtk.按钮,相反,它似乎在一个小部件中画了一个框,我猜它可能是父部件。我不想绘制自己的切换,我想重用
Gtk.ToggleButton
及其
不一致的
属性

编辑1:

因为定制单元格渲染器似乎并不容易,所以我认为在python中看到一个最小的工作示例将特别有用。我还应该提到,我希望尽可能紧凑地显示数据,这排除了建议的解决方法,例如一个值有两个切换

问题:自定义
Gtk.cellRenderToggle
,在True、None(显示为不一致)和False之间循环切换

您被误导了,设置
不一致
标志不是
Gtk.cellRenderToggle
对象的一部分。已经准备好了。您必须实现一个
Gtk.TreeCellDataFunc

我还希望它支持
None

我不能让它与
None
值一起工作,
因此,我将type
int
与值一起使用:
[False,True,2]

注意

  • def on_切换(…)
    中,
    model
    值更改为
    0==False
    1==True
    。如果希望它保持为
    布尔型
    ,请相应地实现
  • 您应该知道,值
    2
    的计算结果也是
    True


参考

  • 此函数用于替代用于设置列值的标准属性映射,并应根据需要设置self的单元渲染器的值

  • 用于设置单元属性的函数,而不是仅使用单元和模型之间的直线映射。这对于自定义单元渲染器非常有用


实现:核心点:
.set\u cell\u data\u func(cell\u呈现程序,.set\u状态)

用法

使用Python:3.5-gi进行测试。版本:3.22.0

问题:自定义
Gtk.cellRenderToggle
,在True、None(显示为不一致)和False之间循环切换

您被误导了,设置
不一致
标志不是
Gtk.cellRenderToggle
对象的一部分。已经准备好了。您必须实现一个
Gtk.TreeCellDataFunc

我还希望它支持
None

我不能让它与
None
值一起工作,
因此,我将type
int
与值一起使用:
[False,True,2]

注意

  • def on_切换(…)
    中,
    model
    值更改为
    0==False
    1==True
    。如果希望它保持为
    布尔型
    ,请相应地实现
  • 您应该知道,值
    2
    的计算结果也是
    True


参考

  • 此函数用于替代用于设置列值的标准属性映射,并应根据需要设置self的单元渲染器的值

  • 用于设置单元属性的函数,而不是仅使用单元和模型之间的直线映射。这对于自定义单元渲染器非常有用


实现:核心点:
.set\u cell\u data\u func(cell\u呈现程序,.set\u状态)

用法


使用Python:3.5-gi进行测试。\uuuuu版本:3.22.0

这是否回答了您的问题?1) 您可以将值存储在GVariant中,或者创建一个包含3个可能值的自定义类,然后可以创建一个类型为
object
的列。我不确定它是否一定是b
class TreeViewColumnTriState(Gtk.TreeViewColumn):

    def __init__(self, title='', model=None, **attributes):
        cell_renderer = Gtk.CellRendererToggle()
        cell_renderer.connect("toggled", self.on_toggle, model)

        self.inconsistent = attributes.pop('inconsistent', None)
        super().__init__(title, cell_renderer, active=0, **attributes)
        self.set_cell_data_func(cell_renderer, self.set_status)

    def set_status(self, column, cell, model, _iter, *ignore):    
        if model.get_value(_iter, 0) == self.inconsistent:
            cell.set_property('inconsistent', True)
        else:
            cell.set_property('inconsistent', False)

    def on_toggle(self, cell, path, model, *ignore):
        if path is not None:
            model = model[model.get_iter(path)]    
            model[0] += 1
            if model[0] == 3:
                model[0] = 0
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib


class App(Gtk.ApplicationWindow):
    def __init__(self):
        super().__init__()
        self.connect("destroy", Gtk.main_quit)

        model = Gtk.ListStore(int)

        #  Some initial data
        for n in [False, True, 2]:
            model.append([n])

        col = TreeViewColumnTriState("Foo", model, inconsistent=2)

        tv = Gtk.TreeView(model)
        tv.append_column(col)
        self.add(tv)

        self.show_all()


if __name__ == "__main__":
    main = App()
    Gtk.main()