使用TraitsUI ListEditor Factory进行任意收集

时间:2017-09-01 18:31:51

标签: python enthought traitsui

如何使用TraitsUI调整ListEditor以列出任意集合的内容?这是一个示例代码

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替换标准列表,我会得到'AttributeError:'Office'对象没有属性'value''错误。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

Traits对list特征中存储的任何内容使用TraitListObject子类(List):这是允许对列表中项目的更改触发特征事件以及属性。我猜测SortedListWithKey类来自" Sorted Containers"第三方包,所以不是特征列表。 ListEditor期望TraitsListObject(或类似工作)使其正常工作,因为它需要知道列表项是否已更改。

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

  1. 使用两个List特征,一个未分类(可能是Set)和一个已排序,并具有特征更改处理程序以同步这两个特征。如果您的无序数据是"模型的一部分,那么这种模式很有效。图层及其排序方式是面向用户的一部分" view"或"演示"图层(即可能在TraitsUI ControllerModelView对象中)。

  2. 编写TraitListObject的子类,其自我排序行为为SortedListWithKey。使用常规的List特征,但是将子类的实例分配给它,或者用于真正光滑的行为子类List,以便在任何设置操作上转换到新的子类。

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

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

  5. 虽然这显然是最不优雅的解决方案,但在大多数情况下,我可能会选择第一种解决方案。您也可以考虑在ETS-Users群组中发布此问题,看看是否有其他人对此有所了解。