| 1 |
import pygtk |
| 2 |
pygtk.require('2.0') |
| 3 |
import gtk |
| 4 |
|
| 5 |
class Browser: |
| 6 |
def make_row( self, piter, name, value ): |
| 7 |
info = repr(value) |
| 8 |
if not hasattr(value, "__dict__"): |
| 9 |
if len(info) > 80: |
| 10 |
# it's a big list, or dict etc. |
| 11 |
info = info[:80] + "..." |
| 12 |
_piter = self.treestore.append( piter, [ name, type(value).__name__, info ] ) |
| 13 |
return _piter |
| 14 |
|
| 15 |
def make_instance( self, value, piter ): |
| 16 |
if hasattr( value, "__dict__" ): |
| 17 |
for _name, _value in value.__dict__.items(): |
| 18 |
_piter = self.make_row( piter, "."+_name, _value ) |
| 19 |
_path = self.treestore.get_path( _piter ) |
| 20 |
self.otank[ _path ] = (_name, _value) |
| 21 |
|
| 22 |
def make_children(self, value, piter ): |
| 23 |
children = [] |
| 24 |
if hasattr(value,"children"): |
| 25 |
children=value.children; |
| 26 |
for child in children: |
| 27 |
_name = child.name; |
| 28 |
_piter = self.make_row(piter,_name,child) |
| 29 |
_path = self.treestore.get_path(_piter) |
| 30 |
self.otank[_path]=(_name,child) |
| 31 |
|
| 32 |
def make_mapping( self, value, piter ): |
| 33 |
keys = [] |
| 34 |
if hasattr( value, "keys" ): |
| 35 |
keys = value.keys() |
| 36 |
elif hasattr( value, "__len__"): |
| 37 |
keys = range( len(value) ) |
| 38 |
for key in keys: |
| 39 |
_name = "[%s]"%str(key) |
| 40 |
_piter = self.make_row( piter, _name, value[key] ) |
| 41 |
_path = self.treestore.get_path( _piter ) |
| 42 |
self.otank[ _path ] = (_name, value[key]) |
| 43 |
|
| 44 |
def make(self, name=None, value=None, path=None, depth=1): |
| 45 |
if path is None: |
| 46 |
# make root node |
| 47 |
piter = self.make_row( None, name, value ) |
| 48 |
path = self.treestore.get_path( piter ) |
| 49 |
self.otank[ path ] = (name, value) |
| 50 |
else: |
| 51 |
name, value = self.otank[ path ] |
| 52 |
|
| 53 |
piter = self.treestore.get_iter( path ) |
| 54 |
if not self.treestore.iter_has_child( piter ): |
| 55 |
#self.make_mapping( value, piter ) |
| 56 |
#self.make_instance( value, piter ) |
| 57 |
self.make_children(value,piter) |
| 58 |
|
| 59 |
if depth: |
| 60 |
for i in range( self.treestore.iter_n_children( piter ) ): |
| 61 |
self.make( path = path+(i,), depth = depth - 1 ) |
| 62 |
|
| 63 |
def row_expanded( self, treeview, piter, path ): |
| 64 |
self.make( path = path ) |
| 65 |
|
| 66 |
def delete_event(self, widget, event, data=None): |
| 67 |
gtk.main_quit() |
| 68 |
return gtk.FALSE |
| 69 |
|
| 70 |
def __init__(self, name, value): |
| 71 |
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) |
| 72 |
self.window.set_title("Browser") |
| 73 |
self.window.set_size_request(512, 320) |
| 74 |
self.window.connect("delete_event", self.delete_event) |
| 75 |
|
| 76 |
# we will store the name, the type name, and the repr |
| 77 |
columns = [str,str,str] |
| 78 |
self.treestore = gtk.TreeStore(*columns) |
| 79 |
|
| 80 |
# the otank tells us what object we put at each node in the tree |
| 81 |
self.otank = {} # map path -> (name,value) |
| 82 |
self.make( name, value ) |
| 83 |
|
| 84 |
self.treeview = gtk.TreeView(self.treestore) |
| 85 |
self.treeview.connect("row-expanded", self.row_expanded ) |
| 86 |
|
| 87 |
self.tvcolumns = [ gtk.TreeViewColumn() for _type in columns ] |
| 88 |
i = 0 |
| 89 |
for tvcolumn in self.tvcolumns: |
| 90 |
self.treeview.append_column(tvcolumn) |
| 91 |
cell = gtk.CellRendererText() |
| 92 |
tvcolumn.pack_start(cell, True) |
| 93 |
tvcolumn.add_attribute(cell, 'text', i) |
| 94 |
i = i + 1 |
| 95 |
|
| 96 |
self.window.add(self.treeview) |
| 97 |
self.window.show_all() |
| 98 |
|
| 99 |
def dump( name, value ): |
| 100 |
browser = Browser( name, value ) |
| 101 |
gtk.main() |
| 102 |
|
| 103 |
def test(): |
| 104 |
class Thing: |
| 105 |
def __init__(self,name,value): |
| 106 |
self.children = [] |
| 107 |
self.name=name |
| 108 |
self.value=value |
| 109 |
self.index=0 |
| 110 |
def findChildren(self): |
| 111 |
print "FINDING CHILDREN OF ", self.name |
| 112 |
def addChild(self,thing): |
| 113 |
print thing.name,"is a child of ",self.name |
| 114 |
self.children.append(thing); |
| 115 |
def __repr__(self): |
| 116 |
return self.name |
| 117 |
def __iter__(self): |
| 118 |
for i in range(len(self.children)): |
| 119 |
yield self.children[i] |
| 120 |
|
| 121 |
a = Thing("a","A value") |
| 122 |
b = Thing("b","B Another value") |
| 123 |
c = Thing("c","C Another value") |
| 124 |
d = Thing("d","D Yet another value") |
| 125 |
a.addChild(b) |
| 126 |
b.addChild(c) |
| 127 |
c.addChild(d) |
| 128 |
d.addChild(a) # circular chain |
| 129 |
dump( "a", a ) |
| 130 |
|
| 131 |
if __name__ == "__main__": |
| 132 |
test() |