This is brilliant work and I love the Qt ecosystem.
Can’t help but imagine the things we could’ve had if Apple wasn’t pushing the horror of Swift down everyone’s throat by blocking alternatives in so many tiny ways.
Looks great, and it has some features and polish that I would love Logseq to have natively, but overall I prefer the customisation potential of logseq with tags, templates, block refs etc.
Great write-up! It would be useful if various PKMs would settle on a similar format for recording (nested) tasks, dates and metadata, as it seems to have become the standard way to store kanban boards and similar 'enhanced' views. Currently there exist various strategies ranging from embedding JSON as comments to esoteric (non-markdown) formats, often trailing at the end of each task. This makes the source look cluttered and difficult to edit/navigate.
IMO, metadata (such as date ranges) could instead be stored as empty links leading each task (or by showing a custom placeholder symbol such as '@'), paving the way for a 'linked' data format while resulting in a same-width list for easy lookups and editing:
For instance, the above tasks would link to the virtual '30..31.md' and '29..30.md' files which collect all backlinked tasks for the provided daterange (akin to Obisidan/Logseq/etc).
In an ideal world, the task marker could hold a custom symbol and linked metadata itself, but would result in non-standard (GFM) markdown:
I've worked with QtWidgets and I have mixed feelings about the extensive (1) documentation about integrating C++ with QML and QtQuick.
Here's a quick history lesson (as I understand it):
- QtWidgets the original C++ QT graphics library.
- Around 2008 or something, they introduced QML and QtQuick. This was basically declarative UI + javascript for logic.
- QtWidgets is considered 'done' and all new features and dev is basically happening in QML / QtQuick.
- ...as described in this post, the current recommended 'best practice' is to avoid writing a pile of javascript spaghetti and bridge between C++ for logic and QML for UI.
So, long story short: We've moved from a robust C++ framework, to a javascript backed framework to 'appeal to the masses', but it's kind of hard to build a whole application that way, and so 'best practice' is to go back and write your logic in C++.
Does that seem weird to anyone else?
> While powerful, Qt Widgets lack some essential modern features, in my opinion, such as declarative UI, bindings, behaviors, anchors, and more. These features enable the creation of beautiful, animated UIs simply and quickly, as seen in QML.
Hum. QML is certainly declarative.
I'd love to see a breakdown of specifically what features you can't do with widgets, and why having a js <-> c++ bridge is better than not having one.
Don't get me wrong; if you want to write a 100% javascript QML application, that's cool. Go for it... but when you're writing a C++ application and choosing, deliberately, to implement you UI in another language and communicate with that UI via a bridge...
...well, let's just say, if you had another option (eg. just use C++), wouldn't that make sense?
Couldn't you do the the same thing with react native components and logic in C++? (You could) Why is this any better than just writing a react native UI? Or a flutter UI?
You could do any kind of UI, even fully native, if you're implementing the application is c++ and then just doing cross language <-> to the ui.
I used Qt back in the day, pre-Nokia, when it was just QtWidgets for cross-platform (Linux/Windows/Mac) desktop apps. I just wanted a decent C++ library/API to create the GUI for a Linux app (real-time spectrogram). It was a great for this, although I was never a fan of MOC - I wish they had committed to a pure/native C++ design.
For me Qt lost it's way when Trolltech was acquired by Nokia, and the focus became mobile rather than desktop, with different UI requirements resulting in QML/QtQuick being added.
Maybe the earlier addition of QtScript (or even MOC!) was a foreshadowing of what was to come, but in any case what had been a great cross-platform desktop UI toolkit, and the primary C++ one for Linux (with GTK being more C focused) ended up orphaning it's desktop roots to focus on mobile instead, having become a sprawling mish-mash of languages, GUI component technologies and scripting.
What exactly - from an end user perspective - do you worry about? Performance? I already showed in my benchmarks that my block editor is faster than all block editors on the market - even more than those that uses native frameworks.
And as I wrote to another commenter: "if you avoid writing Javascript code in your QML components, than most of your executable will end up being compiled C++ code. If you do write Javascript code in your QML components, than it could also be compiled to C++ code using the QML script compiler[1[2]."
BTW, I agree that there's not enough good documentation about communicating and connecting C++ and QML code. I hope I could write some tutorials for that in the future as I struggled with that when first delving into this.
I also think Qt/QML is a very underrated technology. I have been developing a handwritten notes for Linux/Windows using Qt Quick for quite some time [0]. The experience has been a mixed bag though.
I've encountered tons of bugs (many of them still unfixed) that I had to find very ugly workarounds for.
Also, while a declarative style UI language can have a lot of benefits, it does also have a lot of limitations. For example, in my application I required a (infinite) canvas to rendering the ink strokes, which would be a perfect job for QGraphicsView, but there is no equivalent in Qt Quick. So I had to roll out my own component (which uses Skia under the hood), but that was quite painful. Since Qt 6, the Qt Quick scenegraph is rendered with a custom RHI backend (abstracting over Vulkan, Metal, OpenGL and DirectX) which I had a lot of trouble integrating with third party engines (I really wish they had a WebGPU backend).
Qt Widgets is fantastic, but now dated since it has not been updated for the modern world. Plus it is C++, which a lot of devs dislike.
QML feels like a refresh with great ideas, bringing declarative UI and reactive programming. Where it falls short for me is it does not have feature parity with Qt Widgets, so you end up having to roll up your own components, wasting a ton of time. Dealing with layouts in QML is also an exercise in frustration.
Not having an extra language to deal with and so many features being just a flag away is why I decided to go with QtWidgets for the GUI of a project I am working on at work. And it is so nice to use despite being very old. For the graphically intensive parts I am just using Vulkan. I understand this might not be enough for all types of GUIs though and just wish QtWidgets had some sort of GPU acceleration.
I've always lamented that QML and QtWidgets are separate rather than integrated. It would be awesome if there was a declarative way to specify much of the same information that you have to specify programmatically with QtWidgets (e.g., the cumbersome process of defining nested sizers), and then you could write code to handle the actual "business logic". But instead we have two totally separate UI frameworks where you can either use the nice native QtWidgets or you can have a nice declarative UI definiton, but not both.
> and Microsoft tends to abandon each new UI framework every five years
So use the old one? Your first link literally mentions two ancient frameworks that are not abandoned (win32 and MFC)
But you're right
> So, it's more useful to ask: what do we expect from good native apps?
The challenge, though, is there isn't really a good comprehensive list of those things the would allow you to compare the framework you use to native. And you can't patch everything if you don't even know where the holes are
So that why this is correct...
> Qt apps typically don't look or behave exactly like native apps,
... but this is theoretical
> I'm going to argue that they can.
Yes, of course they can, but to do in reality requires too much effort, so you end up with with the state mentioned in the first part of the quote. (that's the whole point of the framework - to handle that complexity for you, and if the whole huge QT can't do that even though "they can" why do you think a single dev can?)
> At the same time, I've grown fond of Markdown. The idea that all my notes are formatted in a syntax that will essentially last as long as computers exist—plain text—is very reassuring
That's a very common mistake as well. It's true only for very primitive parts of markdown, which is rather limiting for notes, but if you venture into the more complicated extensions/HTML area, then it's not different from any other format - as long as the format codecs work, it's usable. Like, even word doc is plain ugly XML text, so will exist forever?
> rendering the underlying Markdown when the cursor is inside a Markdown-formatted text—was quite challenging.
Indeed, because it's not fit for purpose.
> For example, if the cursor is inside this bold and italicized text it will show as *bold and italicized text*.
So you now have constant layout shifts when you simply move your caret around.
> The challenge, though, is there isn't really a good comprehensive list of those things the would allow you to compare the framework you use to native. And you can't patch everything if you don't even know where the holes are
> Yes, of course they can, but to do in reality requires too much effort, so you end up with with the state mentioned in the first part of the quote. (that's the whole point of the framework - to handle that complexity for you, and if the whole huge QT can't do that even though "they can" why do you think a single dev can?)
Yep. This is why I'm now working on a framework built on top of Qt that takes care of all these small but important details that takes time to figure out that Qt isn't equipped with built-in. For example, smooth swipeable StackView on mobile, support for native text handling on mobile, smooth scrolling on ListViews (that's horrible now), etc etc.
> So you now have constant layout shifts when you simply move your caret around.
That's a feature in such apps (look at Bear, etc). I plan to have an option to disable that so the editor is entirely WYSIWYG.
I've worked with Qt about 15 years writing several applications both for work and for fun and overall I think it's a really powerful platform. Not without it's idiosyncrasies and quirks of course.
That being said I find that QML is complete trash. It's fine for simple UIs with minimal logic and prototypes but for anything beyond that you'll always need to implement the logic in C++ and this is where the pain enters the picture. A lot of effort will be spent maintaining the glue code that lets the two worlds comminicate. The tooling is poor and QMLs poor typing makes it hard to ever change anything from types to available methods..
Generally speaking QML has terrible shortcomings in its lack of good typing, debugging abilities, error reporting or general maintainability of the code. It's your typical "write once" platform where the cost comes later if/when you need to maintain and evolve the software later on.
> There's a misconception that you can't statically link your app when using the open-source LGPL version of Qt. From my reading of the LGPL license this doesn't appear to be the case. The LGPL allows you to statically link your app as long as you provide the object files and allow users to relink your app with a different version of Qt. I've observed many people spreading this misinformation about only being able to dynamically link with the LGPL version of Qt.
I mean... is it possible to statically link while giving an option to re-link an application using different set of libraries?
I developed a new database management system and I needed a GUI application to use as an admin tool for it.
I decided to build it using Qt (Qt Widgets in c++) mainly because my whole data engine is also in c++. Since it just uses standard windows and dialog boxes; I haven't felt the need to keep up with the latest Qt version. I am still using Qt 5 (I think revision 13 or 15).
I have been contemplating moving to Qt 6. Have users noticed a big difference (e.g. performance) between Qt 5 and Qt 6?
24 comments
[ 2.3 ms ] story [ 47.4 ms ] threadIMO, metadata (such as date ranges) could instead be stored as empty links leading each task (or by showing a custom placeholder symbol such as '@'), paving the way for a 'linked' data format while resulting in a same-width list for easy lookups and editing:
For instance, the above tasks would link to the virtual '30..31.md' and '29..30.md' files which collect all backlinked tasks for the provided daterange (akin to Obisidan/Logseq/etc).In an ideal world, the task marker could hold a custom symbol and linked metadata itself, but would result in non-standard (GFM) markdown:
It would be up to the editor to render this metadata accordingly.Here's a quick history lesson (as I understand it):
- QtWidgets the original C++ QT graphics library.
- Around 2008 or something, they introduced QML and QtQuick. This was basically declarative UI + javascript for logic.
- QtWidgets is considered 'done' and all new features and dev is basically happening in QML / QtQuick.
- ...as described in this post, the current recommended 'best practice' is to avoid writing a pile of javascript spaghetti and bridge between C++ for logic and QML for UI.
So, long story short: We've moved from a robust C++ framework, to a javascript backed framework to 'appeal to the masses', but it's kind of hard to build a whole application that way, and so 'best practice' is to go back and write your logic in C++.
Does that seem weird to anyone else?
> While powerful, Qt Widgets lack some essential modern features, in my opinion, such as declarative UI, bindings, behaviors, anchors, and more. These features enable the creation of beautiful, animated UIs simply and quickly, as seen in QML.
Hum. QML is certainly declarative.
I'd love to see a breakdown of specifically what features you can't do with widgets, and why having a js <-> c++ bridge is better than not having one.
Don't get me wrong; if you want to write a 100% javascript QML application, that's cool. Go for it... but when you're writing a C++ application and choosing, deliberately, to implement you UI in another language and communicate with that UI via a bridge...
...well, let's just say, if you had another option (eg. just use C++), wouldn't that make sense?
Couldn't you do the the same thing with react native components and logic in C++? (You could) Why is this any better than just writing a react native UI? Or a flutter UI?
You could do any kind of UI, even fully native, if you're implementing the application is c++ and then just doing cross language <-> to the ui.
Right?
[1] - https://doc.qt.io/qt-6/qtqml-cppintegration-overview.html
For me Qt lost it's way when Trolltech was acquired by Nokia, and the focus became mobile rather than desktop, with different UI requirements resulting in QML/QtQuick being added.
Maybe the earlier addition of QtScript (or even MOC!) was a foreshadowing of what was to come, but in any case what had been a great cross-platform desktop UI toolkit, and the primary C++ one for Linux (with GTK being more C focused) ended up orphaning it's desktop roots to focus on mobile instead, having become a sprawling mish-mash of languages, GUI component technologies and scripting.
And as I wrote to another commenter: "if you avoid writing Javascript code in your QML components, than most of your executable will end up being compiled C++ code. If you do write Javascript code in your QML components, than it could also be compiled to C++ code using the QML script compiler[1[2]."
BTW, I agree that there's not enough good documentation about communicating and connecting C++ and QML code. I hope I could write some tutorials for that in the future as I struggled with that when first delving into this.
[1] https://doc.qt.io/qt-6/qtqml-qtquick-compiler-tech.html
[2] https://doc.qt.io/qt-6/qtqml-qml-script-compiler.html
I've encountered tons of bugs (many of them still unfixed) that I had to find very ugly workarounds for. Also, while a declarative style UI language can have a lot of benefits, it does also have a lot of limitations. For example, in my application I required a (infinite) canvas to rendering the ink strokes, which would be a perfect job for QGraphicsView, but there is no equivalent in Qt Quick. So I had to roll out my own component (which uses Skia under the hood), but that was quite painful. Since Qt 6, the Qt Quick scenegraph is rendered with a custom RHI backend (abstracting over Vulkan, Metal, OpenGL and DirectX) which I had a lot of trouble integrating with third party engines (I really wish they had a WebGPU backend).
[0] https://scrivanolabs.github.io
QML feels like a refresh with great ideas, bringing declarative UI and reactive programming. Where it falls short for me is it does not have feature parity with Qt Widgets, so you end up having to roll up your own components, wasting a ton of time. Dealing with layouts in QML is also an exercise in frustration.
Oh, yes!
So use the old one? Your first link literally mentions two ancient frameworks that are not abandoned (win32 and MFC)
But you're right
> So, it's more useful to ask: what do we expect from good native apps?
The challenge, though, is there isn't really a good comprehensive list of those things the would allow you to compare the framework you use to native. And you can't patch everything if you don't even know where the holes are
So that why this is correct...
> Qt apps typically don't look or behave exactly like native apps,
... but this is theoretical
> I'm going to argue that they can.
Yes, of course they can, but to do in reality requires too much effort, so you end up with with the state mentioned in the first part of the quote. (that's the whole point of the framework - to handle that complexity for you, and if the whole huge QT can't do that even though "they can" why do you think a single dev can?)
> At the same time, I've grown fond of Markdown. The idea that all my notes are formatted in a syntax that will essentially last as long as computers exist—plain text—is very reassuring
That's a very common mistake as well. It's true only for very primitive parts of markdown, which is rather limiting for notes, but if you venture into the more complicated extensions/HTML area, then it's not different from any other format - as long as the format codecs work, it's usable. Like, even word doc is plain ugly XML text, so will exist forever?
> rendering the underlying Markdown when the cursor is inside a Markdown-formatted text—was quite challenging.
Indeed, because it's not fit for purpose.
> For example, if the cursor is inside this bold and italicized text it will show as *bold and italicized text*.
So you now have constant layout shifts when you simply move your caret around.
Do UIs built with MFC still look like they were built in the 1990s?
> Yes, of course they can, but to do in reality requires too much effort, so you end up with with the state mentioned in the first part of the quote. (that's the whole point of the framework - to handle that complexity for you, and if the whole huge QT can't do that even though "they can" why do you think a single dev can?)
Yep. This is why I'm now working on a framework built on top of Qt that takes care of all these small but important details that takes time to figure out that Qt isn't equipped with built-in. For example, smooth swipeable StackView on mobile, support for native text handling on mobile, smooth scrolling on ListViews (that's horrible now), etc etc.
> So you now have constant layout shifts when you simply move your caret around.
That's a feature in such apps (look at Bear, etc). I plan to have an option to disable that so the editor is entirely WYSIWYG.
That being said I find that QML is complete trash. It's fine for simple UIs with minimal logic and prototypes but for anything beyond that you'll always need to implement the logic in C++ and this is where the pain enters the picture. A lot of effort will be spent maintaining the glue code that lets the two worlds comminicate. The tooling is poor and QMLs poor typing makes it hard to ever change anything from types to available methods..
Generally speaking QML has terrible shortcomings in its lack of good typing, debugging abilities, error reporting or general maintainability of the code. It's your typical "write once" platform where the cost comes later if/when you need to maintain and evolve the software later on.
Wow just noticed my blog post is on the front page! Will try to respond to all comments here soon.
I mean... is it possible to statically link while giving an option to re-link an application using different set of libraries?
I decided to build it using Qt (Qt Widgets in c++) mainly because my whole data engine is also in c++. Since it just uses standard windows and dialog boxes; I haven't felt the need to keep up with the latest Qt version. I am still using Qt 5 (I think revision 13 or 15).
I have been contemplating moving to Qt 6. Have users noticed a big difference (e.g. performance) between Qt 5 and Qt 6?