Thursday, September 24, 2009

Tix and the Tree Widget

So I'm using Tix for my GUI work and have been exploring the wonderful world of Tix with an introduction to the Tix.Tree

It really is quite simple:


tree = Tix.Tree(master, options='seperator "."')
tree.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10, side=Tix.LEFT)

#fill the tree with our values
tree.hlist.add('one', text='one')
tree.hlist.add('two', text='two')
tree.hlist.add('two.three',text='three')
tree.hlist.add('two.four',text='four')


which will give us this:



Great first pass, lets deconstruct the code:

tree = Tix.Tree(master, options='seperator "."')


The first parameter is the parent window just like all the Tk widgets but options has the seperator keyword which is what is used to parse the strings and create the hierarchical style we are looking for. The following lines are self-explanatory; we are merely creating a list of items where the item 'two' has two other children; two.three and two.four

You tell me, "Pretty simple, dude! But what about the rest of the candy?"
How do we define columns and how do you collapse and expand nodes just like we do in all the file explorers?

First question, how do we set up the columns and headers?

The columns and header information gets passed to the Tree control like so:
Tix.Tree(rootWindow, options='hlist.columns 5 hlist.header 1 seperator "."')

To define them properly we need to digress a little and talk about styles;
styles are a Tix construct that allows you to define a tag which you can impose on any widget's text. This can be defined to include the color, font, padding and other display attributes.
tree.tk.call('tix', 'configure', '-fontset', 'WmDefault')
boldfont=tree.tk.call('tix','option','get','bold_font')
style={}
style['header'] = Tix.DisplayStyle(Tix.TEXT,refwindow=tree.hlist, anchor=Tix.CENTER,padx=8,pady=2,font=boldfont)
The first line is to fix the bug with the windows port of Tix, the subsequent lines are the real meat and potatoes of the style mechanism; we create a dictionary of styles, define a header style with a bold font.

Once this is completed we can define our headers to have the 'header' style; like so:
tree.hlist.header_create(0,itemtype=Tix.TEXT, text='Position',style=style['header'])
tree.hlist.header_create(1,itemtype=Tix.TEXT, text='HostName',style=style['header'])


This takes care of the headers,defining the column width is done like so:
tree.hlist.column_width(0, chars=10)
tree.hlist.column_width(1, chars=20)


The last thing we are interested in is the means to collapse and expand the nodes.This is relatively simple in that the individual nodes and can be defined to have that functionality by calling the setmode on the node entry; if that entry has children, the node will be able to be collapsed or expanded. If the setmode command has not been run on a node with children, it will not have the box icon that controls the expansion/collapse mechanism.

tree.setmode(nodeElement, 'open')


So in the end you can get this:

Wednesday, September 23, 2009

Quest for a GUI

This pythonista loves to do GUI work, but what package to use? What features are we looking for and most importantly for me, how easy is it to install and configure on a target machine?

So, I've been using Tcl/TK with Python and find it suits most of my needs for a simple interface but more and more I'm getting to write applications that are more complex than a few simple modal dialog boxes popping up all over the place.

Tix, which is an extension of Tcl/TK for python gives us more variety in terms of widgets, the widgets I'm most interested right now is the hierarchical list and the tree widget.

I took out Tix for a test drive and right out of the box, there are problems but not so insurmountable that they can't be solved. To begin...

I'm developing with python 2.5 (still supports all the 3rd party tools I have come to know and love) and getting Tix 3.4 to work gave me problems on Windows.

I ran the DemoSHList demo and right away it gave me problems.

The line:


boldfont=hlist.tk.call('tix','option','get','bold_font')


was giving me this annoying error:


_tkinter.TclError: can't read "tixOption(bold_font)": no such element in array


what to do, what to do: It seems as if some Tix stuff is broken in windows (The linux side is another matter entirely!!) and to make a long story short, the fonts and colors are not setup properly for the windows environment.

The fix is relatively simple affair to do, just remind Tix exactly what kind of operating system its running. Just place this line before you call what you think is a system-defined constant.


hlist.tk.call('tix', 'configure', '-fontset', 'WmDefault')


This will set it to the its Window defaults. I would imaging this will be fixed in the next installment but in the meantime, adding the above line won't hurt and will just become redundant in the future.

Running the tree sample, which merely enumerates the contents of my disk worked right out of the box with no changes.

I'll be updating all my Tk code to take advantage of Tix.

I'll keep you posted if I find any other issues in the windows side.

The linux side will have to wait for a bit since my entire customer base is windows based and the only person who uses the tool in linux is myself so I can afford to wait a bit.