我不知道现成的工具,但您可以使用Traits UI快速开发自己的
from enthought.traits.api \
import HasTraits, Instance
from enthought.traits.ui.api \
import View, VGroup, Item, ValueEditor
class DictEditor(HasTraits):
Object = Instance( object )
def __init__(self, obj, **traits):
super(DictEditor, self).__init__(**traits)
self.Object = obj
def trait_view(self, name=None, view_elements=None):
return View(
VGroup(
Item( 'Object',
label = 'Debug',
id = 'debug',
editor = ValueEditor(),
style = 'custom',
dock = 'horizontal',
show_label = False
),
),
title = 'Dictionary Editor',
width = 800,
height = 600,
resizable = True,
)
def build_sample_data():
my_data = dict(zip(range(10),range(10,20)))
my_data[11] = dict(zip(range(10),range(10,20)))
my_data[11][11] = dict(zip(range(10),range(10,20)))
return my_data
# Test
if __name__ == '__main__':
my_data = build_sample_data()
b = DictEditor(my_data)
b.configure_traits()
而已。您将拥有如下 GUI:
Traits UI 使用模型-视图-控制器方法来创建 GUI,而无需以编程方式创建每个小部件。在这里,我使用预定义的 ValueEditor 来显示任意类型。您现在可以扩展它以支持搜索、过滤等...
编辑
支持过滤的简单扩展:
# -*- coding: utf-8 -*-
"""
Created on Fri Feb 22 12:52:28 2013
@author: kranzth
"""
from enthought.traits.api \
import HasTraits, Instance, Str, on_trait_change
from enthought.traits.ui.api \
import View, VGroup, Item, ValueEditor, TextEditor
from copy import deepcopy
class DictEditor(HasTraits):
SearchTerm = Str()
Object = Instance( object )
def __init__(self, obj, **traits):
super(DictEditor, self).__init__(**traits)
self._original_object = obj
self.Object = self._filter(obj)
def trait_view(self, name=None, view_elements=None):
return View(
VGroup(
Item( 'SearchTerm',
label = 'Search:',
id = 'search',
editor = TextEditor(),
#style = 'custom',
dock = 'horizontal',
show_label = True
),
Item( 'Object',
label = 'Debug',
id = 'debug',
editor = ValueEditor(),
style = 'custom',
dock = 'horizontal',
show_label = False
),
),
title = 'Dictionary Editor',
width = 800,
height = 600,
resizable = True,
)
@on_trait_change("SearchTerm")
def search(self):
self.Object = self._filter(self._original_object, self.SearchTerm)
def _filter(self, object_, search_term=None):
def has_matching_leaf(obj):
if isinstance(obj, list):
return any(
map(has_matching_leaf, obj))
if isinstance(obj, dict):
return any(
map(has_matching_leaf, obj.values()))
else:
try:
if not str(obj) == search_term:
return False
return True
except ValueError:
False
obj = deepcopy(object_)
if search_term is None:
return obj
if isinstance(obj, dict):
for k in obj.keys():
if not has_matching_leaf(obj[k]):
del obj[k]
for k in obj.keys():
if isinstance(obj, dict):
obj[k] = self._filter(obj[k], search_term)
elif isinstance(obj, list):
filter(has_matching_leaf,obj[k])
return obj
def build_sample_data():
def make_one_level_dict():
return dict(zip(range(100),
range(100,150) + map(str,range(150,200))))
my_data = make_one_level_dict()
my_data[11] = make_one_level_dict()
my_data[11][11] = make_one_level_dict()
return my_data
# Test
if __name__ == '__main__':
my_data = build_sample_data()
b = DictEditor(my_data)
b.configure_traits()
会给你一个带有“filter-as-you-type”的文本框。搜索并非对所有情况都完全正确,但您可以弄清楚这个想法。
请注意,在此示例中,dict 中的数据部分是整数,部分是字符串,两种类型都会被找到。