すぐに使用できるツールはわかりませんが、TraitsUIを使用して独自のツールをすばやく開発できます。
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があります。
特性UIは、Model-View-Controllerアプローチを使用して、すべてのウィジェットをプログラムで作成する必要なしに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のデータの一部が整数で、一部が文字列であり、両方のタイプが検出されることに注意してください。
