In the interests of making it easier for people to understand the workings of Dragonfly, the following code can be used to open a window showing either node or element trees in a collapsible Tree control.
Disclaimer: the code is as rough as guts.
import Tkinter
import sys
sys.path.append('C:/Python26/Lib/site-packages/TkinterTreectrl-1.0')
Tkinter.wantobjects=0#necessary for tk-8.5 and some buggy tkinter installs
from Tkinter import *
from TkTreectrl import *
import os
import sys
def openTreeOnNode(node, windowTitle):
root = Tk()
root.title(windowTitle)
t = Treectrl(root, showrootbutton=1)
t.pack(fill=BOTH, expand=1)
# create a column and define it as the widget's treecolumn
col = t.column_create(text="Node tree", expand=1)
t.configure(treecolumn=col)
#col = t.column_create(text="Col 2", expand=1)
#t.configure(treecolumn=col)
# create the elements of which a tree item will consist; use the treectrl's per-state option mechanism
# to assign different options for different states where necessary
#folder = PhotoImage(file=os.path.join(sys.path[0], 'folder.gif'))
#openfolder = PhotoImage(file=os.path.join(sys.path[0], 'openfolder.gif'))
el_text = t.element_create(type=TEXT, fill=('white', SELECTED))
el_select = t.element_create(type=RECT, showfocus=1, fill=('blue4', SELECTED))
# put the elements together to make a style
st_folder = t.style_create()
t.style_elements(st_folder, el_select, el_text)
# layout options for look'n'feel:
t.style_layout(st_folder, el_text, padx=8, pady=2)
t.style_layout(st_folder, el_select, union=(el_text,), ipadx=2, iexpand=NS)
class NodeDict:
def __init__(self):
self.nodeDict = {}
self.idv=1
def addNode(self, node):
self.nodeDict[str(self.idv)]=node
self.idv = self.idv + 1
return str(self.idv-1)
def getNode(self, idStr):
return self.nodeDict[idStr]
def buildElements(el): # parent node id
print "el id: ", el
print el
nId = t.itemelement_cget(el, col, el_text, 'data') # parent node
n=D.getNode(nId)
print "node id: ", nId
for c in n.children: # child nodes
node_id = D.addNode(c)
if c.children:
new = t.create_item(parent=el, button=1, open=0)
else:
new = t.create_item(parent=el, button=0, open=0)
t.itemstyle_set(new, col, st_folder)
txt = str(c)+ " B: " + str(c.begin) + " E: " + str(c.end)
print txt
t.itemelement_config(new, col, el_text, text=txt , datatype=STRING, data=node_id)
buildElements(new)
def buildElementsText(el, ilevel):
nId = t.itemelement_cget(el, col, el_text, 'data') # parent node
n=D.getNode(nId)
print(' ' * (ilevel * 4), str(n))
for c in n.children: # child nodes
node_id = D.addNode(c)
if c.children:
new = t.create_item(parent=el, button=1, open=0)
else:
new = t.create_item(parent=el, button=0, open=0)
t.itemstyle_set(new, col, st_folder)
t.itemelement_config(new, col, el_text, text=str(c), datatype=STRING, data=node_id)
buildElementsText(new, ilevel+1)
# set up the root item
t.itemstyle_set(ROOT, col, st_folder)
t.itemelement_config(ROOT, col, el_text, text=str(node), datatype=STRING, data='1')
t.item_config(ROOT, button=1)
D = NodeDict()
D.addNode(node)
#buildElementsText( ROOT, 0 )
# the root item is expanded by default but doesn't have any children yet, so we need to
# generate an <Expand-before> event to fill the root-directory
buildElements( ROOT )
t.see(ROOT)
t.item_expand(ALL)
root.mainloop()
##################################################################
def openTreeOnElement(node, windowTitle):
root = Tk()
root.title(windowTitle)
t = Treectrl(root, showrootbutton=1)
t.pack(fill=BOTH, expand=1)
# create a column and define it as the widget's treecolumn
col = t.column_create(text="Node tree", expand=1)
t.configure(treecolumn=col)
#col = t.column_create(text="Col 2", expand=1)
#t.configure(treecolumn=col)
# create the elements of which a tree item will consist; use the treectrl's per-state option mechanism
# to assign different options for different states where neccessary
#folder = PhotoImage(file=os.path.join(sys.path[0], 'folder.gif'))
#openfolder = PhotoImage(file=os.path.join(sys.path[0], 'openfolder.gif'))
el_text = t.element_create(type=TEXT, fill=('white', SELECTED))
el_select = t.element_create(type=RECT, showfocus=1, fill=('blue4', SELECTED))
# put the elements together to make a style
st_folder = t.style_create()
t.style_elements(st_folder, el_select, el_text)
# layout options for look'n'feel:
t.style_layout(st_folder, el_text, padx=8, pady=2)
t.style_layout(st_folder, el_select, union=(el_text,), ipadx=2, iexpand=NS)
class NodeDict:
def __init__(self):
self.nodeDict = {}
self.idv=1
def addNode(self, node):
self.nodeDict[str(self.idv)]=node
self.idv = self.idv + 1
return str(self.idv-1)
def getNode(self, idStr):
return self.nodeDict[idStr]
class ChildrenWrapper:
def __init__(self, obj):
self.obj = obj
def children(self):
if self.obj.__class__.__name__ == "RuleRef":
print 'ruleref'
if hasattr(self.obj, "rule"):
if hasattr(self.obj, "children"):
if not len(self.obj.children):
return (self.obj.rule,)
elif hasattr(self.obj, "children"):
return self.obj.children
elif hasattr(self.obj, "elements"):
return self.obj.elements
elif hasattr(self.obj, "element"):
return (self.obj.element,)
else:
return []
def buildElements(el): # parent node id
print "el id: ", el
print el
nId = t.itemelement_cget(el, col, el_text, 'data') # parent node
n=D.getNode(nId)
print "node id: ", nId
N = ChildrenWrapper(n)
for c in N.children(): # child nodes
node_id = D.addNode(c)
C = ChildrenWrapper(c)
if C.children():
new = t.create_item(parent=el, button=1, open=0)
else:
new = t.create_item(parent=el, button=0, open=0)
t.itemstyle_set(new, col, st_folder)
t.itemelement_config(new, col, el_text, text=str(c), datatype=STRING, data=node_id)
buildElements(new)
# set up the root item
t.itemstyle_set(ROOT, col, st_folder)
t.itemelement_config(ROOT, col, el_text, text=str(node), datatype=STRING, data='1')
t.item_config(ROOT, button=1)
D = NodeDict()
D.addNode(node)
#buildElementsText( ROOT, 0 )
# the root item is expanded by default but doesn't have any children yet, so we need to
# generate an <Expand-before> event to fill the root-directory
buildElements( ROOT )
t.see(ROOT)
t.item_expand(ALL)
root.mainloop()