~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to wxPython/demo/pyTree.py

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
Hello, and welcome to this test of the wxTreeItemData
 
3
class.
 
4
 
 
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.
 
12
 
 
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.
 
17
 
 
18
Version 1.0, April 4 1999.
 
19
Harm van der Heijden (H.v.d.Heijden@phys.tue.nl)
 
20
 
 
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...
 
24
"""
 
25
 
 
26
import  string  # Used for demo purposes, nothing more. :-)
 
27
import  sys
 
28
 
 
29
import  wx
 
30
 
 
31
#----------------------------------------------------------------------
 
32
 
 
33
def _getindent(line):
 
34
    """Returns the indentation level of the given line."""
 
35
    indent = 0
 
36
    for c in line:
 
37
        if c == ' ': indent = indent + 1
 
38
        elif c == '\t': indent = indent + 8
 
39
        else: break
 
40
    return indent
 
41
 
 
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."""
 
45
    try:
 
46
        f = open(func.co_filename,"r")
 
47
    except:
 
48
        return "(could not open file %s)" % (func.co_filename,)
 
49
 
 
50
    for i in range(func.co_firstlineno):
 
51
        line = f.readline()
 
52
 
 
53
    ind = _getindent(line)
 
54
    msg = ""
 
55
 
 
56
    while line:
 
57
        msg = msg + line
 
58
        line = f.readline()
 
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
 
63
 
 
64
    return msg
 
65
 
 
66
#----------------------------------------------------------------------
 
67
 
 
68
class pyTree(wx.TreeCtrl):
 
69
    """
 
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
 
72
    in this tree.
 
73
    """
 
74
 
 
75
    def __init__(self, parent, id, root):
 
76
        """
 
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.
 
82
        """
 
83
        wx.TreeCtrl.__init__(self, parent, id)
 
84
        self.root = self.AddRoot(str(root), -1, -1, wx.TreeItemData(root))
 
85
 
 
86
        if dir(root):
 
87
            self.SetItemHasChildren(self.root, True)
 
88
 
 
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())
 
92
 
 
93
        self.output = None
 
94
        self.Expand(self.root)
 
95
 
 
96
 
 
97
    def SetOutput(self, output):
 
98
        """
 
99
        Set output function (accepts single string). Used to display string
 
100
        representation of the selected object by OnSelChanged.
 
101
        """
 
102
        self.output = output
 
103
 
 
104
 
 
105
    def OnItemExpanding(self,event):
 
106
        """
 
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().
 
111
 
 
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).
 
116
 
 
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.
 
121
        """
 
122
        item = event.GetItem()
 
123
 
 
124
        if self.IsExpanded(item):  # This event can happen twice in the self.Expand call
 
125
            return
 
126
            
 
127
        obj = self.GetPyData( item )
 
128
        lst = dir(obj)
 
129
 
 
130
        for key in lst:
 
131
            new_obj = getattr(obj,key)
 
132
            new_item = self.AppendItem( item, key, -1, -1,
 
133
                                        wx.TreeItemData(new_obj) )
 
134
 
 
135
            if dir(new_obj):
 
136
                self.SetItemHasChildren(new_item, True)
 
137
 
 
138
    def OnItemCollapsed(self, event):
 
139
        """
 
140
        We need to remove all children here, otherwise we'll see all
 
141
        that old rubbish again after the next expansion.
 
142
        """
 
143
        item = event.GetItem()
 
144
        self.DeleteChildren(item)
 
145
 
 
146
    def OnSelChanged(self, event):
 
147
        """
 
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.
 
152
        """
 
153
        if not self.output:
 
154
            return
 
155
 
 
156
        obj = self.GetPyData( event.GetItem() )
 
157
        msg = str(obj)
 
158
 
 
159
        if hasattr(obj, '__doc__'):
 
160
            msg = msg+"\n\nDocumentation string:\n\n%s" % ( getattr(obj, '__doc__'),)
 
161
 
 
162
        # Is it a function?
 
163
        func = None
 
164
 
 
165
        if hasattr(obj, "func_code"): # normal function
 
166
            func = getattr(obj, "func_code")
 
167
 
 
168
        elif hasattr(obj, "im_func"): # unbound class method
 
169
            func = getattr(getattr(obj, "im_func"), "func_code")
 
170
 
 
171
        if func: # if we found one, let's try to print the source
 
172
            msg = msg+"\n\nFunction source:\n\n" + _sourcefinder(func)
 
173
 
 
174
        apply(self.output, (msg,))
 
175
 
 
176
#----------------------------------------------------------------------
 
177
 
 
178
overview = __doc__
 
179
 
 
180
def runTest(frame, nb, log):
 
181
    """
 
182
    This method is used by the wxPython Demo Framework for integrating
 
183
    this demo with the rest.
 
184
    """
 
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))
 
194
    frame.otherWin = win
 
195
    win.Show(1)
 
196
 
 
197
 
 
198
 
 
199
#----------------------------------------------------------------------
 
200
if __name__ == '__main__':
 
201
 
 
202
    class MyFrame(wx.Frame):
 
203
        """Very standard Frame class. Nothing special here!"""
 
204
 
 
205
        def __init__(self):
 
206
            """Make a splitter window; left a tree, right a textctrl. Wow."""
 
207
            import __main__
 
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)
 
215
 
 
216
    class MyApp(wx.App):
 
217
        """This class is even less interesting than MyFrame."""
 
218
 
 
219
        def OnInit(self):
 
220
            """OnInit. Boring, boring, boring!"""
 
221
            frame = MyFrame()
 
222
            frame.Show(True)
 
223
            self.SetTopWindow(frame)
 
224
            return True
 
225
 
 
226
    app = MyApp(False)
 
227
    app.MainLoop()
 
228
 
 
229