68 comments

[ 3.8 ms ] story [ 138 ms ] thread
For UI you always want to use the a platform or OS’ native controls and APIs rather than some stack on top of it for best performance and a polished look and feel. Anything else is most often second class.
Except on Windows, where Qt looks more "standard" than whatever MSFT's current "standard" framework is this week, and on Linux, where GTK and Qt are the native frameworks. If you handle these with Qt and your budget is limited, you might want to handle more platforms with Qt.
If your budget is limited you're better off using HTML. It's significantly cheaper and gives more consistent and less janky experience than QtQuick.
This is how I’m developing my application with Rust.

The UI is completely separated from the core of the app, and the core can be compiled natively or target Web Assembly.

I’m building the UI with HTML and JS (by the way, Web Components feel way better than React) and running the whole app in the browser (via WASM).

Eventually, I’d like to create native applications for all platforms, but I don’t have the time to spend on that right now. When the time comes, I’ll be able to easily remove the HTML frontend and bolt on a new one written specifically for the target platform.

This lets me prioritize dev speed in the short term and native UX in the long term.

Whether or not that's true depends on the existing skill set of your developers. :)
QWidgets is the one to use if you want to blend in. Qt Quick is highly productive, but native styling is, AFAIK, not completely there yet. It's getting better, not sure how good it will get.
The original article is about mobile development where AFAIK you're supposed to use QML.

I don't know the state of QWidgets on iOS/Android but my guess is it's even worse than QML if at all possible.

Right, QWidgets are not very suitable for mobile. QML is... very suitable for custom (especially touch) GUIs, native styling is WIP. Seems to be done with higher priority than desktop native styling.
Yeah, lack of native styling in QML sucks. Although, customizing Qt Quick components is SO easy and straightforward.
From my work experience: it's not cheaper. Paying people to reimplement stuff that is already implemented and functioning, and then pay them to fix the bugs, and then pay them to make it accessible.
I once took part in a project where we created a QML based implementation of a previously Node.js based embedded app. Node.js took ten people two years, QML three people six months - and no callback hell. Lots of caveats though: I'm not sure how experienced the Node.js guys were - team QML was fairly experienced (and competent in general). JS GUI frameworks have improved a lot respectively become available in the first place. Recreating something is always easier than creating it the first time. We used the same backend parts that were probably co-developed with the Node.js frontend (but AFAIK not counted in the two years, ten people).

We heard that the Node.js version had quite high velocity initially, but slowed down greatly when it came to polishing. Like more than half of the time spent on the last 5%. The QML version also ran more smoothly.

In many cases QT is the native toolkit. Embedded systems for example. It often is useful to run those elsewhere, as a demo.
Qt should just copy Cocoa already, on both desktop and mobile, and both in API surface area and appearance (on desktop, at least, i.e. the Mac look). Now is a better time to do so than ever, given the flattening of Aqua, which makes it easy to mimic, and the Oracle v. Google precedent moving API copyrightability out of the grey area.
What I did some time ago was create two native projects, drop in a WebView, write most code in C++, then use a single shared C++ header for things like bluetooth. This functionality is implemented in a C++ file for Android and an ObjC++ file for iOS. On Android you use JNI to access the Java Bluetooth API's and on iOS you can directly invoke the iOS Bluetooth libraries using Objective-C.

The WebView on Android and iOS supports configuring an interop function. It allows you to map a JavaScript function to Java/ObjC functions. In my case, I had a single function with a single string argument, which I used to pass JSON messages.

I then implemented a callback mechanism where each message would get a unique ID. From JavaScript code, I could call a function in the shared C++ core and get a callback when data is returned.

The shared C++ code can directly access the internet and filesystem (I read in another comment that they changed this recently?).

The performance of the WebView is amazing, especially if you just rawdog it and write plain JavaScript. Modern JavaScript is nothing like it was back in the IE6 days.

With flat UIs, at the end of the day, who cares that it "doesn't feel native". What price are you willing to pay just so that it "feels native"?

Performance? Not so much on Android I would say. The bloated gigantic UI toolkit is so large and complex. A native c application would run much much faster. Harder to create for sure. But if you want performance you should go low level.
That's what wxwidgets does and... yeah, it's not always great. Native widgets have specific behaviour/attributes which don't necessarily translate to generic frameworks. My wx experience is constantly running into "why didn't this call do anything" situations because of that. There's no perfect solution that I've seen.
I believe QML ListView actually does support kinetic scrolling - Qt calls it "flicking". To get behavior closer to React Native, it might work to decrease the value of the Flickable flickDeceleration property [1].

That said, my troubles with Qt's performance and behavior on mobile led me to create my own cross-platform GUI library: https://github.com/styluslabs/ugui/

[1] https://doc.qt.io/qt-6/qml-qtquick-flickable.html

You're right, I will update my post. However, it's quite difficult to get this right on all devices as compared to i.e native where it just works. Plus, there are performance issues like those you mentioned that further impact scrolling and rendering responsiveness.

Your framework looks cool! I like that you have some flex support.

your library seems really interesting (I'd be interested in collaborating if it had a license compatible with my projects) but I've not found it mentioned in the repo. Would you be interested in clarifying the licensing terms?
I love a homebrewed gui system (having made more than a couple myself)! This looks pretty far along, kudos.

The only slight nitpick I have is the unity gui system is also called ugui so search conflicts might be annoying.

Agree with other comments about needing a license - your library looks like it would integrate into audio plugins quite nicely (it's self contained). If it's licensed to allow it, I do try to upstream changes I make!
Honestly, I don't know what you were expecting. QT sucks pretty much everywhere. For universal UI I think the three choices are native (and if you have to pick one start with iOS because of reach and the fact that iPhone users pay for apps), React Native, or Flutter.

The problem with 3rd party frameworks is that you're always playing catch up. So if you're soloing it / developing a proof of concept you're good but if you're a real business you'd have a hard time selling me on anything but native.

Businesses don't necessarily want to maintain 10 versions of the same thing just so that it can run on different platforms. It is costly and they don't like costs.

You're thinking from the perspective of a solo developer making an ios app and nothing else.

Seems like you are thinking from the perspective of "internal enterprise app, possibly sideloaded to use inside warehouse", or something along those lines. Those can really look like anything, but there is a high chance it will be designed and tested on a single platform anyway (since the company can purchase specific devices), so why bother with multi platform. I have seen plenty of cases like these in my work, and those apps always suck and are eventually replaced by native ones.

If you are building an app which is supposed to be used by regular end consumers, native is the only real way to go. And as prizzom mentioned, choosing native iOS toolkit is a good idea if you want to sell, because Android users are not very keen on paying for apps.

Have you seen apps?

slack uses html, steam uses extremely slow html… big companies do not care.

Slack doesn't use HTML for iOS app, it's native.

Steam also recently remade their apps. Authenticator and chat for steam uses native ui toolkit (styled to look like Steam desktop app). Store browsing still uses html frame, but that is less relevant for Steam on mobile.

As soon as someone spells it QT and not Qt, I dial down my valuation of their opinion
Thanks for sharing! What performance issue are you talking about? Did you separate your logic to C++? I'm building an advanced block editor[1] where the model is in C++ and the view in QML and the performance is really great.

The scrolling like you mentioned is subpar compared to native macOS one, so I hope Qt will address that. I saw someone mentioning `flickDeceleration` but at least on desktop it doesn't seem to change anything? Maybe it's because my delegates are so different from each other?

I also plan to support mobile version for my app in the future, so it's sad to read about the rest of the issues.

[1] https://www.get-plume.com/

I haven't seen any performance issues on desktop, but on mobile they really stand out. I have separated logic into QML, and even experimented with implementing custom QQuickItems in some places.

Here are some issues I've seen related to performance on mobile:

1) Opening a larger app is really slow (maybe 3-5 seconds), but works okay for smaller apps. I'm not sure what's going on behind the scenes and haven't had time to dive deep there yet, so this could be specific to me.

2) Rendering full pages is quite slower than native, as is QML rendering in general, even when using the QML compiler (which compiles your QML to C++)

3) Qt text rendering is a bit slow too, but you may not need i.e QTextDocument if you're implementing a text editor of some sort.

Regarding your first point, instantiating a lot of QML items is usually what makes startup slow. You can use Loaders to load things on demand (and timer triggered Loaders to load stuff you will probably need but shouldn't delay startup). Make the Loaders asynchronous and timer triggered (async but immediately triggered still slows down startup) and switch them to synchronous when their contents are needed immediately.

I have a component for it, it's 10-15 lines or so.

These performance issues are vastly different from what I experience on Desktop, so I'm curious to test my app on mobile. In my experience, C++ and QML outperforms comparable native apps by 4x.

Regarding no.3, what do you mean by QTextDocument? My block editor is implemented by each delegate being a TextArea (inh: TextEdit), and it's very fast.

One trick I've learned, is to use `reuseItems`[1][2] in ListView. It gives incredible performance boost. You'll need to adjust some things according to the onPooled and onReused signals, but it's a no-brainer for many use cases.

[1] https://doc.qt.io/qt-6/qml-qtquick-listview.html#reuseItems-...

[2] https://doc.qt.io/qt-6/qml-qtquick-tableview.html#reusing-it...

QTextDocument is a class in Qt::Gui that many of the other text classes/components use. I was thinking you may have implemented your own text handling widget/item, but using delegates of text areas makes sense too.

I will try reuseItems again. It's something I tried before briefly but thought it may have been causing some rendering glitches and removed it. Maybe because I didn't implement onResused or onPooled properly. Thanks!

> I was thinking you may have implemented your own text handling

Yes, but without QTextDocument as I had some problems with it. I had to implement my own undo/redo/copy/paste/etc.

> It's something I tried before briefly but thought it may have been causing some rendering glitches

Yes, I've experienced some (minor) glitches that I've yet to figure out how to fix. For example, the cursor seems to (sometimes) jump when creating new blocks. Sometimes delegates reappear with animation (while I turned them off when onPooled ran). I'm trying to figure out if I'm doing something incorrectly (highly probable) yet I don't get these issues without reuseItems.

Sure, I hope it works out well for you (:

Hmm, for 1 and 2 have you actually tried to profile your code? You can use the QML profiler to check which parts of QML compilation are slowing you down. Also consider using GammaRay [1] to see what's causing the rendering to be slow.

[1] https://www.kdab.com/development-resources/qt-tools/gammaray...

I'll try GammaRay. Thank you for the recommendation. I've tried the QML profiler before but I always have difficulty getting it to work on Android.
For something more data demanding, e.g. a video player, do you have to copy every frame from C++ world to QML/JavaScript in order to display it?
No, you'd use something like libmpv and tell it to which rectangle render the video.
This really depends on the target platform , Qt version you are using. To put things into perspective, With Gstreamer/QML, we've had smooth 1080p30 fps on measly imx6ul hardware, thanks to zero copy pipelines.
I've had good experiences with Flutter on both mobile platforms and Mac desktop. After doing several React Native apps over the years Flutter feels better engineered across the board. It would certainly be my first choice for a cross platform mobile app at this point.
I havent had good experience with either Flutter or React Native and at this point I am willing to bite the bullet and try native next. And they say webdev is bad.
I did about 8 years of native iOS development. I’ll never go back to that.

As frustrating as the web can be I’ll take that over being locked into a single platform proprietary toolkit.

I was a fan of QT 20 years ago. These days I like to use .NET MAUI for cross platform apps.
Why not Platform Uno or Avalonia? Was MAUI improved significantly recently? It was quite lacking, especially for desktop.
It is quite usable. Why not Uno or Avalonia? Because of better tooling, different concept, and more importantly, because MS has better resources to pull it of.

Nancy FX was nice but most people used the Framework and it became the standard.

Got an impression that even if the mobile side is improved, Microsoft does not really care about the desktop support in MAUI.
Being a WPF dev, I like Avalonia but it doesn't even have a rich text box, so it's not as useful as it could be.

They have a WPF compatibility thing but it's "enterprise" overpriced.

It seems like a lot of the newer UI frameworks are weirdly lacking when it comes to a few highly functional widgets like that… UI-as-branding custom styled buttons are prioritized over rich textviews and tableviews/datagrids.
My impression is that MAUI was released with a lot of fanfare but wasn't really ready (but that's just from articles I read, I haven't tried it myself). That's before even getting into lack of official Linux support. It then seems to have very little attention.

It fits the classic Microsoft pattern of releasing a developer technology that doesn't quite work, then abandoning it before they ever finish it. For example, WinForms was meant to get hardware acceleration but, before then, was soft-deprecated in favour of WPF.

It seems like that isn't your experience, is that right? I'm genuinely curious because I want to like MAUI – I'd love a cross platform (Windows, Mac, Linux), hardware accelerated, C# GUI toolkit (that works and is supported).

> My impression is that MAUI was released with a lot of fanfare but wasn't really ready [...] >It fits the classic Microsoft pattern of releasing a developer technology that doesn't quite work, then abandoning it before they ever finish it.

My sense is that MS is all-in on "web ui" (html/css/[js|ts]). Native apps don't fit with the commercial imperative to get as much compute happening in Azure as possible. The Windows desktop increasingly has just one purpose: to maximise the likelihood that the end consumer will use Microsoft's cloud, and not someone else's. The Desktop UI is now a bedraggled mix of several UI toolkit generations, with many built-in apps going all the way back to the original Win API.

Microsoft's own headline apps - Office and Teams - have a web tech future. Teams started there, Office is going through a long, slow and somewhat painful migration.

Windows is slowly becoming just a remote desktop. You don't need native apps on those.

Why didn't the author consider Kotlin Multiplatform in the conclusion?

It seems to be the most accurate choice to answer the described needs while solving the lack of native dependency that QT is apparently facing.

It's just because I hadn't heard of it at the time. I will take a look at it though, others have also mentioned it to me after this post.

It looks like the iOS support is in alpha though, and I'm curious if it uses native components on iOS?

Every year since 2007 I tried Qt for mobile development (starting with Nokia N8) only to be disappointed again and again. Making a game with 3d graphics? Drawing charts? no problem. Using ui elements and sensors? You inevitably run into a bug, a missing feature or learn some new framework that works well until you do something that is not in one of the demos.

The team is obviously incredibly talented and their coding style know-how matured over time, and I really want it to work, but unfortunately it still isn't there yet.

To be fair Qt development on late Symbian versions felt great, as it was the native development environment on late Symbian versions (Symbian Belle if I remember correctly).
Symbian anna and belle came back to back after Microsoft's acquire. Shortly after belle (which regularly crashed), there were no more updates and store stopped working. They essentially killed my phone.
I'm surprised people still try this tbh. I tried Qt on mobile when it first came out and it was clear that the entire approach was wrong.
Qt on mobile aka QWidgets? Otherwise QML/QtQuick is no different from Flutter. I have worked on a couple of different QtQuick Mobile apps, and they work just as well as any other native apps there were. It really depends on what your app does.
I was thinking about QML. In theory it's the same as Flutter, but in practice it's not at all because it was designed for desktop. They basically shrank a desktop app down to phone size. It's the Windows CE of phone GUI toolkits.
Huh? QML is specifically designed for Mobile/Embedded use cases though. That too when Nokia was targeting their Meego and Symbian touch interfaces. The best example usecases of QML you'd see is on Nokia N9/Ubuntu touch/even Sailfish OS.

It was meant to be a declarative scripting language around their QGraphicsView back then iirc. That's how there was no QML Components for Desktop until quite a bit later. Then they made QtQuick a lot more fast/powerful in Qt5 by rewriting it on top of their new OpenGL scenegraph.

So what desktop design paradigms do you see in QML that make it unfit for mobile?

>Being able to share UI and code on Android and iOS is still a desire for many developers. As hinted throughout the post, I think React Native may be the only other possible contender.

I have been a codenameone developer for 8 years now. On Android you run java and on ios you run static c which comes from the java code itself

Shai Almog and Steve Hannah have done a great job at making cn1 a comprehensible platform to develop on mobile. All the issues listed on this post are covered (scrolling with inertia, Android file system updates, etc)

I don't know how successful cn1 is in terms of users but I wish it were more popular on places like HN where React Native/Flutter is the bread and butter

Wrong Flutter has beaten React Native in terms of developers and apps and firms using the framework.
Is there any solid proof of this? It seems that Flutter is not used in any notable apps and React Native is used even by the big players in the field. I have yet to see a single high quality app made with Flutter and literally the only app I’m using that is made with it is the one I’m working on. React Native seems massively popular in comparison. It really feels that the stats that show Flutter being popular are not really measuring real life use. The Flutter ecosystem seems especially tiny and it has close to no support from 3rd parties, even Google treats Flutter as a second class platform when it comes to libraries like Google Ads.
The main issue I felt with Qt on mobile, was that the effort writing JNI bindings or Objective-C++ wrappers for stuff Qt didn't account for, like the file dialogue example, would be better spent just having the business logic in C++ and writing the UI in the platform native languages.

The effort was already there anyway, so Qt wasn't bringing anything to the table, when a desktop app isn't part of the offering.

Everyone is looking for the magical WORA, however the reason Java failed at that, and Electron sucks, is that they are all leaky abstractions.

In reality, for delivering a good experience, knowing the underlying platform is still a requirement, and it only adds up in layers to debug, OS APIs to wrap, build tooling to integrate, IDE plugins for the platform SDK interoperability, and so on.