For years now, Andy Tai has done a great job of maintaining the The GUI Toolkit, Framework Page. It's a very extensive list of GUI toolkits and frameworks, both open source and commercial, for a wide variety of languages and platforms. In fact, it's almost too complete. Many of the toolkits listed are no longer developed or became obsolete years ago. So my aim here is to narrow down his huge list to the toolkits and frameworks that are practical, from a developer's perspective, and worth using today.
First and foremost, we have Qt. Many consider it to be the premiere C++ GUI toolkit. That's not surprising, of course. It has a long history of being developed as a commercial product, first by Trolltech and then by Nokia after they acquired Trolltech. Nevertheless, it has also been released under a variety of open source licenses throughout its lifetime. Given its maturity and use in a wide variety of software systems, including KDE, Opera and Google Earth, it has become known as a very reliable, portable, high-performance and high-quality toolkit.
Although Qt is written in C++, a variety of bindings have been developed for other languages. Some of the most notable include QtAda for Ada 2005, PyQt for Python, PHP-Qt for PHP, QtRuby for Ruby and qtHaskell for Haskell. In short, it proves to be a great toolkit, almost regardless of what language or platform you're using.
After Qt, we can consider wxWidgets to be the next most practical GUI toolkit. Like Qt, it is written in C++, is available under an open source license, is extremely portable, and can allow for the development of a professional-grade UI. Also like Qt, there are bindings for a number of popular languages, including wxPython for Python, wxRuby for Ruby, wxHaskell for Haskell, wxPerl for Perl, and even wxErlang for Erlang and wxLua for Lua.
One of the main benefits of wxWidgets over other GUI toolkits is its use of native controls. This allows applications developed using it to integrate nearly seamlessly with the host operating system, even while remaining somewhat portable. So while other toolkits offer themes that try as best as possible to emulate the behavior and appearance of the native platform's UI toolkit, this is often done imperfectly. A perceptive user will know they're not using a native application. But with wxWidgets, we typically don't find this happening.
After wxWidgets, GTK+ can be considered the next most usable toolkit. One difference that it has from Qt and wxWidgets is that it is written in pure C, rather than C++. While this makes language bindings easier to develop, it does have some drawbacks. One such drawback is that it makes extensive use of the GObject object system to provide object-oriented-like functionality for C. This typically feels inferior to using an actual OO language.
While it is portable to other platforms, its origin as an X Window System toolkit can still be felt. Applications using the Windows port of GTK+, for instance, typically don't truly feel like a native Windows app. Nevertheless, the Windows ports of applications like GIMP and Inkscape are usable and reliable. For the best experience, however, it's usually recommended to use GTK+ applications within an environment such as GNOME or Xfce, both of which are built upon it.
Like wxWidgets and Qt, GTK+ also has a wide variety of language bindings. Some of the most widely used include gtkmm for C++, PyGTK for Python, Gtk2-Perl for Perl, Ruby-GNOME2, PHP-GTK for PHP, Gtk2Hs for Haskell, Gtk# for the languages supported by Mono and .NET, and LablGTK for OCaml. Unlike Qt and wxWidgets, which are quite usable for large applications written in their native language (C++), it's probably best to use GTK+ from one of its more mature bindings, such as gtkmm, PyGTK or Gtk#, rather than from straight C.
Swing is relatively old and well-known. Originally Java-centric, it is becoming a more viable option as languages like Scala and Clojure, which target the JVM, become more prevalent. Other language implementations targeting the JVM, like Jython for Python and JRuby for Ruby, make it even more usable. Unfortunately, it does have a number of problems. It has never been known for offering high performance, and is somewhat memory-intensive. Applications written using Swing never truly feel like native applications, even when using a platform-specific theme. The API itself is also quite messy, having accumulated much cruft after a decade. And many developers don't want the extra baggage associated with the Java runtime, which makes it less appealing for those not writing an application specifically for the Java platform.
The FOX Toolkit is likely the most practical toolkit after Qt, wxWidgets, GTK+ and Swing. Like Qt and wxWidgets, it's written in C++. But unlike them, it doesn't offer as much of an accompanying framework. So in many respects it's a much more lightweight toolkit. And unlike some other toolkits, it doesn't (yet) include support for themes, so it has its own unique look and feel that is reminiscent of the traditional Windows look and feel. Nevertheless, it is portable and released under an open source license.
Unlike the aforementioned toolkits, the FOX Toolkit doesn't have as wide of a variety of language bindings. FXRuby for Ruby is a mature and usable binding, but others, like the FXPy binding for Python and the EiffelFox binding for Eiffel, have stagnated. So the FOX Toolkit is probably best used from its native C++ or from Ruby.
FLTK is similar to the FOX Toolkit in many ways. It's also written in C++, is portable, and is more lightweight than toolkits like Qt and wxWidgets. Unfortunately, it doesn't have as many bindings for other languages, and the ones that do exist (like the Ruby wrapper and pyFLTK for Python) aren't updated very frequently. So while FLTK is usable, it probably isn't the best option for more complex applications that are expected to have a long lifespan.
There are many other GUI toolkits out there, both commercial and open source. In terms of cost, portability, usability, user-experience and programming language interoperability, the toolkits mentioned above are typically the best options. Qt is perhaps the most flexible option for writing high-quality, portable GUI applications, followed closely by wxWidgets. GTK+ is good for software running on UNIX-like systems, but doesn't offer as seamless as an experience on other platforms. Swing is typically the choice for those targeting the JVM. And toolkits like FOX Toolkit and FLTK provide alternatives for those who don't want the baggage of the larger and more complete frameworks. While no toolkit is perfect for every piece of software, picking Qt, wxWidgets, GTK+, Swing, FOX Toolkit or FLTK should prove to be a safe, viable, practical and capable choice.