Maybe it's just familiarity, or I'm out of touch since it's been a few years since I was really evaluating the options, but I find GTK much nicer to work with than Qt. It seems to do better with language bindings too. GTK being a C API seems to make it a lot easier to auto-generate bindings for any language with an FFI. Qt, being both primarily a C++ API, and also with the custom preprocessor and signal/slot nonsense seems like it's much harder to make sensible bindings for.
> GTK being a C API seems to make it a lot easier to auto-generate bindings for any language with an FFI.
Not only that but as outlined in that article, GObject introspection allows easy integration with most popular dynamic languages (most importantly JS and Python) without the need for specific bindings.
QT python bindings were rather confusing with multiple libraries and basically very poor documentation when I checked a couple of years ago.
Not to mention QTs java binding also was not a good story.
This hasn't been the case for a few years. PyQt has been excellent from the beginning of Qt5, and as of 2018 or so the Qt for Python binding is also in very good shape.
I code cross-platform in C++ or Python primarily, so maybe that's why Qt is such a good fit. All the frequent version incompatibilities of Gtk3 just made me not really look into it any further.
Python + Qt got waaay better with the release of Qt 5. It's called wither "Qt for Python" or PySide2. I dunno why it has two names but the docs are fantastic. https://doc.qt.io/qtforpython/contents.html
> It's called wither "Qt for Python" or PySide2. I dunno why it has two names
That brought back some funky history.
In the days of yore, when Qt 4.5 roamed the lands and 4.7 did not exist yet, there was a set of Python bindings called PyQt. They were ... a bit clunky, but they worked. Perhaps more importantly, they were also a subject of cross-company political wrangling.
Nokia bought Qt back in mid-noughties and wanted to make the toolkit more easily accessible for mixed commercial use. Authors of PyQt didn't want to relicense to include LPGL as an option.[0] So PySide was born.
When the development of Qt5 got under way, the developers realised they could finally break many of the internals and eliminate a lot of nasty legacy baggage. The public API remained mostly the same, but low-level bindings, and pretty much anything that poked under the hood, could expect APIs to change, headers to go through contortions and so on.
Considering that the bindings for Qt5 are called PySide2, I can make an educated guess that it was in the end easier to rebuild the new bindings from scratch for 5 and onwards, rather than try to shoehorn the use of possibly conflicting low-level APIs between the two major versions. The name "PySide" was already known in developer circles as "LGPL friendly Python bindings", so holding on to the base name makes perfect sense.
PyQt is a really good binding. Compared to e.g. wxPython (Phoenix), which is built using PyQt's tooling, the latter is full of jank, like whether something is a property seems to be random (SetIcon(icon) -> property, SetIcons(iconbundle) -> not a property, just one funny example). Some things ARE properties, but they're not writeable, even if there actually is a SetXXX method. Some things convert types automatically, some don't. In a bunch of cases there is weirdness, like what you return from a OnGetAttr needs to be protected from Python GC, otherwise it is silently (!?) ignored. Add the jank of wxWidgets itself, and PyQt/PySide look even better.