- OctoMYQtDepends: Our helper to include dependency on all the Qt modules that OctoMY™ needs
- OctoMYLibProbe: Our helper to enumeratelibrary folders
- OctoMYFiles: Our helper to list source files in a project that we care about (this is equivalent to tile fil Group in our StaticLibrary above).
OctoMY™ Supports Ukraine! https://u24.gov.ua/
This is the official blog about the development of OctoMY™, the robot platform for you!
Qbs tutorial part 5/5: Apps
Qbs tutorial part 4/5: File Groups
When specifying files, you can use the wildcards "*", "?" and "", which have their usual meaning. By default, matching files are only picked up directly from the parent directory, but you can tell Qbs to consider the whole directory tree. It is also possible to exclude certain files from the list. The pattern ** used in a pathname expansion context will match all files and zero or more directories and subdirectories.
Qbs tutorial part 3/5: Libraries
Qbs tutorial part 2/5: Tests
- testNames - a list of the names of tests found in our project
- testFolders - the folders for each of our tests
- testFiles - the test.qbs file for each test
- testDefines - some defines that refer to our test names
Qbs tutorial part 1/5: Main project file
After spending a few gruelling weeks porting my brain to "think in Qbs", I felt ready to take on the non-trivial task of comitting 100% to porting the build system of OctoMY™ from qmake to Qbs. This was in large part possible thanks to the super-human patience and wisdom demonstrated by the super awesome Qbs community, which lives on Discord. Shoutout to ABBAPOH, Psy-Kai and Janet Blackquill, your help was indispensible!
I thought I would document my decisions here for future reference and maybe to serve as a template for others trying to get into Qbs with their non-trivial projects. I will also introduce some concepts and tips & tricks that I picked up along the way.
So first up: top level project structure. OctoMY™ is divided coarsely into 3 parts:
- Apps - The actual programs that we run when we want to use OctoMY™
- Libs - The software components which contains the code of OctoMY™, liked into the apps
- Tests - A bunch of programs, each testing one aspect of the codebase
- import qbs.FileInfo: This is how we get access to other types and script libraries in qbs. In this case, we need the FileInfo service provided with qbs that allows us to do file operations.
- Project: This indicates that we are defining a new qbs project. "Project" is a qbs type that represents a project. It is used to collect other items inside of it similar to a folder in a filesystem. It can contain other items directly inside of it, or it can refer to files which in turn will contain such items. In our case we only refer to other files through the references property (see below).
- name: This is what shows up inside QtCreator as the name of your project. If you leave it out, Qbs will use the file as a fallback. In other words, this property is optional.
- qbsSearchPaths: This points to where qbs will look for our user defined reusable components, of which there are several in the OctoMY™ project. You don't have to use this feature, but it will serve you well to use it once your Qbs project grows beyond the trivial "Hello World" examples. In this case we tell qbs that this project will look for our components in ./integrations/qbs folder, and you can see (in theproject tree at the top of this article) that it contains some components that we will use from sub projects, such as OctoMYTestProbe.qbs.
- references: References is a list of files that Qbs should read and include in the project. Since we are currently defining a project, we want to include the actual sources and libraries and tests of the project, and that is done by referring to the qbs files which we use to find them. In this case we include 3 sub-projects via the libs.qbs, apps.qbs and test.qbs files.
OctoMY™ will migrate from qmake to Qbs
OctoMY™ has from this date forward decided to standardize on Qbs and migrate from qmake to Qbs. qmake project files will remain for some time until we see that the Qbs project files replace them perfectly before they will be removed. Thanks for all the fish qmake!
This might seem like a strange decision since Qt itself has selected CMake in favor of their own Qbs project, however the benefits Qbs will have to OctoMY™ is substancial compared to what CMake will bring. So here is the list of reasons why OctoMY™ will chose Qbs over CMake:
- CMake is arguably hard to work with, inelegant, cargo-culty, full of legacy, slow, inflexible, archaic and challenging to like
- The main selling point of CMake is that "everyone is using it" and so you will find that a lot of projects support CMake and consuming these projects as dependencies with CMake will be simpler. This is however not relevant for OctoMY™ because we have a strict policy of not depending on any external libraries except Qt framework itself. All the sources are in the tree.
- CMake will allow us to export our project as a dependency to others. Again, this is a mute point as OctoMY™ will not be consumed as a source level dependency.
- Qbs is well supported by Qt (they developed it after all)
- Qbs is well integrated into QtCreator which is very important for OctoMY™ since we depend on that as our main development tool
- Qbs is modern
- Qbs is flexible
- Qbs is fast
- Qbs is multi-platform and has good support for all the platforms that OctoMY™ do and will need support for in the future
- Qbs is open-source
- Qbs is well written (if you peek inside the sources of Qbs, you will probably like what you see)
- Qbs acts as a server that talks to QtCreator over a pipe. This means that QtCreator will better reflect the internal state of Qbs at any given time. For example, it would automatically update the project tree view in QtCreator whenever I saved changes to the project (*.qbs) files, and Qbs would act as expected in many cases where qmake just would not. This gave a surprisingly fluid experience that is addictive.
- Qbs really maxes out your CPU at build time and spends almost zero time on house-keeping. The system is really fast at dependency checking and re-building only the necessary files making your developer experience quite pleasant.
- It has not yet screwed up dependencies even once even in my very demanding project and with me as a demanding user which is quite impressive. qmake would require a full re-build on a regular basis.
- While Qbs works out of the box with Qt, it is not limited to Qt. It has extensions to support a whole load of platforms, languages and frameworks and can integrate with a bunch of developer tools including IDEs, other build tools and more. Especially, Qbs aims to tackle the not-for-the-faint-of-heart builds that target embedded hardware, mobile platforms and other quirky and archaic targets full of demanding requirements such as cross compilation and advanced tool-chain management. Impressive! This means we have some wiggle-room for futer expansion of the OctoMY™ project
- There is a Qbs Discord Server where devs and users of Qbs hang out. This has been one of the best discoveries so far. The amount of patience and wisdom the core team have showed me as a annoying beginner is truely amazing.
- Qbs will hopefully grow and get a much deserved boost in adoption!
- The Qbs output is very sparse and debugging Qbs is very difficult for a beginner in the start before you start udnerstanding how it all works under the hood. The log output windows in QtCreator will all just be completely empty even if there definitely are some problems. There are options to add more verbose output, but it is well hidden and off by default. Also the "max verbose" option is not possible to swithc on at all.
- "printf debugging" is hard since Qbs is declarative. It is definitely possible but very quirky.
- Some of the features in Qbs have severe pitfalls that you are expected to pick up on by yourself. Here are some examples:
- Group prefix is a string, and NOT a file entity. In other words, "someFolder" and "someFolder/" means different things.
- While the documentation is "complete" it is kind of sparse still, and leaves you wondering about implementation details in many cases. For example, does Group.excludeFiles support wildcards like Group.files or not? (The answer is yes, it does, but the documentation does not mention this).
Old dog learns new tricks: Qbs edition
So I had a go at QML a few years ago and it seems like a cool technology and definitely has a lot of potential for creating good user interfaces.
Getting started with QML is easy enough thanks to the examples directly present in QtCreator. You can get up and running quickly and adapt an example to what you want to achieve.
After a while you will stumble upon a bunch of more or less fundamental questions like:
- How can I interface QML with my existing C++ code?
- How can I get the filename and path of the current module from code?
- What is the meaning of life?
Brief OctoMY™ update 2023
These are the changes scheduled for early to mid 2023 in the OctoMY™ project:
- Good bye Qt5 hello Qt6
- Refactoring of subsystems relating to media such as speech, video streaming etc
- Once-over of whole project
- New build system
Good bye Qt5 hello Qt6
New build system
My pet peeves with Qt and QtCreator in 2023
I took a break from C++ and Qt for a few years as I was working on other stuff, and when I came back a unique opportunity presented itself; I could look at Qt from an outsider's perspective not being as biased as before. Well I am biased, Qt is my all time favorite platform so who am I kidding. But I have seen the world beyond and just maybe I can spot some trends where Qt moved while I was gone? This is in essence my mandatory rant on UX in programming tools, with Qt & QtCreator as a backdrop.
NOTE: I am looking at this from a community perspective. I am sure if you pay for Qt your experience will differ in some respects.
Installing Qt is still terrible, but a little better than it used to be. It still features an install wizard straight from the 1990s era, but at least it has green color to bring it into the future.
Seriously, the wasted potential is staggering. I wish someone would appoint me UX lead on the installer team, I would have a go at setting things straight. Seriously, get in touch! I will let the real-time html layout popping go I promise!
To be fair here are the options:
- Install ancient mangled version from your favorite Linux distro's repository (not recommended)
- Build from source.
- Just rememer to schedule 20 minutes of your time to actually find the download link on the qt.io website. This is what happens when the marketing people takes over. I mean they really tore a page from the the old Microsoft 1990s era FUD tactic playbook here. The only contender is the delete account wizard in the Boo dating app.
- Once you have the source.... uhm. ok so yes. I will... follow these steps and. Uhm.. It is almost as if someone made it extra hard on purpose.
- Use some 3rd party Docker image that encapsualtes the build. Because there are no official ones. Seriously, Qt company has no official Docker images to use their shit in 2023.
- Download online installer:
- On linux; a payloaded bash script with a windows style install wizard inside.
- On OSX; an img with a windows style wizard inside.
- On Windows; a native executable with a windows style wizard inside.
- The wizard has the worst UX of any installer I have ever used, and I have used alot of installers in my lifetime. It is actually inexcusable.
- Download offline installer:
- Nope, can't find it anymore. Is it there? Well you did a good job hiding it. PEBCAK.
- Download prebuilt binaries in ZIP format.
- I don't know if they even exist because all the files are so well hidden. If the actually exist then I am sorry for being a retard. PEBCAK.
Migration to Qt6
Migrating from Qt5 to Qt6 in my projects was actually not that bad. It took a day of search/replace/copy/paste for a fairly large codebase. Luckily I had lot's of tests to verify my changes but still the experience was good overal. QRegularExpression and QMedia* were the most hard to adapt.
The documentation spesific to migration was OK, but it could definitely have been much better. I would have loved to see a dropdown at the top of documentation pages where you could select the version you care about instead of fumbling around with google to find the relevant version. Also a collapsed comment on migration next to each deprecated member would be really helpful, instead of having all migration stuff collected on one big page.
Good documentation is one of the best sides of Qt so not complaining too much here!
I know this is a controversial topic. A lot of people like CMake, and a large minority dislike it. And I have a fairly strong opinion myself. Here is my breakdown;
I think that the people that like CMake like it for a completely different reason than why the other people dislike it. The people that like CMake are very pragmatic. They made it work with CMake and then it works and now we can go do something else. Or they were told by their non-technical boss to use CMake beacuse "customer X uses CMake and we must align with them".
The people that don't like CMake are more opportunistic and perfectionistic. I suspect there is a good overlap in this group with those that liked Qbs for this reason. They just can't look at CMake next to Qbs or qmake and think that CMake is the better choice. This group think (and I agree with them) while the rest of industry selected CMake, that alone is not a good enough argument to use it. Instead we should strive to surpass it on every metric beyond "popularity by mediocre middle managers" (to put it on point).
File types support
This peeve goes way back. Unfortunately it has worsened over time. It has several facets. I will start with the most annoying and obvious for me.
- Open source in editor, make changes and save
- Open terminal, invoke build command
- Open debugger invoke program, debug, find error
- Go back to editor make changes
Mandatory rant on UX in programming tools
I am not alone thinking about this, my question about encoding video from a sequence of QImages from 6 years ago has 63 votes and still no resolution.
Finally a list of minor anoyances in QtCreator that I felt needed to come of my chest after years of brooding.
- The refresh action is missing in the file tree so now I find myself closing and reopeng the program every time a file has changed outside QtCreator. Luckily closing and opening QtCreatos is now super fast for some reason. It feels really snappy, so good job on that at least...
- The swap between source and header key combination is not <ctrl>+<tab> by default. C'mon guys.
- There is no key combination for switching between design view and editor view, and for some inexplicable reason, I am always moved to look at my design in read-only XML. dafuq?
- The editor view for design is READ ONLY? I have to open an external text editor to edit the XML for my design? SERIOUSLY? Why don't you just remove editor view entirely, and make it a special operation to edit for those rare cases when that is even remotely relevant? Am I the only one who is annoyed by this?
- Design view still takes up the whole screen. On modern 4k displays this is a travesty, a UX abomination. The Designer editor should really present inside a normal editor view.
- There is no "collapse all" and "uncollapse all" buttons in tree view. I have to dig thorugh a submenu. I might as well collaps and uncollaps the tree manually and it will be faster than finding those actions *sigh*.
- There are still issues with scaling for high DPI screens. The issues view cannot be zoomed like the other views(??) and is sometimes displaying text in way too small font.
- The "split side by side" is wonderful, however moving the separator is not intuitive. Expected is that "everything stays the same except the size of the two views next to the separator will change in size. Actual is "depending on which separator I move, SOME windows will stretch and other not". It should be super easy to fix, just remove the separator widget in place of a horizontal layout and add widgets to take mouse dragging to change the layout. Why is this not fixed ages ago?
- It is sometimes desirable to view files that are NOT in your project in the tree view. Yes I know, radical thought. How about adding the option to render all files found in directory with the files that are not part of the project grayed slightly out? You could even add an option to "include in proejct". Radical I know.