将 TraitsUI 列表编辑器工厂用于任意集合



如何使用 TraitsUI 调整列表编辑器以列出任意集合的内容?下面是一个示例代码

from traits.api import HasStrictTraits, Instance, Int, List, Str
from traitsui.api import View, Item, ListEditor, InstanceEditor
from sortedcontainers import SortedListWithKey
class Person(HasStrictTraits):
name = Str
age = Int
class Office(HasStrictTraits):
# employees = Instance(SortedListWithKey, 
kw={'key': lambda employee: employee.age})
employees = List
employee_view = View(
Item(name='name', show_label=False, style='readonly')
)
office_view = View(
Item(name='adults',
show_label=False,
style='readonly',
editor=ListEditor(
style='custom',
editor=InstanceEditor(view=employee_view),
),
),
resizable=True
)
employee_list = [Person(name='John', age=31), Person(name='Mike', age=31),
Person(name='Jill', age=37), Person(name='Eric', age=28)]
#office = Office()
#office.employees.update(employee_list)
office = Office(employees=employee_list)
office.configure_traits(view=office_view)

如果我使用我注释掉的代码将标准列表替换为 SortedListWithKey,我会收到"属性错误:"Office"对象没有属性"值"错误。我该如何解决这个问题?

Traits对存储在ListTraits 中的任何内容使用list子类 (TraitListObject):这允许在更改列表中的项目以及属性时触发 Traits 事件。 我猜SortedListWithKey类来自"排序容器"第三方包,因此不是特征列表。ListEditor需要一个TraitsListObject(或类似工作)才能正常工作,因为它需要知道列表项是否已更改。

我能想到的修复/解决方法:

  1. 使用两个List特征,一个未排序(可能是Set),一个已排序,并具有特征更改处理程序来同步两者。 如果您的无序数据是"模型"层的一部分,并且它的排序方式是面向用户的"视图"或"表示"层的一部分(即可能在 TraitsUIControllerModelView对象中),则这种模式非常有效。

  2. 编写一个具有SortedListWithKey自排序行为的TraitListObject子类。 使用常规List特征,但将子类的实例分配给其中,或者对于真正光滑的行为子类List在任何集合操作上转换为新的子类。

  3. 使用
  4. 常规List特征,但使用带有nameage列的TableEditor:这是与您的意图不同的 UI,可能不适合您的现实世界,但TableEditor可以设置为对列进行自动排序。 对于更简单的示例,ListStrEditor也可能有效。

  5. 向 TraitsUIListEditor添加功能,以便可以选择按排序顺序显示列表项。 这可能是最困难的选择。

虽然这显然是最不优雅的解决方案,但在大多数情况下,我可能只会选择第一个。您也可以考虑将此问题发布在 ETS 用户组上,看看是否有其他人对此有一些想法。

最新更新