自定义 Gtk.CellRenderer,在 True、None(显示为不一致)和 False、python GTK 3 之间循环切换
Custom Gtk.CellRenderer with a Toggle cycling between True, None (displayed as inconsistent) and False, python GTK 3
我需要编写一个行为类似于 Gtk.CellRendererToggle
的自定义 Gtk.CellRenderer
(我们称之为 CellRendererToogleWithNone
),而不是仅支持 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_or_none
而不是 bool
(也不知道该怎么做)和在我的习惯 CellRendererToogleWithNone
中保留我自己的 Gtk.ToggleButton
。
编辑 0:
This post 关于如何编写自定义 Gtk.CellRenderer
给出了一些可能可以重用但不能解决我的问题的提示。它没有显示如何让 Gtk.TreeStore
接受 bool
变量的 None
值,我不明白那里的一切。它甚至不使用 Gtk.Button,而是似乎在我猜可能是父级的小部件内绘制了一个框。我不想画自己的 Toggle,我想重用 Gtk.ToggleButton
和它的 inconsistent
属性
编辑 1:
由于自定义单元格渲染器似乎并不容易,我认为在 python 中看到一个最小的工作示例会特别有用。我还应该提到,我想尽可能紧凑地显示数据,这排除了建议的解决方法,例如为一个值设置两个切换。
Question: Custom Gtk.CellRendererToggle
with a Toggle cycling between True, None (displayed as inconsistent) and False.
你被误导了,设置 inconsistant
标志不是 Gtk.CellRendererToggle
对象的一部分。它已经在那里实施了。您必须改为实施 Gtk.TreeCellDataFunc
。
I also want it to support None
I don't get it to work with a None
value,
therefore i use type int
with values: [False, True, 2]
注:
- 在
def on_toggle(...)
中,model
值更改为 0 == False
和 1 == True
。如果您希望它保持 boolean
类型,请相应地实施。
- 您应该知道,值
2
的计算结果也为 True
。
参考:
Gtk.TreeViewColumn.set_cell_data_func
This function is used instead of the standard attributes mapping for setting the column value, and should set the value of self’s cell renderer as appropriate.
-
A function to set the properties of a cell instead of just using the straight mapping between the cell and the model. This is useful for customizing the cell renderer
Implementation: Core point: .set_cell_data_func(cell_renderer, .set_status)
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
Usage:
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()
测试 Python:3.5 - gi.__version__:3.22.0
我需要编写一个行为类似于 Gtk.CellRendererToggle
的自定义 Gtk.CellRenderer
(我们称之为 CellRendererToogleWithNone
),而不是仅支持 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_or_none
而不是 bool
(也不知道该怎么做)和在我的习惯 CellRendererToogleWithNone
中保留我自己的 Gtk.ToggleButton
。
编辑 0:
This post 关于如何编写自定义 Gtk.CellRenderer
给出了一些可能可以重用但不能解决我的问题的提示。它没有显示如何让 Gtk.TreeStore
接受 bool
变量的 None
值,我不明白那里的一切。它甚至不使用 Gtk.Button,而是似乎在我猜可能是父级的小部件内绘制了一个框。我不想画自己的 Toggle,我想重用 Gtk.ToggleButton
和它的 inconsistent
属性
编辑 1:
由于自定义单元格渲染器似乎并不容易,我认为在 python 中看到一个最小的工作示例会特别有用。我还应该提到,我想尽可能紧凑地显示数据,这排除了建议的解决方法,例如为一个值设置两个切换。
Question: Custom
Gtk.CellRendererToggle
with a Toggle cycling between True, None (displayed as inconsistent) and False.
你被误导了,设置 inconsistant
标志不是 Gtk.CellRendererToggle
对象的一部分。它已经在那里实施了。您必须改为实施 Gtk.TreeCellDataFunc
。
I also want it to support
None
I don't get it to work with a
None
value,
therefore i use typeint
with values:[False, True, 2]
注:
- 在
def on_toggle(...)
中,model
值更改为0 == False
和1 == True
。如果您希望它保持boolean
类型,请相应地实施。- 您应该知道,值
2
的计算结果也为True
。
参考:
Gtk.TreeViewColumn.set_cell_data_func
This function is used instead of the standard attributes mapping for setting the column value, and should set the value of self’s cell renderer as appropriate.
-
A function to set the properties of a cell instead of just using the straight mapping between the cell and the model. This is useful for customizing the cell renderer
Implementation: Core point:
.set_cell_data_func(cell_renderer, .set_status)
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
Usage:
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()
测试 Python:3.5 - gi.__version__:3.22.0