Recipe 11.10. Using IDLE's Tree Widget in Tkinter
Credit: Sanghyeon Seo
Problem
You need to use a Tree widget in
your Tkinter application, and you know that such a widget comes with
IDLE, the Integrated Development Environment that comes with
Python.
Solution
IDLE's functionality is
available in the Python Standard Library in package
idlelib, so it is easy to import and use in your
applications. The Tree widget is in
idlelib.TreeWidget. Here, as an example, is how to
use that widget to display an XML document's DOM as
a tree:
from Tkinter import Tk, Canvas
from xml.dom.minidom import parseString
from idlelib.TreeWidget import TreeItem, TreeNode
class DomTreeItem(TreeItem):
def _ _init_ _(self, node):
self.node = node
def GetText(self):
node = self.node
if node.nodeType == node.ELEMENT_NODE:
return node.nodeName
elif node.nodeType == node.TEXT_NODE:
return node.nodeValue
def IsExpandable(self):
node = self.node
return node.hasChildNodes( )
def GetSubList(self):
parent = self.node
children = parent.childNodes
prelist = [DomTreeItem(node) for node in children]
itemlist = [item for item in prelist if item.GetText( ).strip( )]
return itemlist
if _ _name_ _ == '_ _main_ _':
example_data = '''
<A>
<B>
<C>d</C>
<C>e</C>
</B>
<B>
<C>f</C>
</B>
</A>
'''
root = Tk( )
canvas = Canvas(root)
canvas.config(bg='white')
canvas.pack( )
dom = parseString(data)
item = DomTreeItem(dom.documentElement)
node = TreeNode(canvas, None, item)
node.update( )
node.expand( )
root.mainloop( )
Discussion
My applications needed Tree widgets, and Tkinter does not have such a
widget among its built-in ones. So I started looking around the
Internet to see the Tree widgets that had been implemented for
Tkinter. After a while, I was pleasantly surprised to learn that
quite a useful one was already installed and working on my computer!
Specifically, I had IDLE, the free Integrated DeveLopment Environment
that comes with Python, and therefore I had
idlelib, the package within the standard Python
library that contains just about all of the functionality of IDLE. A
Tree widget is among the widgets that IDLE uses for its own GUI, so
idlelib.TreeWidget is just sitting there in the
standard Python library, quite usable and useful.The only problem with idlelib is that it is not
well documented as a part of the Python Standard Library
documentation, nor elsewhere. The best documentation I could find is
the pydoc-generated one at http://pydoc.org/2.3/idlelibl.
treeWidget is one of the modules documented there.
I suggest reading the sources on your disk, which include the
docstrings that pydoc is using to build the useful
documentation site. Between sources and pydoc, it
is quite possible to reuse some of the rich functionality
that's included in idlelib,
although having real docs about it would
definitely not hurt. Python is known as the language that comes
"with batteries included." When you
consider, not just the hundreds of library modules that are fully
documented in Python's official docs, but also the
many additional library modules that aren't (such as
those in idlelib), it's hard to
deny this characterization.
This
recipe shows how to implement a simple GUI Tree: define a node-item
class by subclassing idlelib.TreeWidget.TreeItem,
and override some methods. You may want to override ten methods
(http://pydoc.org/2.3/idlelib.TreeWidgetl#TreeItem
has the complete list), and this recipe only needs three:
GetText to define how the item is displayed
(textually), IsExpandable to tell the Tree whether
to put a clickable + character next to the node to
allow expansion, GetSubList to return a list of
children items in case expansion is required. Other optional methods,
which this recipe does not need, allow iconic rather than textual
display, double-clicking on nodes, and even editing of Tree
items.
See Also
idlelib docs at http://pydoc.org/2.3/idlelibl.