Articles / GUI Toolkits for The X Wind…

GUI Toolkits for The X Window System

This article is aimed at Unix developers who already have some experience with programming languages and want to start developing GUI applications (mainly for The X Window System, though portability is discussed). It may also come in handy if you have used a particular GUI toolkit for some time and want to know whether others might suit your needs better. The main focus is comparison and introduction, but it serves as a bit of tutorial, as well.

Why Do We Need Toolkits?

There are two significant answers to this question:

  1. The Xlib API is hard to use because...
    • ... its function calls bloat the code and limit readability.
      (By the way, did you know that the function prototypes are still K&R style? Ugh!)
    • ... the color handling is awful.
      (Now you know why most applications that come with X are 1 bit colored.)
  2. Portability. It must be pure hell to port Xlib code to Microsoft Windows or the Linux DirectFB.

Possible reasons for not choosing a toolkit are easily refuted. We'll take a look at three of them:

  1. Money: All of the toolkits mentioned here can be used free of charge (Qt only for non-commercial applications, though). Even if they couldn't, the time saved would make up for the initial cost.
  2. Performance: I was unsure myself whether the use of a toolkit would yield a performance penalty, and therefore collected some information regarding this issue. My research shows that the overhead caused by the additional far jumps (read: function calls) is negligible for all but the most critical applications (at least with GTK's drawing library, GDK; see "Timing analysis of Xlib and GDK"). Even there, I don't think that this is a problem with today's CPUs and graphics cards.
  3. Flexibility: One could say that we're giving up flexibility by not using the most primitive functions. Most toolkits just remove the fuss of dealing with Xlib; I can't think of any case in which Xlib would give the programmer more freedom than a toolkit does. And if you pay attention to the fact that most toolkits are organized in an object-oriented fashion, which also means (multiple) inheritance, you will see that this argument certifies Xlib as a disadvantage instead of an advantage.

Synopsis

Below, I offer a guide to various toolkits for POSIX-based systems which can be used free of charge: GTK+/gtkmm, Trolltech Qt, FOX Toolkit, FLTK, and wxWindows. It will start with some general information about the concepts of GUI programming, so beginners will have a better chance of understanding the code examples I provide. All toolkits will mainly be examined in terms of maturity (which means stability), popularity (which popular applications/how many applications use this toolkit?), accessibility and internationalization support, portability, language bindings, extensibility, licensing conditions, and documentation. The core of each toolkit's information is written in continuous English sentences, but a spotlight on the specific properties follows each section.

Please note that I won't cover Motif/Lesstif in this article because it is similar to Xlib in terms of age and complexity. Tcl/Tk isn't much better. If you feel a specific toolkit should be mentioned here, drop me an email.

Terminology

Widget:
From Eric S. Raymond's "Jargon File":

"[...] [poss. evoking 'window gadget'] A user interface object in X graphical user interfaces."

So what exactly is a widget by example? A button you can click on, a value slider you can slide around, a window, checkboxes, radio buttons... The term "widget" is used with most toolkits (also on Win32) nowadays as a generic name for these objects.

Main Loop, GUI Loop, Main Event Loop:
Most, if not all GUI toolkits, be they in C or C++, have this. The main loop waits for user input and controls various other things (depending on the toolkit).
Event:
An event is something coming from the outside, maybe a resize event sent by the operating system so the application can take actions to rearrange its graphical interface elements. An event can also be induced by the user, e.g., a mouse click. (This last is X terminology. I think that on Win32, "event" does not refer to user actions.)
Callback:
A callback can be an ordinary C function or a C++ member function if the GUI system supports functors. Callbacks are often used to handle user input; a click on a button may call the callback function on_button_click(widget* w, int but_num).
Signal/Slot:
These two belong together and can be used for communication between objects: Object A sends a specific signal which is caught by object B because the latter has a slot for it. A slot is a callback for a signal.
Dynamic Layout:
Think of a user resizing the window. When the coordinates of a widget are fixed X/Y pixel coordinates (Xlib, Win32 native API), the widgets will resize not at all, incorrectly, or only with a lot of code overhead. Dynamic layout is achieved by using logical objects instead of coordinates.
Rapid Application Development (RAD):
RAD describes techniques that aid the programmer in a way that enables him to concentrate on the core of the application he is writing. Most important RAD tools are GUI builders which offer a point-and-click interface for tasks like widget placement or callback definitions. RAD tools also include, for example, makefile generators.

The Toolkits Themselves

[GTK+ Logo] GTK+ and gtkmm

"GTK" is the abbreviation for "The GIMP Toolkit", which was originally developed for the popular 2D graphics application "The GIMP" (for more information on the history of GTK+, see The GTK+ FAQ, sections 1.2ff). Since then, it has evolved into a large collaborative project. The current major version of GTK+ is 2, and it introduces (in comparison with the old 1.2 series) some new and enhanced widgets, better internationalized input support, speed improvements, and a lot of API changes, along with all the resulting incompatibilities. GTK+ itself is written in pure C using an object-oriented approach, special types, and casts. There is, however, a C++ wrapper library called "gtkmm" (formerly GTK--), which reacts very quickly to changes in the underlying GTK+ code and offers developers a very good C++ API. The fact that there exists a plain C API and numerous language bindings attracts a lot of developers and is responsible for the toolkit's great popularity. gtkmm adds C++'s syntactical sugar and built-in object-orientation features. Thanks to its well-defined interface, very structured and clean programming is possible.

GTK+ 2 supports Unicode natively; translation is not integrated and must be done with GNU gettext or another tool or technique of your choice. Some important things are not present in the GTK+ distribution, such as support for OpenGL. This is a design decision by the GTK+/gtkmm development teams, resulting in a very modular approach, so that you have, in this example, the choice between GtkGLArea, a widget that serves as a GL viewport (beware: the homepage is dead, the current version doesn't compile), and GtkGLExt and its C++ wrapper gtkglextmm, which integrates seamlessly with gtkmm. (The gtkglext packages provide the ability to use OpenGL code on any widget.) The same is true for network functionality, document/view, and many other features.

Overview of GTK+
Full Name GTK+ -- GIMP Toolkit
Web site http://www.gtk.org/
Programming Language C / C++ with gtkmm
Language Bindings (AKA wrappers) Many, see the official list
License GNU LGPL
Portability Win32, DirectFB, BeOS
Themable Yes (GTK+ themes @ freshmeat)
RAD Yes (mainly with Glade; some others available)
Documentation Comprehensive reference (most of the time behind the current API, though), tutorials
Extensibility GTK+: with plain C OOP; gtkmm: standard C++ inheritance
Strengths & Features
  • Internationalization features: many input methods available, right-to-left support, Unicode strings
  • gtkmm: objects live in well-defined namespaces
  • gtkmm: well-defined, clean, and modular API
  • Markup support with font rendering
Weaknesses
  • Win32 port unstable
Notes
  • Uses GNU gettext for translations

[Trolltech Qt Logo] Trolltech Qt

Qt is the next big GUI package I'd like to discuss here. In terms of size and functionality, it is probably next to GTK+. The popular major versions of Qt are 2 and 3, and both are written in C++ with the addition of a precompiler pass involving a special program from Trolltech, the "Meta Object Compiler", or "MOC". It meddles with Trolltech's C++ extensions (such as arbitrary class information like name and author or signal/slot capabilities for each class), things that C++, RTTI, and gtkmm with its libsigc++ provide. The problem with Qt is that it was written with early C++ compilers in mind which didn't offer the capabilities Trolltech needed for their GUI toolkit, and today, one has to work with the slack. There is also another precompiler called "User Interface Compiler", or "UIC". It must be invoked if you use the integrated RAD environment QtDesigner. QtDesigner saves its files in XML format; UIC converts them to C++ source. These additional build steps can, of course, be integrated into the project's Makefile (there are examples of how to do this in Qt's manual), so I don't think of it as a negative thing. Documentation in HTML format and man pages comes with the Qt source tree, and a PDF version is available for download. There is also an application for browsing the documentation ("QtAssistant"). Unfortunately, I couldn't get it to work... No matter, my browser does just as well (though without a global search feature).

Before I continue discussing the technical aspects of Qt, I will discuss the license issues that caused a lot of disturbance and uncertainty in the Open Source community. What you get when you download Qt 2/3 is the free X11 version ("Qt Free Edition") which enables you to write non-commercial applications for The X Window System. When you want to create commercial, proprietary, or non-free software, or want to compile your program for Windows or embedded systems, you'll have to pay for the Qt Professional or Enterprise version (both are quite expensive). Qt tried to specify this in their own license (the "QPL") because they felt the GPL could cause them some problems (please see freshmeat article #180 for more information). From Qt 2.2 and upwards, you can now freely choose between the QPL and GPL before building the libraries. That's the whole story; if you feel I missed an important point, feel free to correct me (Qt flames go straight to /dev/null, though). You can read more about Trolltech's licensing issues in freshmeat articles #170, #172, and the one mentioned above.

Back to tech. Along with QtDesigner and QtAssistant, Trolltech bundles even more useful applications with the Qt package: There is QtLinguist for easy editing of translation packages, qembed, a tool to convert many different sorts of data to embedded C code, and qmake, a portable Make utility with special support for Qt. QtDesigner offers, in addition to its basic functionality, wizards to help you get started. Widgets and predefined dialogs have, by default, a look very similar to Microsoft Windows. It is fully themable, though, so at least the colors can be changed. The internationalization capabilities are quite excellent. There is the tool mentioned above (QtLinguist), support for argument strings (think of printf() without the disadvantages), and Unicode support. A string class and various other convenient STL stuff is also included, so you don't have to use STL in your project.

I feel that Qt's weaknesses lie not in its technical aspect, but in Trolltech's general attitude towards the end user. Trolltech says they wanted to create, among other things, a free toolkit for developers of Free Software. They succeeded, and Qt-X11 is a very good product used by many applications, the most prominent being KDE. But when you look at their Web site, you'll see a lot of business talk and praises reminding me of a market place. And what if you want to port your program to Windows? No problem if you have $1,550; for this price, you get the professional version of Qt. The Macintosh and Embedded versions are free, though. I can't help it, but the real Free Software community feeling doesn't well up on my side. This should not stop you from choosing Qt if it fits your needs, though; it is a toolkit like the others presented here, with its own strengths and weaknesses. I'll get back to Qt and "fitting your needs" in the summary.

Overview of Qt
Full Name Trolltech Qt
Web site http://www.trolltech.com/
Programming Language C++ with special pre-compilers ("MOC", "UIC")
Language Bindings (AKA wrappers) Perl, PHP, Python
License Trolltech QPL or GNU GPL at your will
Portability Win32, MacOS, Embedded Devices, Linux Framebuffer
Themable Yes
RAD Yes (Bundled Qt Designer)
Documentation Comprehensive reference, tutorials
Extensibility Plug-In interface for some base widget types
Strengths & Features
  • Integrated internationalization and translation features and programs to help with internationalization
  • Many helpful tools bundled
  • RAD tool offers nice wizards
  • Many advanced widgets bundled
Weaknesses
  • Very business-oriented main Web site
  • Main branch depending on one company
  • Commercial developers and people wanting portability have to pay
  • Huge sources and binaries, library itself takes ages to compile
  • Objects not referred by namespace but simple literal prefix "Q"
Notes
  • Slow FTP server
  • Needs special precompiler pass ("MOC", "UIC" with RAD)
  • Dominant Microsoft Windows look

[FLTK Logo] Fast, Light Tool Kit (FLTK)

FLTK is the C++ successor to the XForms library (which is written in plain C), so I won't cover the latter here. XForms is not Free Software and is free of charge only for non-commercial use. FLTK's strength lies, as its name suggests, in its size and speed. The abstract base class for widgets is 60 bytes, and a statically linked and stripped "hello world" is ~80kb. FLTK code is carefully organized and offers the linker a lot of opportunities to leave unused code out. The basic widget types have many variants, some of which are quite innovative and beautiful. FLTK's main loop (which waits for and processes user events) is non-blocking; FLTK must be instructed explicitly to wait for events. While FLTK lacks precomposed dialogs, it offers a very optimized and direct interface to OpenGL, and a compatibility header file for GLUT is included. In my opinion, this is a very good base for getting started with 3D programming. The toolkit is also, in general terms, very friendly to beginners, and is easily understood.

One thing you have to get used to is the quite unique (yes, that word again; FLTK has some things not found in the other toolkits) method of getting and setting widget attributes. You may be used to things like Object::set_attribute() and Object::get_attribute(). The approach used by FLTK is to leave out the "get_"/"set_", and just write Object::attribute() and act according to the context. If the attribute accessor function is called in a context implying a void return type, the "set" function is called. When a return value is demanded, the "get" function, which is declared constant, is executed. This has positive and negative sides; you have to type less when dealing with attributes, but the code is (arguably) less readable.

FLTK doesn't have to hide when it comes to RAD, either. Its RAD tool, "FLUID", containing every widget the FLTK library supports, is a mere ~350kb statically linked, outputs C++ code, and is, like the rest of the FLTK library, efficient and not overloaded.

It should be noted that FLTK's internationalization capabilities are limited. While it supports composition of accented characters, it uses ordinary char arrays for string handling. Capabilities beyond that depend on the underlying operating system or external libraries (which may, of course, be a positive thing if speed and size do matter to you). It must be stated, therefore, that FLTK programs are quite easily (with the help of GNU gettext) internationalized for a certain bunch of languages. When it gets to things like right-to-left input or characters requiring Unicode, it gets complicated.

Still, I couldn't find any real weaknesses. FLTK does an excellent job of meeting its design goals. It's fast, light, flexible, and easy to use.

Overview of FLTK
Full Name FLTK -- Fast, Light Toolkit
Web site http://www.fltk.org/
Programming Language C++
Language Bindings (AKA wrappers) Lua, Perl, Python
License GNU LGPL
Portability Win32
Themable Yes
RAD Yes ("FLUID")
Documentation Comprehensive reference, tutorials
Extensibility Standard C++ inheritance
Strengths & Features
  • Very small memory footprint, throughly optimized
  • Programming is very straightforward
  • Direct OpenGL support; portable GLUT header file
  • Main loop non-blocking
Weaknesses
  • Widgets not referred by namespace but simple literal prefix "Fl_"; functions and enums are, though
Notes
  • Internationalization issues not handled by FLTK; depends on OS
  • Uses return type overloading for differentiation of get/set methods.

[wxWindows Logo] wxWindows

wxWindows is a giant among GUI toolkits. The documentation section reflects the size and functionality of the whole toolkit quite well, and it's not small. It is a very well-designed toolkit with portability and features in mind. In the number of language bindings, it is only surpassed by GTK+, its RAD tools are innumerable, and there's even an OS/2 port. The wxWindows team is especially proud that its toolkit is one of the most advanced and mature ones. They're right; its history starts in 1992. Despite these facts, it is not very well known. That might change in the near future, as wxPython (for example) is getting more and more happy developers, and wxWindows developers are zealous when it comes to GUI toolkits.

The core of wxWindows is rock solid. Only 10% of its functions are non-portable OS-specific drawing functions, and so it claims to be a kind of "written once, running anywhere" toolkit, like FOX. There's also a version that sits atop GTK+, so it can be seen as an addition and simplification of the toolkit level GTK+ is on. With this in mind, one can see that wxWindows adds many convenient features. A built-in configuration file API saves a lot of work that most applications require, and the same goes for printing support. Resource files in XML format ensure optimum portability, and the integrated HTML class makes reports, text formatting, and a help viewer a piece of cake. Its position among the other toolkits is discussed in the summary.

Overview of wxWindows
Full Name wxWindows -- Cross-platform GUI library
Web site http://www.wxwindows.org/
Programming Language C++
Language Bindings (AKA wrappers) BASIC, Eiffel, Java, Javascript, Lua, Perl, Python
License wxWindows License (GNU GPL compatible)
Portability Win32, MacOS, OS/2, Embedded Devices
Themable No
RAD Yes, many tools available; for example with wxPython: Boa Constructor
Documentation Very comprehensive
Extensibility Standard C++ inheritance
Strengths & Features
  • Very advanced, mature, and portable
  • Uses native widgets if possible, provides fallbacks if not
  • Supports XML resource files
  • Built-in configuration manager
  • Built-in printing support (generates Postscript on X)
  • Integrated OpenGL, HTML, Networking
Weaknesses
  • Some things done with macros
  • Not themable
  • Not exception-safe
  • Objects not referred by namespace but simple literal prefix "wx"
Notes  

[Fox-Toolkit Logo] FOX Toolkit

The FOX toolkit is, in terms of features and portability, probably next to wxWindows, but it introduces some interesting concepts and occasionally obscures things which could be straightforward. For example, it requires you to call the FX_DECLARE macro in the declaration of a class derived from an FX object. This may result in less typing, but also in less clarity, and exchanging clarity for brevity is something I'm not very fond of. Or take the message ID handling: The documentation tells the developer to use an enum and fiddle around with FOX's private message IDs. That hurts me, and I think to myself, "Why don't they provide a class for this? Why does someone write a library in C++ if he misses some of the fundamental concepts of the language, like data encapsulation?"

Enough ranting. After all, FOX has some really fine features to offer! For example, its messaging system: All FOX objects can send messages to each other and receive all kinds of events. Message forwarding is also possible, and automatic updating of GUI elements according to specified conditions in the application. What FOX does here is basically take the functionality of gtkmm's libsigc++ and add a lot of predefined stuff to it. This may be complicated, but is also very convenient. Easy incorporation of outside events (like incoming data via a pipe or signals) is also possible with FOX. Data targets provide an excellent interface between data and widgets, again taking tedious chores away from you. Last but not least, FOX comes with its own regular expression class, which might come in handy. All in all, FOX can be a very powerful, comfortable, and portable toolkit once you get used to its syntax (and do better OO than the documentation's examples).

Overview of FOX Toolkit
Full Name FOX Toolkit
Web site http://www.fox-toolkit.org/
Programming Language C++
Language Bindings (AKA wrappers) Eiffel, Python, Ruby
License GNU LGPL
Portability Win32, Mac (with OS X + XFree or Apple X Server)
Themable No
RAD Work in progress
Documentation Comprehensive, but structured like a collection of HOWTOs; Doxygen-style reference docs would be great (note: there is a link to an unofficial "Class Index" page, but it was dead when I visited the site)
Extensibility Standard C++ inheritance
Strengths & Features
  • Sophisticated target/message system
  • Built-in regular expression support "FXRex"
  • Built-in configuration manager
  • Direct OpenGL support
Weaknesses
  • API at times quite hackish and immature (macros)
  • Objects not referred by namespace but simple literal prefix "FX"
Notes  


Summary

All of the toolkits mentioned have quality reference documentation with tutorials and a comprehensive hyperlinked API reference. All of them have wrappers for other languages, with C++ still the most structured and fastest of all (though scripting languages are easier to program with). Speaking of C++, all the toolkits but gtkmm neglect the fact that C++ has a very useful feature called "namespaces". Instead of using namespaces, they add a prefix to their functions and classes. A good feature they all have is dynamic layout; none of them relies on pure Cartesian pixel coordinates, although it is possible to arrange widgets with them in this way. Two toolkits, wxWindows and FOX, rely on preprocessor macros for critical calls. This is a bad habit because type safety is thrown away. GTK+ uses macros, too, but it uses them almost exclusively for safe type casting and enhances type safety in this way, instead of losing it.

For a short summary and comparison of the toolkits, I'll start with FLTK because of its unique position: It is the only toolkit discussed here which offers amazingly small and fast applications while still keeping a lot of useful widgets at the programmer's disposal. It is ideal for projects that need to be small and/or fast and programmers who like clean and straightforward interfaces. If you want to have a solid base and good internationalization or just want to program in plain C (ugh!), GTK+ is the all-around choice. gtkmm offers even more, and it has the cleanest and most structured API I've ever seen, but if you want extra functionality (OpenGL, for example), you'll have to rely on external libraries. If you're not an API purist, you can choose among the three huge toolkits, FOX, Qt, and wxWindows. I personally think Qt is made irrelevant by both of the others because they are not missing anything Qt offers. The tools that come with Qt may not be bundled with them, but comparable tools do exist and can be used free of charge, and most often as Free Software. Qt's biggest weaknesses are its relic called "MOC" and its business orientation. Yes, it's GPL, but not for MS Windows, so you're not really free. FOX and (especially) wxWindows offer similarly advanced sets of widgets and techniques, so you might as well throw Qt away. In terms of portability, it's the same, and wxWindows even adds OS/2 portability. Believe me, I don't want to be unfair to Trolltech or upset dedicated Qt developers. I tried to be objective, and that's my objective conclusion. Maybe we can discuss this point in the comments for this article.

Recent comments

23 Jun 2006 09:47 Avatar codemedic

Tabular Comparison
I would love it if someone could update this atricle with a tabular summary, including various criteria that affects performance and portability. It will be great if a glossary can be included as well (for the criteria, example: blocking or non-blocking main loop - what does that mean). Including the glossary will be particularly helpful for newbie developers who are stepping into the free world.

Other things like language compatibility, language feature utilisation, learning curve, etc will be really helpful.

11 May 2006 06:47 Avatar bugmenot

Re: Many thanx!!!


> Many thanx!!! Very useful article!!!

Same thoughts. But it will be so much greater if it's updated.

02 Feb 2006 19:53 Avatar Tonyy

Many thanx!!!
Many thanx!!! Very useful article!!!

03 Jul 2005 00:18 Avatar billposer

tcl/tk


I can't agree with the statement that tk is at the same level of complexity and abstraction as xlib. Tk is MUCH simpler and higher level than xlib. I'm probably in an almost ideal position to judge. At one time I did a great deal of programming in raw xlib. For about ten years I then did next to no graphics programming. What little I did was updating old xlib code. A couple of years ago I returned to doing graphics programing and decided to try tcl/tk. I have since written several fairly complex programs in tcl/tk. I've also done a couple of minor projects using tkinter with python.

I was simply stunned with how much easier and faster it is to write in tcl/tk than in C/xlib. Some of that is of course due to tcl being much higher level than C, but it is also true that it took me a while to get used to tcl and that I was already very familiar with C when I was using raw xlib, so I don't think that that is the major factor. Tk takes care of all sorts of details that you have to deal with in xlib.

Let me also make a comment on tcl since some people have said that it has a weird and inconsistent syntax. I don't agree. The problem at first, for experienced programmers, is that tcl has an unfamiliar
syntax, one that is simpler than that of most other languages. Ironically, the syntax is probably more of a problem for experienced programmers than for novices; we're more set in our ways. Tcl syntax is actually rather like that of lisp. Indeed, the thing that bothers me most about Tcl syntax now that I'm familiar with it is the way comments are handled, which limits where you can put them. That's also a problem with many versions of lisp, though for a different reason.

04 Dec 2004 12:01 Avatar sid007

In regards to . . .
I would say flexibility is the biggest advantage and as a programmer sid (http://www.shroff.us), Xlib allows more freedom and flexibility.

Screenshot

Project Spotlight

Kigo Video Converter Ultimate for Mac

A tool for converting and editing videos.

Screenshot

Project Spotlight

Kid3

An efficient tagger for MP3, Ogg/Vorbis, and FLAC files.