I do not know of a ready-to-use tool, but you could use Traits UI to swiftly develop your own
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()
That's it. You will have a GUI like:
Traits UI uses the Model-View-Controller approach to create GUI without having the need to programatically create every widget. Here, I use the predefined ValueEditor to display arbitrary types. You can now extend it to support searching, filtering etc...
EDIT
Simple extension to support filtering:
# -*- 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()
will give you a textbox with "filter-as-you-type". The search isn't completely correct for all cases, but you can figure out the idea.
Please note that in this sample the data in the dict are partly integers and partly strings, and both types will be found.
