]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/pyTree.py
Change demo to not try to drop the table when it thinks it is creating it for the...
[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
86
87
88 def SetOutput(self, output):
89 """
90 Set output function (accepts single string). Used to display string
91 representation of the selected object by OnSelChanged.
92 """
93 self.output = output
94
95
96 def OnItemExpanding(self,event):
97 """
98 The real workhorse of this class. First we retrieve the object
99 (parent) belonging to the branch that is to be expanded. This
100 is done by calling GetPyData(parent), which is a short-cut for
101 GetPyItemData(parent).Get().
102
103 Then we get the dir() list of that object. For each item in
104 this list, a tree item is created with associated
105 wxTreeItemData referencing the child object. We get this
106 object using child = getattr(parent, item).
107
108 Finally, we check wether the child returns a non-empty dir()
109 list. If so, it is labeled as 'having children', so that it
110 may be expanded. When it actually is expanded, this function
111 will again figure out what the offspring is.
112 """
113 item = event.GetItem()
114 obj = self.GetPyData( item )
115 lst = dir(obj)
116 for key in lst:
117 new_obj = getattr(obj,key)
118 new_item = self.AppendItem( item, key, -1, -1,
119 wx.wxTreeItemData(new_obj) )
120 if dir(new_obj):
121 self.SetItemHasChildren(new_item, wx.TRUE)
122
123 def OnItemCollapsed(self, event):
124 """
125 We need to remove all children here, otherwise we'll see all
126 that old rubbish again after the next expansion.
127 """
128 item = event.GetItem()
129 self.DeleteChildren(item)
130
131 def OnSelChanged(self, event):
132 """
133 If an output function is defined, we try to print some
134 informative, interesting and thought-provoking stuff to it.
135 If it has a __doc__ string, we print it. If it's a function or
136 unbound class method, we attempt to find the python source.
137 """
138 if not self.output:
139 return
140 obj = self.GetPyData( event.GetItem() )
141 msg = str(obj)
142 if hasattr(obj, '__doc__'):
143 msg = msg+"\n\nDocumentation string:\n\n%s" % ( getattr(obj, '__doc__'),)
144 # Is it a function?
145 func = None
146 if hasattr(obj, "func_code"): # normal function
147 func = getattr(obj, "func_code")
148 elif hasattr(obj, "im_func"): # unbound class method
149 func = getattr(getattr(obj, "im_func"), "func_code")
150 if func: # if we found one, let's try to print the source
151 msg = msg+"\n\nFunction source:\n\n" + _sourcefinder(func)
152
153 apply(self.output, (msg,))
154
155#----------------------------------------------------------------------
156
157overview = __doc__
158
159def runTest(frame, nb, log):
160 """
161 This method is used by the wxPython Demo Framework for integrating
162 this demo with the rest.
163 """
96bfd053
RD
164 #thisModule = __import__(__name__, globals())
165 thisModule = sys.modules[__name__]
cf694132
RD
166 win = wx.wxFrame(frame, -1, "PyTreeItemData Test")
167 split = wx.wxSplitterWindow(win, -1)
168 tree = pyTree(split, -1, thisModule)
169 text = wx.wxTextCtrl(split, -1, "", wx.wxDefaultPosition,
170 wx.wxDefaultSize, wx.wxTE_MULTILINE)
171 split.SplitVertically(tree, text, 200)
172 tree.SetOutput(text.SetValue)
173 tree.SelectItem(tree.root)
174 win.SetSize(wx.wxSize(800,500))
175 frame.otherWin = win
176 win.Show(1)
177
178
179
180#----------------------------------------------------------------------
181if __name__ == '__main__':
182
183 class MyFrame(wx.wxFrame):
184 """Very standard Frame class. Nothing special here!"""
185
186 def __init__(self):
187 """Make a splitter window; left a tree, right a textctrl. Wow."""
188 import __main__
189 wx.wxFrame.__init__(self, wx.NULL, -1, "PyTreeItemData Test",
190 wx.wxDefaultPosition, wx.wxSize(800,500))
191 split = wx.wxSplitterWindow(self, -1)
192 tree = pyTree(split, -1, __main__)
193 text = wx.wxTextCtrl(split, -1, "", wx.wxDefaultPosition,
194 wx.wxDefaultSize, wx.wxTE_MULTILINE)
195 split.SplitVertically(tree, text, 200)
196 tree.SetOutput(text.SetValue)
197 tree.SelectItem(tree.root)
198
199 class MyApp(wx.wxApp):
200 """This class is even less interesting than MyFrame."""
201
202 def OnInit(self):
203 """OnInit. Boring, boring, boring!"""
204 frame = MyFrame()
205 frame.Show(wx.TRUE)
206 self.SetTopWindow(frame)
207 return wx.TRUE
208
209 app = MyApp(0)
210 app.MainLoop()
211
212