It's not C++
Qt requires a C++ compiler, it uses classes, namespaces, templates... looks like C++.
they have their own little language that compiles to C++ using an external compiler
False. If you're refering about "moc", it just provides implementations for functions declared through various macros (Q_OBJECT, Q_PROPERTY...). If you use their meta-make (qmake) or some other Qt-aware tool (CMake, VisualStudio with Qt plugins,
It has crappy alternatives for everything in STL that work just slightly different but not any better.
Qt supports a wide range of C++ compilers since 20 years, including some which were not quite standard conformant or were not providing a "good enough" STL. So Qt provided its own containers. But their use is required only when use some Qt APIs: you can freely and happily use STL containers everywhere else. In more recent versions, Qt's containers provide an API (alongside the Qt one) pretty similar to STL's one. Also they're often seen as easier to use by C++ beginners or non-expert.
It has copy-on-write.
Copy-on-write was very interesting at some point in time. As everything, it's not perfect, but in some cases it was very handy, for example allowing to return large objects by value, allowing great speedup for compilers not knowing about RVO (Return Value Optimisatin). Today it is probably superseded by the move semantic, but this is a rather recent improvement to C++ and maybe not yet supported by all compilers that Qt supports.
It doesn't use inheritance, but gives you endless lists of almost-identical function calls (all those functions to add controls, for example).
Look at the hierarchy of classes inheriting from QObject, look at all the virtual functions that can be overloaded by the user. Inheritance is actually used at large. And most of the "almost identical functions" are there for a purpose.
And that stupid Q everywhere you look is just painful.
Totally subjective and mostly irrelevent. What about those "stupid" gl/GL_ prefixes in OpenGL, vk/VK_ in Vulkan, the "G" in GTK, the "C" for all MFC classes (as if we didn't know already we were dealing with classes), and so on. Of course Qt is not perfect - no one is saying that. Using it daily in a millions-lines (commercial, expensive, closed-source) project, I have my share of gripes against it. But it's the same with any framework. After having used various frameworks in non-trivial projects (GTK+, wxWidget, MFC and a handful of others), for C++ I see Qt as "the best" framework - which in some cases means "the least bad", and never means it's perfect.
"moc" provides introspection you would hardly get another way
Not true. You can get it with plenty of other ways, including normal usage of the embedded preprocessor.
I wrote "hardly", not "impossible". Now you may be of the elitist kind of people which assume everyone should be able to write and use something like Boost::MPL for breakfast, but in the real world easy tools are sometimes welcome.
That's still OOP and C++.
Associating C++ with OOP is a problem. It's a multi-paradigm language. OOP has very few valid use cases. If you want OOP abused everywhere, use Java.
Notice I said "OOP and C++": I did not say "OOP is C++" nor the other way around.
Qt does not duplicate the STL, it provides similar functionalities
It has its own set of containers, strings, iterators, all of which use are not conforming to the standard concepts. They might have better implementations in some cases (for example a custom hash map implementation optimized for a given usage pattern might be faster than the general-purpose one of your standard library implementation), but the design is not as well-crafted and is significantly less flexible.
Less flexible, quite true. But again, overall easier to use. Now their containers provide the usual "::iterator" and "::const_iterator", making them looking quite similar to STL containers. Even QString provides begin() and end().
Indeed it uses COW almost everywhere it might make sense.
COW never makes sense unless it's used to implement partial data sharing within a larger data collection. That's not the case in Qt. In Qt it's just used because the bad design forces the framework to copy many objects even though it's not needed.
The thing is, quite often data is shared in a heavyweight GUI app. It may be mostly useless in Qt itself, but it's quite usefull when you *use* Qt. Now we can talk about "good" or "bad" design: I tend to prefer a design which may not be academically perfect, but clean and easy to read and use. When you have to maintain several millions LOC, perfection may have different meanings.
Sometimes it's a real nice thing to be able to return a QString by value for (almost) free
I don't understand how that's related. Returning a local variable or temporary variable by value is always "free" (doesn't call copy constructors) regardless of COW. It's called NRVO, though that it is a silly name. It's not really an optimization. It's more a matter of ABI.
ABI which is not standardized, last time I checked. Here the optimization is provided by the framework, not relaying on the compiler. That said, if you don't like it, then don't use it... as simple as that.
don't forget all of this was created long before we had rvalues and move semantic in C++.
rvalue references allow to distinguish lvalues and rvalues at the language level. There was no problem implementing move semantics by handling rvalues explicitly. Before C++11, people used swap when they needed to move. Qt containers didn't even have swap before 4.7 (2010).
Don't take my poor example for more than it is... There's more in sharing data than just moving. Granted, it's pretty useless for a "Hello world" label.
"Good" language features are usually "modern" language features (sure, not always, I know). Because Qt tries to be available for older compilers, even awful proprietary ones (Visual C++ anyone?), it has to do tradeoffs here and there.
Current Qt only works with Visual C++ 9 (2008) and higher, Visual C++ 10 (2010) or higher is even highly recommended. Decent C++ support has been available since Visual C++ 7.1 (2003).
I wouldn't call "decent" the C++ support in Visual 7.1. Not even in Visual 2010. Visual 2012 is getting close to be "decent", although "decent" is pretty far from "good".
About typesafety, well... I won't really disagree on this one
;-) but it's a real minor concern really
Type safety, a minor concern!? The point of C++ is that it has a powerful type system that can catch errors. Type errors are ones of the worst type of errors you can have in a program.
It's a minor concern in the context of using Qt. Feel free to write typesafe code around it.
"moc" provides introspection you would hardly get another way, at the cost of a single macro (Q_OBJECT) and automatically generated code. That's still OOP and C++.
Qt does not duplicate the STL, it provides similar functionalities, but arguably simpler to use. Indeed it uses COW almost everywhere it might make sense. Sometimes it's a real nice thing to be able to return a QString by value for (almost) free - don't forget all of this was created long before we had rvalues and move semantic in C++.
"Good" language features are usually "modern" language features (sure, not always, I know). Because Qt tries to be available for older compilers, even awful proprietary ones (Visual C++ anyone?), it has to do tradeoffs here and there.
About typesafety, well... I won't really disagree on this one
By the way, I've been using Qt for... oh my, 16 years already??
Try this: http://www.doudoulinux.org/web/english/
Should be OK for a 4-years-old. Two things:
Yes, that's actual real-life experience
Are there still Logo implementations around?
KTurtle : http://edu.kde.org/kturtle/ My 8-years old son really enjoyed playing with it, after giving him a few basic informations. Amazing how children can try and discover by themselves.
Some people have a great ambition: to build something that will last, at least until they've finished building it.