he code of the Browser is freely available via the Download link in the
python subdirectory. The detailed description and the code follows next.
The lines 1-2 import wxPython library and the tree widget.
The function browse(...), lines 4-12, is the main interface.
Lines 7,10,12 start and kill the "Event loop" of wxPython.
Line 9 is the call to the implementation class.
The displayPrivates argument regulates whether the browser will display fields
starting with underscore "_". The displayCallables argument regulates whether
the browser will display callable fields (functions). The verboseDict
regulates the manner of dictionary visualization.
Lines 17-39 is the initialization code of the ObjectBrowser class.
Lines 22,23 initialize wxPython's Frame and TreeListCtrl classes.
Line 24 binds the event EVT_TREE_ITEM_EXPANDED to the method _OnItemExpanded
of the ObjectBrowser class.
Lines 25-33 build initial column layout.
Lines 34-37 set initial node of the tree: the main string (line 34), type
string (line 35) and callable test (lines 36-37).
Lines 38 is a call to _populateItem function that populates the list of
immediate children.
Line 39 is a convenience call to expand the root node.
Lines 41-44 is the function that regulate the appearance of the root node. It
is a customization point. The body of this function may be replaced with
almost anything. It has to return a string and should not throw.
Lines 46-50 is the function that regulates the commentary string that appears
first in the children list of every node. This is a customization point. It
has to return a string and should not throw.
Lines 55-144 is the function that inserts a list of children for every given
node of the tree. The "parent" argument is the node in question. The exact
type is TreeItemId of the wxPython library. The "obj" argument is the object
whose fields will constitute the children list.
The groups of cells 57-66, 67-79,...,103-112 specify special handling for
string, list, tuple, dictionary, integer and floating point number. Each of
these is a call to _addToTree member function that encapsulates access to the
TreeListCtrl object. This function is described below.
The cells 113-121 is the default handler.
The cells 122-144 are the principal code that generates the list of fields of
the "obj"-given object.
The function _hasValue (lines 146-147) identifies the fields that have a
value. It is a customization point. By default it is set to identify integers,
floats and strings. However, it can be anything as long as you can supply
matching customization of the function _getValueStr that follows next, lines
149-150. These functions should not throw.
The function _addToTree, lines 152-161, adds a single node to the
TreeListCtrl. The "parent" argument is the parent node of the added node. The
"itemStr" is the main string of the added node. "typeStr" is the type string
(second column string). The arguments "isCallableBool" is the data for the
third column. The argument "hasChildrenBool" specifies whether the added node
will have the expansion sign (+). The argument "treeData" is the associated
python object.
The function _hasChildren, lines 164-169, identifies the object that has
children in the tree.
The function _OnItemExpanded is an event handler for expansion of a node
(user's click on (+) sign).
1\import wx
2\import wx.gizmos
3\
4\def
browse(obj,displayPrivates=False,displayCallables=False,verboseDict=False)
:
5\
print
"OTS Object Browser, www.opentradingsystem.com"
6\
print
"Copyright 2009, Konstantin Aslanidi"
7\
_otsObjectBrowserApp
= wx.App(False)
8\
try:
9\
ObjectBrowser(obj,displayPrivates,displayCallables,verboseDict).Show()
10\
_otsObjectBrowserApp.MainLoop()
11\
finally:
12\
del
_otsObjectBrowserApp
13\
14\
15\class ObjectBrowser:
16\
_toBeExpandedTag="ToBeExpanded"
17\
def
__init__(self,obj,displayPrivates,displayCallables,verboseDict):
18\
self._object=obj
19\
self._displayPrivates=displayPrivates
20\
self._displayCallables=displayCallables
21\
self._verboseDict=verboseDict
22\
self._frame=wx.Frame(
None, wx.ID_ANY, title="OTS Python Object Browser", size=(500,500))
23\
self._tree
= wx.gizmos.TreeListCtrl(self._frame, style = wx.TR_DEFAULT_STYLE \
wx.TR_FULL_ROW_HIGHLIGHT)
24\
self._frame.Bind(wx.EVT_TREE_ITEM_EXPANDED,
self._OnItemExpanded, self._tree)
25\
self._tree.AddColumn("Name")
26\
self._tree.AddColumn("Type")
27\
if
self._displayCallables :
28\
self._tree.AddColumn("Callable")
29\
self._tree.SetMainColumn(0)
30\
self._tree.SetColumnWidth(0,200)
31\
self._tree.SetColumnWidth(1,200)
32\
if
self._displayCallables :
33\
self._tree.SetColumnWidth(2,200)
34\
root
= self._tree.AddRoot(self._rootObjectDescriptor())
35\
self._tree.SetItemText(root,
type(self._object).__name__, 1)
36\
if
self._displayCallables :
37\
self._tree.SetItemText(root,
self._toStr(callable(self._object)), 2)
38\
self._populateItem(root,self._object)
39\
self._tree.Expand(root)
40\
41\
def
_rootObjectDescriptor(self) :
42\
if
type(self._object)==type("") :
43\
return
self._object
44\
return
"root"
45\
46\
def
_toStr(self,o) :
47\
try
:
48\
return
o.__str__()
49\
except
:
50\
return
"__str__() is not defined"
51\
52\
def
Show(self) :
53\
self._frame.Show()
54\
55\
def
_populateItem(self,parent,obj) :
56\
handled=False
57\
if
type(obj)==type(") :
58\
self._addToTree(
\
59\
parent=parent,
\
60\
itemStr="'"+obj+"'",
\
61\
typeStr=type(obj).__name__,
\
62\
isCallableBool=False,
\
63\
hasChildrenBool=False,
\
64\
treeData=None
\
65\
)
66\
handled=True
67\
if
type(obj)==type([]) or type(obj)==type(()) :
68\
i=0
69\
for
x in obj :
70\
self._addToTree(
\
71\
parent=parent,
\
72\
itemStr='['+self._toStr(i)+']',
\
73\
typeStr=",
\
74\
isCallableBool=False,
\
75\
hasChildrenBool=True,
\
76\
treeData=x
\
77\
)
78\
i=i+1
79\
handled=True
80\
if
type(obj)==type({}) :
81\
i=0
82\
for
x in obj :
83\
if
self._verboseDict :
84\
self._addToTree(
\
85\
parent=parent,
\
86\
itemStr='['+self._toStr(x)+']',
\
87\
typeStr=",
\
88\
isCallableBool=False,
\
89\
hasChildrenBool=True,
\
90\
treeData=(x,obj[x])
\
91\
)
92\
else
:
93\
self._addToTree(
\
94\
parent=parent,
\
95\
itemStr='['+self._toStr(x)+']',
\
96\
typeStr=type(obj[x]).__name__,
\
97\
isCallableBool=False,
\
98\
hasChildrenBool=True,
\
99\
treeData=obj[x]
\
100\
)
101\
i=i+1
102\
handled=True
103\
if
type(obj)==type(1) or type(obj)==type(0.1) :
104\
self._addToTree(
\
105\
parent=parent,
\
106\
itemStr=self._toStr(obj),
\
107\
typeStr=type(obj).__name__,
\
108\
isCallableBool=False,
\
109\
hasChildrenBool=False,
\
110\
treeData=None
\
111\
)
112\
handled=True
113\
if
not handled :
114\
self._addToTree(
\
115\
parent=parent,
\
116\
itemStr=self._toStr(obj),
\
117\
typeStr=type(obj).__name__,
\
118\
isCallableBool=False,
\
119\
hasChildrenBool=False,
\
120\
treeData=obj
\
121\
)
122\
for
item in dir(obj) :
123\
if
not self._displayPrivates and item[0]=='_' :
124\
continue
125\
attr=getattr(obj,item)
126\
if
not self._displayCallables and callable(attr) :
127\
continue
128\
ni=self._addToTree(
\
129\
parent=parent,
\
130\
itemStr=item,
\
131\
typeStr=type(attr).__name__,
\
132\
isCallableBool=callable(attr),
\
133\
hasChildrenBool=self._hasChildren(attr),
\
134\
treeData=attr
\
135\
)
136\
if
self._hasValue(attr) :
137\
self._addToTree(
\
138\
parent=ni,
\
139\
itemStr=self._getValueStr(attr),
\
140\
typeStr=",
\
141\
isCallableBool=False,
\
142\
hasChildrenBool=False,
\
143\
treeData=attr
\
144\
)
145\
146\
def
_hasValue(self,attr) :
147\
return
type(attr)==type(1) or type(attr)==type(0.1) or type(attr)==type(")
148\
149\
def
_getValueStr(self,attr) :
150\
return
self._toStr(attr)
151\
152\
def
_addToTree(self,parent,itemStr,typeStr,isCallableBool,hasChildrenBool,treeData)
:
153\
newItem=self._tree.AppendItem(parent,itemStr)
154\
self._tree.SetItemText(newItem,typeStr,1)
155\
if
self._displayCallables :
156\
self._tree.SetItemText(newItem,isCallableBool.__str__(),2)
157\
if
not treeData is None :
158\
self._tree.SetItemPyData(newItem,treeData)
159\
if
hasChildrenBool :
160\
self._tree.AppendItem(newItem,self._toBeExpandedTag)
161\
return
newItem
162\
163\
164\
def
_hasChildren(self,obj) :
165\
for
item in dir(obj) :
166\
if
not self._displayPrivates and item[0]=='_' :
167\
continue
168\
return
True
169\
return
False
170\
171\
def
_OnItemExpanded(self, evt):
172\
item=evt.GetItem()
173\
child=self._tree.GetFirstChild(item)[0]
174\
if
self._tree.GetItemText(child,0)==self._toBeExpandedTag :
175\
self._tree.DeleteChildren(item)
176\
obj=self._tree.GetItemPyData(item)
177\
self._populateItem(item,obj)
|