I’m not sure what it means when you’re surprised when a GUI toolkit actually works. I suspect it means that you’ve been using TK too long.

A couple weeks ago, I decided that one of my little projects at work needed a better UI then print statements could reasonably provide; I was generating a huge amount of log-like data, and it was getting hard to pick important lines out of the chaff. I started by throwing a curses wrapper around the ruby script that does the actual work, and then separating the logs into three panes on the screen. It worked, but it was impossible to scroll back when things went off the screen, and curses isn’t exactly noted for its ease of use.

So, I tried TK. Again. I keep dragging it out every couple years and hoping that somehow, this years incarnation in this year’s scripting language doesn’t suck as bad as it did last time. I think I can officially say now that TK sucks no matter when or where you try to use it. I write more detail later, but a specific source of suckage in ruby is the near-total lack of english-language documentation. Most suggestions say “look at the perl docs, it’s mostly like that.” The Ruby TK bindings do weird things with threads, and my poor little app kept coredumping. I wanted to do a couple non-standard things with text windows, and I couldn’t find docs on anything even slightly related online. So, once again, I dumped TK.

The current hot GUI toolkit for ruby is Fox, but the current version isn’t in Debian, so I decided to give Ruby’s GTK bindings a try. Of course, it wasn’t available for Ruby 1.8 in sid either, but at least GTK itself was, and (amazingly enough), it was trivial to build. And it worked. I was stunned.

Here’s an example–suppose you want to build a text box with horizontal and vertical scroll bars. In TK it’s easy–just create a text field, then a horizontal scroll bar, and then a vertical scroll bar, then tie them together, then put them into a grid layout thingy and tweak it so that it doesn’t try to shove one scrollbar or the other into the bottom corner. Piece of cake, if you don’t mind typing 10 lines of code and remembering how the grid layout engine works. Got GTK in Ruby, it looks more like this:

    win=Gtk::TextView.new
    scroll=Gtk::ScrolledWindow.new
    scroll.add(win)

That’s it; from here on, you can deal with ‘scroll’ when it comes to layout; it encapsulates ‘win’ so that you never need to worry about it again. Gtk::ScrolledWindow automatically attaches the scrollbars to whatever you shove inside it. If you only want horizontal or vertical scrollbars, there are simple method calls for that. All in all, it just works. If you want to use ‘win’ for displaying text, but don’t want the user to enter text, then call ‘win.editable=false’. Line wrapping, margins, and pretty much everything else is similar. Callbacks largely work as you’d expect in ruby, via anonymous code blocks and yield.

Plus, best of all, there’s documentation. It’s not perfect, or even 100% complete, but it was good enough for me to be able to churn out a non-trival application (dynamically-created tabs, multiple frames, multhreading, collapsing tree widgets, etc) in about a day and a half. Since I’m not really a GUI person, that seems entirely reasonable.

This is the fourth GUI toolkit that I’ve used enough to churn out a small application. I started with Windows somewhere around the time of 2.1 or so (back when Excel came with a free copy of Windows :-), before MSFC or .NET or whatever they’re using these days. ‘Hello World’ was around 30 lines of code. Enough said. After that, I used Motif a bit. It was better, but still painful, and it ate a horrific amount of memory for 1994 or so. I used TCL/TK briefly in 1996 or so; it was a lot easier to code in, but TK is so limited, and it’s difficult to get it to do things that it doesn’t want to do. GTK seems a lot better; it’s clearly a full-sized GUI toolkit, but it’s easy to write small stuff in it. It’s flexible enough–one thing I needed for this ap was “sticky” text windows, where they’d auto-scroll to the bottom when I inserted new text if they were at the bottom before I inserted anything. That took about 5 lines of code, most of which is if/then logic. It only actually took two GTK calls to figure out if I was at the bottom, and 1 call to move the scrollbar.

I may have finally found a GUI I can live with. Amazing. It only took 15 years.