]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/pyTree.py
corrected assert even better
[wxWidgets.git] / wxPython / demo / pyTree.py
CommitLineData
cf694132
RD
1"""
2Hello, and welcome to this test of the wxTreeItemData
3class.
4
5The wxTreeItemData class can be used to associate a python
6object with a wxTreeCtrl item. In this sample, its use is
7demonstrated via a tree control that shows the contents of a
8python namespace according to the standard dir()
9command. Every item in the tree has its label taken from the
10dir() output, and 'behind it' a reference to the python
11object is stored in a wxTreeItemData object.
12
13As you may have guessed by now, this sample automatically
14displays '__doc__' strings if the selected python object
15happens to have one. Please expand the pyTree object to
16learn more about the implementation.
17
18Version 1.0, April 4 1999.
19Harm van der Heijden (H.v.d.Heijden@phys.tue.nl)
20
21P.S. Check out the string module. It's imported in this
22sample not because it's used, but because it's so
23beautifully documented...
24"""
25
26from wxPython import wx
96bfd053 27import sys, string # Don't use it, but it's fun expanding :-)
cf694132
RD
28
29#----------------------------------------------------------------------
30
31def _getindent(line):
32 """Returns the indentation level of the given line."""
33 indent = 0
34 for c in line:
35 if c == ' ': indent = indent + 1
36 elif c == '\t': indent = indent + 8
37 else: break
38 return indent
39
40def _sourcefinder(func):
41 """Given a func_code object, this function tries to find and return
42 the python source code of the function."""
43 try:
44 f = open(func.co_filename,"r")
45 except:
46 return "(could not open file %s)" % (func.co_filename,)
47
48 for i in range(func.co_firstlineno):
49 line = f.readline()
50 ind = _getindent(line)
51 msg = ""
52 while line:
53 msg = msg + line
54 line = f.readline()
55 # the following should be <= ind, but then we get
56 # confused by multiline docstrings. Using == works most of
57 # the time... but not always!
58 if _getindent(line) == ind: break
59 return msg
60
61#----------------------------------------------------------------------
62
63class pyTree(wx.wxTreeCtrl):
64 """
65 This wxTreeCtrl derivative displays a tree view of a Python namespace.
66 Anything from which the dir() command returns a non-empty list is a branch
67 in this tree.
68 """
69
70 def __init__(self, parent, id, root):
71 """
72 Initialize function; because we insert branches into the tree
73 as needed, we use the ITEM_EXPANDING event handler. The
74 ITEM_COLLAPSED handler removes the stuff afterwards. The
75 SEL_CHANGED handler attempts to display interesting
76 information about the selected object.
77 """
78 wx.wxTreeCtrl.__init__(self, parent, id)
79 self.root = self.AddRoot(str(root), -1, -1, wx.wxTreeItemData(root))
80 if dir(root):
81 self.SetItemHasChildren(self.root, wx.TRUE)
82 wx.EVT_TREE_ITEM_EXPANDING(self, self.GetId(), self.OnItemExpanding)
83 wx.EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed)
84 wx.EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
85 self.output = None
493f1553 86 self.Expand(self.root)
cf694132
RD
87
88
89 def SetOutput(self, output):
90 """
91 Set output function (accepts single string). Used to display string
92 representation of the selected object by OnSelChanged.
93 """
94 self.output = output
95
96
97 def OnItemExpanding(self,event):
98 """
99 The real workhorse of this class. First we retrieve the object
100 (parent) belonging to the branch that is to be expanded. This
101 is done by calling GetPyData(parent), which is a short-cut for
102 GetPyItemData(parent).Get().
103
104 Then we get the dir() list of that object. For each item in
105 this list, a tree item is created with associated
106 wxTreeItemData referencing the child object. We get this
107 object using child = getattr(parent, item).
108
109 Finally, we check wether the child returns a non-empty dir()
110 list. If so, it is labeled as 'having children', so that it
111 may be expanded. When it actually is expanded, this function
112 will again figure out what the offspring is.
113 """
114 item = event.GetItem()
493f1553
RD
115 if self.IsExpanded(item): # This event can happen twice in the self.Expand call
116 return
cf694132
RD
117 obj = self.GetPyData( item )
118 lst = dir(obj)
119 for key in lst:
120 new_obj = getattr(obj,key)
121 new_item = self.AppendItem( item, key, -1, -1,
122 wx.wxTreeItemData(new_obj) )
123 if dir(new_obj):
124 self.SetItemHasChildren(new_item, wx.TRUE)
125
126 def OnItemCollapsed(self, event):
127 """
128 We need to remove all children here, otherwise we'll see all
129 that old rubbish again after the next expansion.
130 """
131 item = event.GetItem()
132 self.DeleteChildren(item)
133
134 def OnSelChanged(self, event):
135 """
136 If an output function is defined, we try to print some
137 informative, interesting and thought-provoking stuff to it.
138 If it has a __doc__ string, we print it. If it's a function or
139 unbound class method, we attempt to find the python source.
140 """
141 if not self.output:
142 return
143 obj = self.GetPyData( event.GetItem() )
144 msg = str(obj)
145 if hasattr(obj, '__doc__'):
146 msg = msg+"\n\nDocumentation string:\n\n%s" % ( getattr(obj, '__doc__'),)
147 # Is it a function?
148 func = None
149 if hasattr(obj, "func_code"): # normal function
150 func = getattr(obj, "func_code")
151 elif hasattr(obj, "im_func"): # unbound class method
152 func = getattr(getattr(obj, "im_func"), "func_code")
153 if func: # if we found one, let's try to print the source
154 msg = msg+"\n\nFunction source:\n\n" + _sourcefinder(func)
155
156 apply(self.output, (msg,))
157
158#----------------------------------------------------------------------
159
160overview = __doc__
161
162def runTest(frame, nb, log):
163 """
164 This method is used by the wxPython Demo Framework for integrating
165 this demo with the rest.
166 """
96bfd053
RD
167 #thisModule = __import__(__name__, globals())
168 thisModule = sys.modules[__name__]
cf694132
RD
169 win = wx.wxFrame(frame, -1, "PyTreeItemData Test")
170 split = wx.wxSplitterWindow(win, -1)
171 tree = pyTree(split, -1, thisModule)
172 text = wx.wxTextCtrl(split, -1, "", wx.wxDefaultPosition,
173 wx.wxDefaultSize, wx.wxTE_MULTILINE)
174 split.SplitVertically(tree, text, 200)
175 tree.SetOutput(text.SetValue)
176 tree.SelectItem(tree.root)
177 win.SetSize(wx.wxSize(800,500))
178 frame.otherWin = win
179 win.Show(1)
180
181
182
183#----------------------------------------------------------------------
184if __name__ == '__main__':
185
186 class MyFrame(wx.wxFrame):
187 """Very standard Frame class. Nothing special here!"""
188
189 def __init__(self):
190 """Make a splitter window; left a tree, right a textctrl. Wow."""
191 import __main__
493f1553 192 wx.wxFrame.__init__(self, None, -1, "PyTreeItemData Test",
cf694132
RD
193 wx.wxDefaultPosition, wx.wxSize(800,500))
194 split = wx.wxSplitterWindow(self, -1)
195 tree = pyTree(split, -1, __main__)
196 text = wx.wxTextCtrl(split, -1, "", wx.wxDefaultPosition,
197 wx.wxDefaultSize, wx.wxTE_MULTILINE)
198 split.SplitVertically(tree, text, 200)
199 tree.SetOutput(text.SetValue)
200 tree.SelectItem(tree.root)
201
202 class MyApp(wx.wxApp):
203 """This class is even less interesting than MyFrame."""
204
205 def OnInit(self):
206 """OnInit. Boring, boring, boring!"""
207 frame = MyFrame()
208 frame.Show(wx.TRUE)
209 self.SetTopWindow(frame)
210 return wx.TRUE
211
212 app = MyApp(0)
213 app.MainLoop()
214
215