Code to visualise Dragonfly parse trees in GUI

66 views
Skip to first unread message

Jason Veldicott

unread,
Feb 24, 2012, 4:03:31 AM2/24/12
to dragonf...@googlegroups.com
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. 

It requires TKinterTreectrl at http://tktreectrl.sourceforge.net/.

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()

Jason Veldicott

unread,
Feb 24, 2012, 5:57:44 AM2/24/12
to dragonf...@googlegroups.com

Screenshot: 


Reply all
Reply to author
Forward
0 new messages