2
Hello, and welcome to this test of the wxTreeItemData
5
The wxTreeItemData class can be used to associate a python
6
object with a wxTreeCtrl item. In this sample, its use is
7
demonstrated via a tree control that shows the contents of a
8
python namespace according to the standard dir()
9
command. Every item in the tree has its label taken from the
10
dir() output, and 'behind it' a reference to the python
11
object is stored in a wxTreeItemData object.
13
As you may have guessed by now, this sample automatically
14
displays '__doc__' strings if the selected python object
15
happens to have one. Please expand the pyTree object to
16
learn more about the implementation.
18
Version 1.0, April 4 1999.
19
Harm van der Heijden (H.v.d.Heijden@phys.tue.nl)
21
P.S. Check out the string module. It's imported in this
22
sample not because it's used, but because it's so
23
beautifully documented...
26
import string # Used for demo purposes, nothing more. :-)
31
#----------------------------------------------------------------------
34
"""Returns the indentation level of the given line."""
37
if c == ' ': indent = indent + 1
38
elif c == '\t': indent = indent + 8
42
def _sourcefinder(func):
43
"""Given a func_code object, this function tries to find and return
44
the python source code of the function."""
46
f = open(func.co_filename,"r")
48
return "(could not open file %s)" % (func.co_filename,)
50
for i in range(func.co_firstlineno):
53
ind = _getindent(line)
59
# the following should be <= ind, but then we get
60
# confused by multiline docstrings. Using == works most of
61
# the time... but not always!
62
if _getindent(line) == ind: break
66
#----------------------------------------------------------------------
68
class pyTree(wx.TreeCtrl):
70
This wx.TreeCtrl derivative displays a tree view of a Python namespace.
71
Anything from which the dir() command returns a non-empty list is a branch
75
def __init__(self, parent, id, root):
77
Initialize function; because we insert branches into the tree
78
as needed, we use the ITEM_EXPANDING event handler. The
79
ITEM_COLLAPSED handler removes the stuff afterwards. The
80
SEL_CHANGED handler attempts to display interesting
81
information about the selected object.
83
wx.TreeCtrl.__init__(self, parent, id)
84
self.root = self.AddRoot(str(root), -1, -1, wx.TreeItemData(root))
87
self.SetItemHasChildren(self.root, True)
89
self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.OnItemExpanding, id=self.GetId())
90
self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed, id=self.GetId())
91
self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, id=self.GetId())
94
self.Expand(self.root)
97
def SetOutput(self, output):
99
Set output function (accepts single string). Used to display string
100
representation of the selected object by OnSelChanged.
105
def OnItemExpanding(self,event):
107
The real workhorse of this class. First we retrieve the object
108
(parent) belonging to the branch that is to be expanded. This
109
is done by calling GetPyData(parent), which is a short-cut for
110
GetPyItemData(parent).Get().
112
Then we get the dir() list of that object. For each item in
113
this list, a tree item is created with associated
114
wxTreeItemData referencing the child object. We get this
115
object using child = getattr(parent, item).
117
Finally, we check wether the child returns a non-empty dir()
118
list. If so, it is labeled as 'having children', so that it
119
may be expanded. When it actually is expanded, this function
120
will again figure out what the offspring is.
122
item = event.GetItem()
124
if self.IsExpanded(item): # This event can happen twice in the self.Expand call
127
obj = self.GetPyData( item )
131
new_obj = getattr(obj,key)
132
new_item = self.AppendItem( item, key, -1, -1,
133
wx.TreeItemData(new_obj) )
136
self.SetItemHasChildren(new_item, True)
138
def OnItemCollapsed(self, event):
140
We need to remove all children here, otherwise we'll see all
141
that old rubbish again after the next expansion.
143
item = event.GetItem()
144
self.DeleteChildren(item)
146
def OnSelChanged(self, event):
148
If an output function is defined, we try to print some
149
informative, interesting and thought-provoking stuff to it.
150
If it has a __doc__ string, we print it. If it's a function or
151
unbound class method, we attempt to find the python source.
156
obj = self.GetPyData( event.GetItem() )
159
if hasattr(obj, '__doc__'):
160
msg = msg+"\n\nDocumentation string:\n\n%s" % ( getattr(obj, '__doc__'),)
165
if hasattr(obj, "func_code"): # normal function
166
func = getattr(obj, "func_code")
168
elif hasattr(obj, "im_func"): # unbound class method
169
func = getattr(getattr(obj, "im_func"), "func_code")
171
if func: # if we found one, let's try to print the source
172
msg = msg+"\n\nFunction source:\n\n" + _sourcefinder(func)
174
apply(self.output, (msg,))
176
#----------------------------------------------------------------------
180
def runTest(frame, nb, log):
182
This method is used by the wxPython Demo Framework for integrating
183
this demo with the rest.
185
thisModule = sys.modules[__name__]
186
win = wx.Frame(frame, -1, "PyTreeItemData Test")
187
split = wx.SplitterWindow(win, -1)
188
tree = pyTree(split, -1, thisModule)
189
text = wx.TextCtrl(split, -1, "", style=wx.TE_MULTILINE)
190
split.SplitVertically(tree, text, 200)
191
tree.SetOutput(text.SetValue)
192
tree.SelectItem(tree.root)
193
win.SetSize((800,500))
199
#----------------------------------------------------------------------
200
if __name__ == '__main__':
202
class MyFrame(wx.Frame):
203
"""Very standard Frame class. Nothing special here!"""
206
"""Make a splitter window; left a tree, right a textctrl. Wow."""
208
wx.Frame.__init__(self, None, -1, "PyTreeItemData Test", size=(800,500))
209
split = wx.SplitterWindow(self, -1)
210
tree = pyTree(split, -1, __main__)
211
text = wx.TextCtrl(split, -1, "", style=wx.TE_MULTILINE)
212
split.SplitVertically(tree, text, 200)
213
tree.SetOutput(text.SetValue)
214
tree.SelectItem(tree.root)
217
"""This class is even less interesting than MyFrame."""
220
"""OnInit. Boring, boring, boring!"""
223
self.SetTopWindow(frame)