ObjectBrowser.py 4.04 KB
Newer Older
David Scherer's avatar
David Scherer committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
# XXX TO DO:
# - popup menu
# - support partial or total redisplay
# - more doc strings
# - tooltips

# object browser

# XXX TO DO:
# - for classes/modules, add "open source" to object browser

from TreeWidget import TreeItem, TreeNode, ScrolledCanvas

from repr import Repr

myrepr = Repr()
myrepr.maxstring = 100
myrepr.maxother = 100

class ObjectTreeItem(TreeItem):
    def __init__(self, labeltext, object, setfunction=None):
        self.labeltext = labeltext
        self.object = object
        self.setfunction = setfunction
    def GetLabelText(self):
        return self.labeltext
    def GetText(self):
        return myrepr.repr(self.object)
    def GetIconName(self):
        if not self.IsExpandable():
            return "python"
    def IsEditable(self):
        return self.setfunction is not None
    def SetText(self, text):
        try:
            value = eval(text)
            self.setfunction(value)
        except:
            pass
        else:
            self.object = value
    def IsExpandable(self):
        return not not dir(self.object)
    def GetSubList(self):
        keys = dir(self.object)
        sublist = []
        for key in keys:
            try:
                value = getattr(self.object, key)
            except AttributeError:
                continue
            item = make_objecttreeitem(
                str(key) + " =",
                value,
                lambda value, key=key, object=self.object:
                    setattr(object, key, value))
            sublist.append(item)
        return sublist

class InstanceTreeItem(ObjectTreeItem):
    def IsExpandable(self):
        return 1
    def GetSubList(self):
        sublist = ObjectTreeItem.GetSubList(self)
        sublist.insert(0,
            make_objecttreeitem("__class__ =", self.object.__class__))
        return sublist

class ClassTreeItem(ObjectTreeItem):
    def IsExpandable(self):
        return 1
    def GetSubList(self):
        sublist = ObjectTreeItem.GetSubList(self)
        if len(self.object.__bases__) == 1:
            item = make_objecttreeitem("__bases__[0] =",
                self.object.__bases__[0])
        else:
            item = make_objecttreeitem("__bases__ =", self.object.__bases__)
        sublist.insert(0, item)
        return sublist

class AtomicObjectTreeItem(ObjectTreeItem):
    def IsExpandable(self):
        return 0

class SequenceTreeItem(ObjectTreeItem):
    def IsExpandable(self):
        return len(self.object) > 0
    def keys(self):
        return range(len(self.object))
    def GetSubList(self):
        sublist = []
        for key in self.keys():
            try:
                value = self.object[key]
            except KeyError:
                continue
            def setfunction(value, key=key, object=self.object):
                object[key] = value
            item = make_objecttreeitem(`key` + ":", value, setfunction)
            sublist.append(item)
        return sublist

class DictTreeItem(SequenceTreeItem):
    def keys(self):
        keys = self.object.keys()
        try:
            keys.sort()
        except:
            pass
        return keys

from types import *

dispatch = {
    IntType: AtomicObjectTreeItem,
    LongType: AtomicObjectTreeItem,
    FloatType: AtomicObjectTreeItem,
    StringType: AtomicObjectTreeItem,
    TupleType: SequenceTreeItem,
    ListType: SequenceTreeItem,
    DictType: DictTreeItem,
    InstanceType: InstanceTreeItem,
    ClassType: ClassTreeItem,
}

def make_objecttreeitem(labeltext, object, setfunction=None):
    t = type(object)
    if dispatch.has_key(t):
        c = dispatch[t]
    else:
        c = ObjectTreeItem
    return c(labeltext, object, setfunction)

# Test script

137
def _test():
David Scherer's avatar
David Scherer committed
138
    import sys
139 140
    from Tkinter import Tk
    root = Tk()
David Scherer's avatar
David Scherer committed
141 142 143 144 145 146
    root.configure(bd=0, bg="yellow")
    root.focus_set()
    sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1)
    sc.frame.pack(expand=1, fill="both")
    item = make_objecttreeitem("sys", sys)
    node = TreeNode(sc.canvas, None, item)
147 148
    node.update()
    root.mainloop()
David Scherer's avatar
David Scherer committed
149 150

if __name__ == '__main__':
151
    _test()