Writing GUIs is not a ton of fun for me (whether with Qt on desktop, native development on iOS and Android, or Flutter for mobile/desktop), but I wouldn't say Qt Widgets are worse than other stuff. I'd say it's definitely better that Android and iOS were a few years ago, before reactive programming became widespread.
I didn't have a good experience with QML; I'd call it at most not great, not terrible.
I've been using Flutter lately for a desktop app and the GUI part is more pleasant to write, for me (mainly because of the general "immediate mode/react" feel); if the app had a reasonably complex business logic I wouldn't want to write it in Dart though.
"... if the app had a reasonably complex business logic I wouldn't want to write it in Dart though."
I'm surprised by this as I've been working on a pure Dart library lately and really enjoyed it. Anything in particular you dislike?On the plus side, I wouldn't say it really needs to be learned if you know Java (and maybe Kotlin or Swift, so that you are used to the ? operator). I wrote a couple of apps in Flutter, having never read even a single line about Dart. I picked it up by looking at the Flutter examples.
One particularly annoying thing is that a whole lot of stuff is achieved through code generation (serialization, equality operators, ORM mapping, localization among others), and there are so many different way that code generation can be done - some automatic during the build, some that must be manually invoked. The build system seems really lacking.
As for Tony Hoare's billion dollar mistake, I'm not sure if you've seen the information about Sound Null-Safety[1], but it's actually one of my favorite features about the language. Static analysis in Dart feels a little bit like Rust in that as you write code your IDE can provide smart suggestions and bugs are often found as you write instead of when you compile.
Finally, I'll take the pub.dev[2] toolchain and build system over anything out there today besides Cargo. Plus, compiling to a single executable file without any dependencies that have to be installed on the deployment target is great.
"There are many better Java++ languages out there."
Any in particular you'd suggest? I'd definitely give it a shot if it blows Dart out of the water![1]: https://dart.dev/null-safety
[2]: https://pub.dev/
Kotlin looks like a good Java++ language (especially for Android); and Typescript would be the most pragmatic choice for web. But again, Dart is going to have to keep up even with modern Java.
Regarding boilerplate, can Dart define a simple data class with equals and hashcode in one or two lines?
Frankly, I haven't needed to implement such a basic data structure myself in Dart, but here's a whole book of examples of implementing common data structures[1]. They look pretty straight forward to me. You can also take a look at the Dart language tour.[2]
[1]: https://www.raywenderlich.com/books/data-structures-algorith...
My experience with QML/Quick is that while you get a little JavaScript runtime and a slightly less obtuse way of defining "widgets" and application layouts than the original Qt "forms", there are some clear drawbacks that make it a near non-starter for anything I've thought about using it for.
Right out of the box, you have to use QML, which is a weird hybrid of language/markup paradigms, and it's a proprietary language. What designer knows QML? Probably f$#%& zero. Electron wins right out of the gate because what designers don't know at least something about HTML and CSS? Sure, if QML was that groundbreaking then maybe people would learn it, but it's owned by a company and it brings nothing new to the table that HTML and CSS can't do better.
The solution to most things in Quick is to write JavaScript. I've been a JavaScript engineer for most of my career, but when you're writing a Qt application then the obvious place to do anything useful or complex is in the host language of C++ or Python. So what if you want to tie behavior between your Quick widget and a C++ library you either wrote yourself or have imported from a vendor? Well, you can kinda sorta do that, but it's hard to explain here; let's just say that tying a widget to C++ code is extremely clumsy, and good luck calling a function on a Quick widget class because you just can't simply do that.
For instance, Qt provides a WebView widget, which was exactly what I needed recently. Uh oh, the decided to make it a Quick widget only, rather that do the obvious thing of exposing it as a C++ class and providing a Quick widget that wraps around it. Why did they do this? I guess it's because in the long term they think that they'll move away from classic widgets entirely. In any case, I wanted to call the `runJavaScript` method on the widget class without having to jump through hoops in QML. The only way to make that happen was to hack the build process to expose private methods.
But I realized that, at that point, there was no longer any point in using Quick if I was going to have to use some neat tricks in C++.
So in just a day, I wrote a classic widget that implements the same WebView used in the Quick version, just without any of the QML crap.
https://github.com/Ravenstine/qt-web-view-widget
And yeah, Qt does provide some form of a WebView in as a classic widget but, guess what, it involves bundling a browser runtime rather than using the browser engine of the host OS. Makes sense if you need more of the browser APIs exposed, but if all you want to do is show some simple things on a webpage and call JS from C++, then going through the effort of compiling Qt with support for that browser engine is overkill.
Overall, I don't mind most things about Qt. Despite how overcomplicated some of it is, it does what I want, which is to allow me to write native desktop apps without needing to invest much of my knowledge in OS-specifics. I like that I can use their Bluetooth library and, besides some quirks with how macOS handles device identifiers, I can compile it on other platforms and it will work for the most part.
I wish they'd abandon QML/Quick and just focus on making the experience of writing completely native apps better. I also see no reason why the solution to mobile development can't simply be different sets of classic widgets that are mobile-specific.
Whole thing was built in about 3 days and I would say it was a huge success (visualisation crested with it was used at a gig of about 1.2k attendees and creating the editor meant being able to iterate quickly to create a visualisation the musicians were happy with, LEDs were attached to clothing). I certainly enjoyed the experience.
Doing it in Qt meant that I could write C++ code to “run” the visualisation, but with a different display implementation (editor version drew to the editor, hardware version outputted to the LED hardware, but the track runtime was the same code). QML made building the UI easy.
Nowadays I mainly do React-based web UI’s, but I still much prefer QML to html/react/css. I especially miss QML’d anchors for layouts.
I liked that QML allowed me to iterate quickly on the UI. It was really quick to just compose a bunch of components together and have something working. I also enjoyed the integration with the C++ side. Overall I found QML pretty solid. If I'd build a desktop app again, I'd definitely consider it.
The editor simulated the LED strip using the same code to generate the effects as the on device version (which just ran without the UI and a different “driver” class implementation). It ran on a Raspberry Pi so the device wasn’t a microcontroller or anything, which made it easy to run the C++ code. In theory I could have made it run in a microcontroller but it wasn’t necessary for the project and time was limited.
Anyway, the code is here: https://github.com/danielytics/ledstudio
And the QML specifically is here: https://github.com/danielytics/ledstudio/blob/master/main.qm...
If I were to clean it up, I would at least split the different labels into their own QML files but hey, shortcuts were taken over those few days :)
Visually, it didn’t look all that great, but I’m not a UI person either and it was rushed. Functionally it could have been improved too, but it did what it was supposed to and it worked well. It allowed us to create various LED effect sequences quickly and play them back later.
I personally quite like QML. It’s not perfect, by any means, but I like using it more than React (which is what I’ve been using on projects since due to needing to be web based).
Also, there's nothing wrong with using Qt Quick from C++, or using QML without Qt Quick at all. what matters is your project, not what whatever best practices say.
It's finally matured into a usable system now that application processor horsepower has caught up in the embedded field. It only took 12 years.
No, you don't.
And unless I'm mistaken, if you're doing anything with JavaScript, that's all defined in QML. I don't think there's a way around that, unless I'm mistaken. And often times you need JS to achieve certain things in the separate memory space where the Quick widget is being executed. What that means is that there's a wall between Quick and C++ even if you are instantiating Quick widgets from C++.
While Quick widgets technically share memory space with the rest of the app code, any sort of UI behavior is expected to be handled by JavaScript, which doesn't run in the same memory space, and of course it's not going to in any case because it's not C++. So when data is shared, it has to be type converted, which can become a problem if you even slightly wander off the beaten path:
https://doc.qt.io/qt-5/qtqml-cppintegration-data.html#conver...
If you could elaborate on why I'm wrong, I'd certainly appreciate it. It's been about 3 months since I decided to entirely ditch anything involving Quick/QML, so I could be easily misremembering aspects of it.
In no way am I saying that someone shouldn't use Quick if they find that it works well for them. I find Quick's argument versus nearly all alternatives to be lacking. The primary argument against Electron is that it's bulky, and I think that's absolutely the case. The argument for Electron, however, is using the full web stack, which everyone knows how to use, and if you need performance to use WASM and workers, and that makes a lot more sense to me than something that even most C++ devs aren't familiar with that still forces you into dealing with all of Qt's compiler quirks.
As for mobile: if you can afford to develop completely independent apps for mobile, then do it. Many organizations cannot, and saying "we'll do the backend in C or C++, then call that code from a Java/.NET/Swift/HTML5 UI" looks fine on paper but then reality hits. Is the deliverable big? Yes it is, especially if you don't compile statically. But there's no good and cheap solution (and yes, Qt is cheap for the kind of savings it provides).
Qt saw this paradox and declared that iOS builds don't count as "embedded" builds, so you can deploy with a desktop license and not pay the exorbitant per-device vig. But it's still non-zero.
^(yes, you can do it dynamically, but you can't use GPL because users can't replace the dynlibs. So you're static whether you like it or not)
https://www.gnu.org/licenses/gpl-faq.en.html#LGPLStaticVsDyn...
If you statically link against an LGPLed library, you must also provide your application in an object (not necessarily source) format, so that a user has the opportunity to modify the library and relink the application.
Now, for mobile apps "providing your [proprietary] application in an object format... so that a user has the opportunity to modify [Qt] and relink" might be challenging/impossible, e.g. given the nature of the iOS platform.However, what I've found is that many devs believe that Qt static builds (for proprietary apps) are not allowed in general by the LGPL, and that's simply not true per the FSF's own FAQ. Qt's docs/marketing don't help in this regard (in my experience).
I agree, Qt docs/marketing regarding licensing are a complete shit-show, and a solid reason why I don't recommend them anymore when I show up in a new organization. And I've been a Qt developer since the version 2 days. It's just too hard to negotiate and explain to management anymore, and the new lean towards a subscription model makes it even worse.
Literally any other cross platform mobile solution is better, possibly the fact that QT tries to stretch itself across mobile and desktop is why it is so frustrating to work with on mobile. The apps tend to come out like desktop apps someone did their very best to shrink down
I think the only way we can get away with using it is because noone has any choice, if anyone launched an app using native in our field, any qt app is at an instant disadvantage. The qt team worries that an new ios release happened while i’m looking at the release notes and docs looking for things to use to our advantage
That said, I still hate trying to do basic stuff with Qt, for example using slots. Example: im calling an external script or process that could take 30 seconds to run. I'm doing this 50 times and using thread pooling to manage those workers. Try issuing an update to a widget to let the user know that its progressing. The slot setup barely makes sense, is a pain in the arse to understand, and I've not managed to do it successfully yet. The issue here is, its the main way of doing things and its a nebulous, poorly articulated concept in almost every bit of doc or guide, and very difficult to implement between the Designer and code of an existing application.
I would say I prefer QML over that other Qt GUI Framework, mostly because you can leverage JavaScript for fast development, but not that fond of the the GUI part of QML, but it is still better than the Qt GUI Framework because of better customization.
I found it difficult to adapt and style many of the standard widgets in the Qt GUI framework, like item lists and similar things.
It is sort of easy to expose "dumb" C++ functions from Qt to be used from QML's JavaScript and then you put all the GUI logic in JavaScript instead.
Qt makes the C++ easier with their own copy-on-write containers for the most common things you need, however the extra qmake build step is somewhat horrible and when you need to ship your application you run some command line tool that copies a bunch of dlls that you still need to sort out manually. And when all is done you have big zip file anyway.
But would I use Qt again? No, even if we ignore the licensing issues.
I'm not interested in writing GUI desktop applications in C++, it just too clunky (still with C++20) and does not fit a fast iterative approach (at least not for me) even with all Qt containers. And of course compiling C++ is not fun especially when you add an extra qmake step. (And now I see that Qt 6 has switched to CMake, oh lord, I truly dislike CMake, the main reason why I stopped using CLion)
If I remember correctly there was some complaints of lack of documentation for the Qt Python bindings, that you basically need to read the C++ code and then figure it out, but that can have changed.
If I want native widgets I write that in PureBasic, PureBasic is way faster to develop in than C++ or even C. I have instant compilation of my project on press of button out of the box. No asinine build step that I spend hours to configure.
And for QML I think there are better options. One that I'm in the beginning of building is with Sciter(HTML/CSS/JS) with a custom backend in PureBasic.
Nice thing with Sciter is that you can easily bind it to any language you prefer as long as you can load a dynamic library(dll/so/dylib) (I think if you have a license you can compile it against C headers). It exist many different bindings, C/C++ of course, Pascal, golang, rust, python, .NET, D.
Or you can just go with app bundle that Sciter ships and don't have custom backend at all (all depending on what you are trying to build of course). Sciter is not a browser either like electron, so it doesn't have the same resource impact.
Would you elaborate how do you program GUIs in PureBasic? I noticed there are multiple ways to do that: positioning each gadget manually, coding XML, using visual GUI designer, more?
Also, how are things on macOS? They mention full Cocoa coverage in the documentation.
Yes, I have only done manual position. My programs are not that big yet. Some gadgets are not always feature complete, thus sometimes you need to write custom code (like for special events) for each platform or use a canvas. Drawback with canvas is that you need to write it dpi aware thus making it a bit more complex.
GUI for Windows is the old Windows look (win32), not the new modern one.
That is why I was bit excited with a Sciter integration, now you have the possibility to write complex GUI ("modern") with Sciter and classic GUI with PureBasic or a combination.
XML layout, there is some critique against it not being DPI perfect. You can read about it in this thread
https://www.purebasic.fr/english/viewtopic.php?t=71146
Form Designer - popular but to my understanding starts showing some limitations when you start getting multiple windows (handling of identifiers of windows/gadgets). And if the form designer has a default that you can't change then of course you need to change that value manually every time you update your form by the form designer.
To my knowledge there exist two commercial alternative to the built in form designer, PureVision (old) and IceDesign (new).
macOS - I'm not a mac user so I can't tell, but I do know there is frequent mac discussions on the forum. There have been some excitement around the new coming PureBasic 6 release with a new C backend, making it possible to compile to native code for the M1 processor.
What I would really like to see would be a QRhi-based QPainter implementation for things to be future proof but I understand it's a non-trivial task at all.
Also, even though QML is very nice for projects with more or less fixed UIs, for very dynamic things I find it to be more unwieldy; I reach for it for mobile and embedded without hesitation but for "traditional" authoring desktop apps I'm generally faster to develop with QWidgets/QGraphicsScene in C++.
We purchased a small business license for QT 5 and I’ve never hated a framework more. It was clunky, resource consuming, surprisingly challenging to build in the way we needed, difficult to work with, etc. No engineer wanted to touch the gui codebase until we moved off of it.
Most of the use cases where I see people sing it’s praises are the python framework rather than the C++ one, but are we really the only people who had this negative of an experience?