Version 21 of User Interface Design for Tcl/Tk

Updated 2005-05-01 16:42:48

EKB created this page as a place to discuss user interface design using Tcl/Tk and to give examples.

After some feedback (see below), I changed some of the text on the page.

The intended focus is on GUI design with Tk (but this is a Wiki, so that might change). It's meant to compliment Tk coding styles and philosophies by focusing on the user experience. I'm thinking it might be useful for people in the same predicament as me: While I may be used to command-line interfaces and a Motif look, my users aren't. Feedback from users indicates that they expect the program to respond more like their other MacOS/Windows/Gnome/... programs. For me, and I think for many programmers, this means focusing on interface details.

This page is not meant to be a style guide and especially not a style straitjacket. Instead, it's meant to be a place to share ideas and hold discussions.


EKB I've found Joel Spolsky's User Interface Design for Programmers [L1 ] to be very useful. The site includes text from his book of the same title. A pair of concepts from this source that I like to keep in mind are:

  • A UI is well designed when the computer model matches the user model.
  • The user model is very simple.

The idea of "user model" means that a user approaches a program interface with some idea of what to expect based on a description of the program or its appearnace. They have a "model" of the program, in that if they do one thing they expect the program to do another. Users tend to be happy if their model matches what the program will do and frustrated otherwise. This is true even if what the program does is reasonable, but different from what the user exepcts. The computer also has a model of the software, expressed in code, that corresponds exactly to what the program will do. The user will have a better experience (and the programmer have happier users) if they are in agreement.

A further idea from Spolsky's book that I found useful is on what to do if the computer model is complicated by nature. In these cases the UI can provide metaphors (actually similes, but "metaphor" is the term of choice) and affordances. A metaphor is a representation of something already familiar to the user (a "desktop", a "spreadsheet", a "file system"), but is only similar enough to the actual item to orient users, not to recreate the item itself. An affordance is something that suggests how it should be used (e.g., buttons, entry widgets, tabbed dialogs, the little ridged "gripper" at the bottom right of windows in Windows).

For a sometimes amusing look at awkward interfaces, see the User Interface Hall of Shame [L2 ]. (The site itself is no longer active - this is an archived copy.)


EKB One problem that I face is that while it's easy to make a UI in Tcl/Tk, it is also easy to make poor user interfaces in Tcl/Tk. (By "poor" I mean that it is frustrating for the user or that it looks or feels awkward because it differs from what the users expect from a "professional" program. What these expectations are depends on the audience.)

My audience tends to consist of people with technical backgrounds but not programming backgrounds. From the point of view of interface design, that means they're pretty much like the average computer user, but perhaps a bit more forgiving. (Is this similar to what other Tcler's Wiki readers have to answer to?)

Based on user feedback and comparing my "1st cut" interfaces to interfaces in other programs my users might be familiar with, here are some things that I've had to work on to make my programs more usable. I see this in other programs, too, mainly because these things are easy to do in the first flush of enthusiasm when making a Tcl/Tk interface. I'm trying to move toward a development style where I anticipate the recurring problems rather than always respond to user feedback.

  • Inconsistent button sizes
  • No padding/inconsistent padding, so things looked "crushed"
  • Inconsistent tab order
  • GUI elements don't line up (e.g., entry widgets jump all over the place)
  • Unclear wording (Specifically, writing from the programmer's point of view rather than the user's point of view.)
  • Unrelated items are grouped close together/Related items are separated
  • The program overrides the system settings
  • Poor support for keyboard alternatives to GUI elements

Another issue is internationalization. For myself, I need to design my interfaces for internationalization. I think Tcl/Tk has a lot to offer in this regard. Interfaces written in other languages don't resize very nicely when their content changes. It's much easier in Tcl/Tk to have things resize properly (buttons, labels, etc.) when the language changes, but it doesn't look nice (in my experience) without some work.


Here's an example to show some of these things. Suppose I want to make a simple prompt/entry interface with a several prompts and entries. For example, suppose I want to get name, phone and address. I'm not going to worry about what I'll do with the information or how I'll gather it, but focus on the GUI instead (I'd probably have an array to hold the entries and assign the array elements using -textvar.)

Here's a simple approach that's easy to do with Tcl/Tk. I've made things like this for my own consumption:

 label .nl -text "Name:"
 entry .ne
 label .pl -text "Phone:"
 entry .pe
 label .al -text "Address:"
 entry .ae1
 entry .ae2
 entry .ae3

 pack .nl -side top
 pack .ne -side top
 pack .pl -side top
 pack .pe -side top
 pack .al -side top
 pack .ae1 -side top
 pack .ae2 -side top
 pack .ae3 -side top

The result looks like this:

http://www.kb-creative.net/screenshots/ex1.gif

It is already useful as an interface (except it's missing any buttons to either commit the changes or cancel), but is not a standard-looking interface, so most people using it (including me) have to think a moment before figuring out what to do and how to do it.

One way to improve the interface is to put the entries and labels in separate frames:

 frame .n
 label .n.l -text "Name:"
 entry .n.e
 pack .n.l -side left
 pack .n.e
 frame .p
 label .p.l -text "Phone:"
 entry .p.e
 pack .p.l -side left
 pack .p.e
 frame .a1
 label .a1.l -text "Address:"
 entry .a1.e
 pack .a1.l -side left
 pack .a1.e
 frame .a2
 label .a2.l -text "Address 2 (optional):"
 entry .a2.e
 pack .a2.l -side left
 pack .a2.e
 frame .a3
 label .a3.l -text "City, State, ZIP, Country"
 entry .a3.e
 pack .a3.l -side left
 pack .a3.e

 pack .n -side top
 pack .p -side top
 pack .a1 -side top
 pack .a2 -side top
 pack .a3 -side top

Here's what it looks like:

http://www.kb-creative.net/screenshots/ex2.gif

It is more clear now where and what the user is supposed to type, but the labels aren't aligned and the entry widgets are ragged. As far as I know there are two ways to deal with this:

  • Assign a width to the labels
  • Put the labels and entries into parallel frames, rather than each label and entry in its own frame

The first solution is problematic if the application is to be internationalized, because in some languages the labels may overflow the label size (or they may be really small). The second option is better in this case, but it can have problems because the entries and labels can get out of alignment if they use different fonts.

Here's the code for the second approach:

 frame .left
 frame .right

 label .left.nl -text "Name:"
 entry .right.ne
 label .left.pl -text "Phone:"
 entry .right.pe
 label .left.a1l -text "Address:"
 entry .right.a1e
 label .left.a2l -text "Address 2 (optional):"
 entry .right.a2e
 label .left.a3l -text "City, State, ZIP, Country"
 entry .right.a3e

 pack .left.nl -side top
 pack .left.pl -side top
 pack .left.a1l -side top
 pack .left.a2l -side top
 pack .left.a3l -side top
 pack .right.ne -side top
 pack .right.pe -side top
 pack .right.a1e -side top
 pack .right.a2e -side top
 pack .right.a3e -side top

 pack .left -side left
 pack .right

Here's the result:

http://www.kb-creative.net/screenshots/ex3.gif

This is better in that things are lined up, but the centered labels are non-standard. Generally, people either put them all flush left or flush right. For this example, I'll make them flush right using the "anchor" option for the pack command:

 frame .left
 frame .right

 label .left.nl -text "Name:"
 entry .right.ne
 label .left.pl -text "Phone:"
 entry .right.pe
 label .left.a1l -text "Address:"
 entry .right.a1e
 label .left.a2l -text "Address 2 (optional):"
 entry .right.a2e
 label .left.a3l -text "City, State, ZIP, Country:"
 entry .right.a3e

 pack .left.nl -side top -anchor e
 pack .left.pl -side top -anchor e
 pack .left.a1l -side top -anchor e
 pack .left.a2l -side top -anchor e
 pack .left.a3l -side top -anchor e
 pack .right.ne -side top
 pack .right.pe -side top
 pack .right.a1e -side top
 pack .right.a2e -side top
 pack .right.a3e -side top

 pack .left -side left
 pack .right

Here's how it looks:

http://www.kb-creative.net/screenshots/ex4.gif

This is much better, although it could certainly be improved. But there's an even bigger problem. If I drag the window edges, I get this:

http://www.kb-creative.net/screenshots/ex4_dragged.gif

This is sub-optimal. I do want the user to be able to drag the window, but it should behave better:

  • Everything should still line up
  • The entry widgets should expand to give the user more room (probably what he/she wanted)

There is no reason to allow the window to resize downward, but I'm going to allow the user to resize it just in case. The widgets will remain anchored to the top.

I get these effects by anchoring the two frames (.left and .right) to the top of the main window and setting the entry widgets to -fill x. I also set the .right frame to -fill x and -expand:

 frame .left
 frame .right

 label .left.nl -text "Name:"
 entry .right.ne
 label .left.pl -text "Phone:"
 entry .right.pe
 label .left.a1l -text "Address:"
 entry .right.a1e
 label .left.a2l -text "Address 2 (optional):"
 entry .right.a2e
 label .left.a3l -text "City, State, ZIP, Country:"
 entry .right.a3e

 pack .left.nl -side top -anchor e
 pack .left.pl -side top -anchor e
 pack .left.a1l -side top -anchor e
 pack .left.a2l -side top -anchor e
 pack .left.a3l -side top -anchor e
 pack .right.ne -side top -fill x
 pack .right.pe -side top -fill x
 pack .right.a1e -side top -fill x
 pack .right.a2e -side top -fill x
 pack .right.a3e -side top -fill x

 pack .left -side left -anchor n
 pack .right -side right -anchor n -fill x -expand yes

Now when the window is dragged it behaves much better:

http://www.kb-creative.net/screenshots/ex5_dragged.gif

Aside from the facts that it's still missing buttons so the user can do anything with this information (like store it, print it, use it to mail something, etc.) and that it doesn't apply in all countries, the interface is looking and behaving better.

I'll make two last changes -- I'll make the phone number entry a fixed width, give a default width to the other entry widgets and add a little "breathing space" around the widgets using padx, pady:

 frame .left
 frame .right

 label .left.nl -text "Name:"
 entry .right.ne -width 30
 label .left.pl -text "Phone:"
 entry .right.pe -width 15
 label .left.a1l -text "Address:"
 entry .right.a1e -width 30
 label .left.a2l -text "Address 2 (optional):"
 entry .right.a2e -width 30
 label .left.a3l -text "City, State, ZIP, Country:"
 entry .right.a3e -width 30

 pack .left.nl -side top -anchor e
 pack .left.pl -side top -anchor e
 pack .left.a1l -side top -anchor e
 pack .left.a2l -side top -anchor e
 pack .left.a3l -side top -anchor e
 pack .right.ne -side top -fill x
 pack .right.pe -side top -anchor w
 pack .right.a1e -side top -fill x
 pack .right.a2e -side top -fill x
 pack .right.a3e -side top -fill x

 pack .left -side left -anchor n -padx 6 -pady 6
 pack .right -side right -anchor n -fill x -expand yes -padx 6 -pady 6

Here's how it looks:

http://www.kb-creative.net/screenshots/ex6.gif

There are many other things that could be done from this point, such as:

  • Clearly separate the address block from the rest
  • Add buttons (typically in the bottom right, but the order of the buttons -- cancel, save, close, etc. -- depends on the OS)
  • Automate the widget creation by putting the repetitive code into procs

Also, it could be tested with a real user. I've done this a few times and it's somewhat painful, but useful. The idea is to show the application to someone and then sit silently while they try to use it. It's best if they say their thought process aloud while they're doing it, while the programmer takes notes.



The exchange that led me to edit the page follows:


TV Well I'm sure the 2 points about the models are in line with my Electrical Engineering masters' thesis, wherein what I wrote made sense, but what is this 'User model' ?

The error list sounds pretty much like rubbish to me, who cares about shrinking buttons compared to the freedom to at least make a window smaller when one wants, to, who sais all people want padding, who decides on what is 'inconsistent', why is lining up required, maybe those articles in a newspaper layout look fine with people for instance, why are so many people interested in Linux, where historically al lot of communication takes place with very short commands and messages, which fits on one screen easier, what's wrong with a program choosing it's own distinctive settings, and why would it be an error to have not keyboard shortcuts, it sounds more like an omission. Internationalisation and such sound less important than some UI that works at least and does something usefull instead of acting as a style council implemented.

There are very strong courses and books at top computer engineering level about OS'es (Lets say Tanenbaum or something), less strong but profound enough material about 'datastructures and algoritms', very good and scientifically relevant book about Computer Graphics (I'm and expert in the field and I made commercial very up to standard and more 'normal' GUI's already in the time of the Atari ST) both 2D and 3D, but is seems to me general UI courses are doomed to either be like the windows certification moloch, a redo or simply ripping of of principles of let's say what the macIntosh computer seems to preach to us (which usually is quite bearable), or hopefully something uplifting about nice principles, interaction times, resolution considerations (most well designed user interfaces look bad and work like crap on a high resolution screen like a 1600x1200 one I prefer, which however makes not for good general use contemporary screendumps on web pages), or an interesting vision, or maybe some fun stuff.

Like the 'Global Scenario Group' appears to me as a 30 year late ridiculous New Age (with all the adverse purposes) redo of the original and relevant 'group of rome', I'd say its not a very supreme idea to make something like a highschool course with rules about the schoolnewspaper layout without proper knowledge about why for example the campbell soup style from Warhole looks like it looks in the adds in it.


EKB 30 April 2005 --

Hi, TV, maybe I shouldn't have called them "errors," there's probably a better term. But the basic ideas I put forward seem sensible to me. (Just to be clear, they're not ones I've come up with, but rather ones I've gleaned from other people's writing on interface design.)

The basic message is that the design of the interface should be consistent with the expectations of the users. The program interface should not get in the way of what users want to do. Also, the user's expectation for how the program will behave is usually (not always) less complex than what a programmer might think, so it takes some work on the part of the programmer to make a really nice interface.

But I shouldn't try to lay down hard and fast "rules," that's true -- program goals and users' expectations are much more flexible than that. I guess I came off sounding pedantic ("something like a highschool course with rules about the schoolnewspaper layout") which isn't at all what I wanted -- I wanted a place where people could discuss what "good looking Tcl/Tk" might look like in the context of user interface design in general. Also, I'm not at all an expert in user interface design. I'm just trying bit by bit to make my programs accessible to a larger audience. It seems to me from conversations on the Wiki that others are trying to do the same thing. I thought maybe we could share ideas here. (I've changed the page to hopefully make it less annoyingly pedantic.)

Some specific responses:

"who cares about shrinking buttons compared to the freedom to at least make a window smaller when one wants, to" -- These aren't incompatible. You can make consistently-sized buttons that don't look crammed onto the page and still allow dynamic resizing of the window. But I'll admit that what looks "crammed" to me may look just fine to others.

"who decides on what is 'inconsistent'" -- Agreed, this is tricky. Partly it is convention. (E.g., there seems to be some complaint about the "Motif" look of Tcl/Tk. This wasn't a problem for me, because it was the convention at the time and I and others were used to it. But it isn't the convention any more, and my main focus is on a trouble-free user experience. Maybe a boring goal, but it lets the user focus on the program's functionality rather than the quirks in its design.) Partly it is based on how quickly users new to an interface element can learn how it works (e.g., tabbed dialogs vs. trees).

"what's wrong with a program choosing it's own distinctive settings" -- Because without a really good reason, it seems to needlessly interfere with the users' choices.

"why would it be an error to have not keyboard shortcuts, it sounds more like an omission" -- Agreed, it's an omission. But if a user of my program is frustrated because a common shortcut isn't available, then I feel like that's my responsibility.

"why are so many people interested in Linux, where historically al lot of communication takes place with very short commands and messages, which fits on one screen easier" -- Unix/Linux has a great user interface. The command-line interfaces in the various shells are some of the most successful around. But they still appeal to only a relatively small number of people. I imagine that many folk visiting this Wiki have to consider a larger range of users than a command-line interface would appeal to. Since many of us (me included) are quite happy with command-line interfaces (and Wikis), it takes some work for us to figure out what will feel most comfortable to a majority of our users.

"Internationalisation and such sound less important than some UI that works at least and does something usefull instead of acting as a style council implemented." -- I've certainly made UI's that "work at least and do something useful," but I find that in the field they need modification to make them most useful to the actual users. The focus of effective design is on the user's experience and expectations. Internationalization might or might not be important, depending on who might want to use the program. BTW, one reason to focus on this with Tcl/Tk is that it seems to me a much better option than some alternatives. Automatic resizing of widgets can make it relatively easy to make a GUI that looks good in a variety of languages, no matter how the lengths of strings change.

"with rules about the schoolnewspaper layout without proper knowledge about why for example the campbell soup style from Warhole looks like it looks in the adds in it" -- Personally, I want to keep my art appreciation separate from my (rather pedestrian) interface design. Most interface design isn't art, although some is. It's just trying to help users get their jobs done.

"windows certification moloch" -- Yikes! I definitely don't want to do that. Windows has done a lot of user testing, but they've only tested what they've thought of, and only tested it in the way they chose to test it. I'm more interested in user reactions and preferences. You're right, though, what I've put down so far does seem to lead to such a cookbook approach. That's not good.

"hopefully something uplifting about nice principles, interaction times, resolution considerations (most well designed user interfaces look bad and work like crap on a high resolution screen like a 1600x1200 one I prefer, which however makes not for good general use contemporary screendumps on web pages), or an interesting vision, or maybe some fun stuff." -- Great! As indicated at the start of the page, I'd be open to having this page go in a very different direction from what I first put one it. Fun stuff sounds good to me.

Regarding your flame about the Global Scenario Group, was that in reference to my home page? Thanks for looking at it. But I am not a member of the GSG -- I did technical work for them. I had no editorial control on what they produced. I agree with some of it and disagree with others, sometimes strongly. (I also have agreements and sometimes strong disagreements with the Club of Rome work as well.) I'd be happy to discuss this with you, but this seems like the wrong venue for such a discussion. Feel free to contact me directly if you want to discuss this (non Tcl/Tk) part of my work ([email protected]).

To everyone, I still think this might be a useful page. Any other thoughts?

Lars H: This lengthy discussion is skewing it a bit, but the basic idea is good. One thing I think could be useful is if there also were some code examples (and screen dumps) to back up the various "rules" given above, for example the one about incorrect alignment: how does one make sure things align? These examples are probably best put on separate pages and only referenced here, but linking theory and example is a useful didactic technique.

EKB Thanks, Lars! I've added an example.


Category Design