]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/pyTree.py
1 # 11/13/2003 - Jeff Grimmett (grimmtooth@softhome.net)
3 # o Updated for wx namespace
7 Hello, and welcome to this test of the wxTreeItemData
10 The wxTreeItemData class can be used to associate a python
11 object with a wxTreeCtrl item. In this sample, its use is
12 demonstrated via a tree control that shows the contents of a
13 python namespace according to the standard dir()
14 command. Every item in the tree has its label taken from the
15 dir() output, and 'behind it' a reference to the python
16 object is stored in a wxTreeItemData object.
18 As you may have guessed by now, this sample automatically
19 displays '__doc__' strings if the selected python object
20 happens to have one. Please expand the pyTree object to
21 learn more about the implementation.
23 Version 1.0, April 4 1999.
24 Harm van der Heijden (H.v.d.Heijden@phys.tue.nl)
26 P.S. Check out the string module. It's imported in this
27 sample not because it's used, but because it's so
28 beautifully documented...
31 import string
# Used for demo purposes, nothing more. :-)
36 #----------------------------------------------------------------------
39 """Returns the indentation level of the given line."""
42 if c
== ' ': indent
= indent
+ 1
43 elif c
== '\t': indent
= indent
+ 8
47 def _sourcefinder(func
):
48 """Given a func_code object, this function tries to find and return
49 the python source code of the function."""
51 f
= open(func
.co_filename
,"r")
53 return "(could not open file %s)" % (func
.co_filename
,)
55 for i
in range(func
.co_firstlineno
):
58 ind
= _getindent(line
)
64 # the following should be <= ind, but then we get
65 # confused by multiline docstrings. Using == works most of
66 # the time... but not always!
67 if _getindent(line
) == ind
: break
71 #----------------------------------------------------------------------
73 class pyTree(wx
.TreeCtrl
):
75 This wx.TreeCtrl derivative displays a tree view of a Python namespace.
76 Anything from which the dir() command returns a non-empty list is a branch
80 def __init__(self
, parent
, id, root
):
82 Initialize function; because we insert branches into the tree
83 as needed, we use the ITEM_EXPANDING event handler. The
84 ITEM_COLLAPSED handler removes the stuff afterwards. The
85 SEL_CHANGED handler attempts to display interesting
86 information about the selected object.
88 wx
.TreeCtrl
.__init
__(self
, parent
, id)
89 self
.root
= self
.AddRoot(str(root
), -1, -1, wx
.TreeItemData(root
))
92 self
.SetItemHasChildren(self
.root
, True)
94 self
.Bind(wx
.EVT_TREE_ITEM_EXPANDING
, self
.OnItemExpanding
, id=self
.GetId())
95 self
.Bind(wx
.EVT_TREE_ITEM_COLLAPSED
, self
.OnItemCollapsed
, id=self
.GetId())
96 self
.Bind(wx
.EVT_TREE_SEL_CHANGED
, self
.OnSelChanged
, id=self
.GetId())
99 self
.Expand(self
.root
)
102 def SetOutput(self
, output
):
104 Set output function (accepts single string). Used to display string
105 representation of the selected object by OnSelChanged.
110 def OnItemExpanding(self
,event
):
112 The real workhorse of this class. First we retrieve the object
113 (parent) belonging to the branch that is to be expanded. This
114 is done by calling GetPyData(parent), which is a short-cut for
115 GetPyItemData(parent).Get().
117 Then we get the dir() list of that object. For each item in
118 this list, a tree item is created with associated
119 wxTreeItemData referencing the child object. We get this
120 object using child = getattr(parent, item).
122 Finally, we check wether the child returns a non-empty dir()
123 list. If so, it is labeled as 'having children', so that it
124 may be expanded. When it actually is expanded, this function
125 will again figure out what the offspring is.
127 item
= event
.GetItem()
129 if self
.IsExpanded(item
): # This event can happen twice in the self.Expand call
132 obj
= self
.GetPyData( item
)
136 new_obj
= getattr(obj
,key
)
137 new_item
= self
.AppendItem( item
, key
, -1, -1,
138 wx
.TreeItemData(new_obj
) )
141 self
.SetItemHasChildren(new_item
, True)
143 def OnItemCollapsed(self
, event
):
145 We need to remove all children here, otherwise we'll see all
146 that old rubbish again after the next expansion.
148 item
= event
.GetItem()
149 self
.DeleteChildren(item
)
151 def OnSelChanged(self
, event
):
153 If an output function is defined, we try to print some
154 informative, interesting and thought-provoking stuff to it.
155 If it has a __doc__ string, we print it. If it's a function or
156 unbound class method, we attempt to find the python source.
161 obj
= self
.GetPyData( event
.GetItem() )
164 if hasattr(obj
, '__doc__'):
165 msg
= msg
+"\n\nDocumentation string:\n\n%s" % ( getattr(obj
, '__doc__'),)
170 if hasattr(obj
, "func_code"): # normal function
171 func
= getattr(obj
, "func_code")
173 elif hasattr(obj
, "im_func"): # unbound class method
174 func
= getattr(getattr(obj
, "im_func"), "func_code")
176 if func
: # if we found one, let's try to print the source
177 msg
= msg
+"\n\nFunction source:\n\n" + _sourcefinder(func
)
179 apply(self
.output
, (msg
,))
181 #----------------------------------------------------------------------
185 def runTest(frame
, nb
, log
):
187 This method is used by the wxPython Demo Framework for integrating
188 this demo with the rest.
190 thisModule
= sys
.modules
[__name__
]
191 win
= wx
.Frame(frame
, -1, "PyTreeItemData Test")
192 split
= wx
.SplitterWindow(win
, -1)
193 tree
= pyTree(split
, -1, thisModule
)
194 text
= wx
.TextCtrl(split
, -1, "", style
=wx
.TE_MULTILINE
)
195 split
.SplitVertically(tree
, text
, 200)
196 tree
.SetOutput(text
.SetValue
)
197 tree
.SelectItem(tree
.root
)
198 win
.SetSize((800,500))
204 #----------------------------------------------------------------------
205 if __name__
== '__main__':
207 class MyFrame(wx
.Frame
):
208 """Very standard Frame class. Nothing special here!"""
211 """Make a splitter window; left a tree, right a textctrl. Wow."""
213 wx
.Frame
.__init
__(self
, None, -1, "PyTreeItemData Test", size
=(800,500))
214 split
= wx
.SplitterWindow(self
, -1)
215 tree
= pyTree(split
, -1, __main__
)
216 text
= wx
.TextCtrl(split
, -1, "", style
=wx
.TE_MULTILINE
)
217 split
.SplitVertically(tree
, text
, 200)
218 tree
.SetOutput(text
.SetValue
)
219 tree
.SelectItem(tree
.root
)
222 """This class is even less interesting than MyFrame."""
225 """OnInit. Boring, boring, boring!"""
228 self
.SetTopWindow(frame
)