Utilizing Qt As A Unique Way For Developing Cross-Platform Applications
Some people think that the hardest part of developing a software application is coming up with the idea and then creating a feature set outline and wireframes leading to a Statement of Work (SoW). And yes, that stuff is important and takes real time to create; and the fact is that development can’t really start till it is done. But choosing the tech stack - what technology or platform will be used to develop the application - can be one of the hardest and most difficult choices to make.
Not too long ago, starting an application development project and choosing a tech stack often meant making tough decisions right from the outset. Typically, we had to choose just one platform to support—whether web, native iOS, or native Android—based on the preferences and location of our target users. If the business model proved successful, we would then expand to additional platforms. However, this often involved duplicating the same development efforts across separate teams for each new platform, which could quickly become expensive and time-consuming.
The IT industry has always sought the ultimate programming language or cross-platform framework that could meet all requirements in one go. While this is a nearly impossible goal, there have been several promising attempts over the years, such as PhoneGap, Xamarin, Unity, Qt, NativeScript, Node.js, Electron, Framework7, Ionic, React Native, Kotlin, and Flutter. Today, we are fortunate to have a wide range of solid options to choose from. Many of these frameworks are based on JavaScript, a language familiar to a large number of developers, making it easier to find skilled professionals to work on projects.
Annoying Side Effects
JS has some annoying “Side Effect” for developers due to the way it was architected. An example is that the number of open source packages that developers have to choose from is surprisingly high. Just try to create a new project; your project folder size could be a few hundreds of megabytes with many files organized in many folders from day one.
Also, if you are not an experienced JS developer, you probably need someone to help explain how it all works; which files are auto generated during the development process, which files aren’t, how to make set-up the basic settings, how to manage versions and new packages and which ones are you allowed to touch and so on.
In other words, the barriers to being able to use a new JS platform are high. For security reasons (and because of common sense) JS application packages need to be constantly updated. Most updates do not cause any difficulties, but sometimes you need to refactor your code to be compliant with some major upgrade of specific packages. For dependency reasons, sometimes you also need to switch the implementation of a feature from one package to another, meaning you have to modify perfectly working code lines as well.
The more packages you use, the less chance you have to continue your work seamlessly after a few weeks of project pause. Sometimes you wait for the design, other times you have to let the partners, testers, clients or co-workers play with the actual version for a while in order to receive good quality feedback in return. You can easily end up doing way too much maintenance rather than pure and satisfying development that moves the product forward.
To sum it up, moving to and using a JS platform to develop cross-platform apps is challenging due to a steep learning and experience curve and it tends to need a lot of maintenance even during development and after as well.
Another Way
If your background is web development, you probably would say “business as usual”. If you are coming to JS from another tech stack, say embedded development (such as myself), you might want to try another way to do a cross platform app.
For me, most C/C++ projects are easy to revisit and reuse long after I have finished them, even if I haven’t touched them in years. Then don’t need much maintenance and so if you were used to this, going to a JS platform would be a very different experience.
This difference really hit me like a brick wall when I started to learn JS, and after several months of struggle I decided I needed to look for a different cross platform development tech stack, something more aligned with my C/C++ experience.
When I first came across Qt, I wasn’t sure how it would hold up in this regard. However, I decided to give it a try because the programming languages it relies on - Python and C++ - were already familiar to me. Choosing the right cross-platform framework isn’t always straightforward; because like anything, each option comes with its own set of strengths and weaknesses, and finding the best fit often depends on individual needs and preferences.
Before committing to Qt, I experimented with Flutter. After doing some research, Flutter seemed like a logical choice. It isn’t based on JavaScript but Dart, offering rapid development cycles and quick time-to-market. Many of my colleagues excel at building sleek, modern applications with Flutter, and it’s a great tool for them. However, I quickly realized that Flutter didn’t align with my personal preferences or workflow.
Instead, I decided to embrace Qt, fully aware that I’d be trading one set of pros and cons for another. But for me, Qt’s unique advantages made it the better choice.
The DL On Qt
Qt has a large and active community and boasts a history spanning over 20 years. However, it’s unlikely to dominate the development landscape for two main reasons: licensing and its reliance on C++.
While Qt is open-source, it’s not entirely free. For commercial use, you’ll need to pay a licensing fee unless you comply with the LGPL license. The smallest commercial plan costs around $500 per year for small companies under a certain income threshold, while larger companies can expect to pay around $3,500+ annually. Although the LGPL license doesn’t require you to share your source code if you use dynamic linking, the licensing model can still be a deal-breaker for many developers and businesses.
The second potential drawback is C++ itself. For companies without in-house C++ expertise, hiring C++ developers can add significant costs (outsourcing to a company like ScreamingBox can reduce this cost depending on project size). While this may not be an issue for embedded projects, which typically require C++ developers regardless, it can deter businesses focused on other types of applications.
Let's say we are at peace with the disadvantages now**,** and it is time to talk about the benefits. One of Qt’s major advantages is its strong support for embedded systems - an area where many other cross-platform frameworks fall short. This makes Qt a standout choice for developers working on embedded projects despite the challenges posed by licensing and language requirements.
How does Qt work out for someone who starts learning it? In my experience, getting to the level of being productive was easier than I thought before. Compared to the Javascript world or Flutter / Dart, the barrier of being able to use it seemed significantly lower.
One could say that the real barrier here is having a solid C++ knowledge, but it isn't completely true. You don't need to be a master of inheritance, abstraction, templates, operator overloading and other obscure things you may face at a C++ job interview. In order to catch up with Qt quickly, all you need is a simple C knowledge, the basics of C++, and the ability to read documentation and code examples.
Real World Example
My first real project with Qt is a time tracking system: I'd like to replace some cloud infrastructure in our company to cut costs, be more flexible and have more control over our sensitive data. I already had the backend part of it from a previous attempt, a Python Django + HTML / CSS / Javascript frontend project from 2 years ago. Guess what, I wasn't satisfied with the Javascript part, but Django was surprisingly effective and easy to learn.
I decided to reuse the Django backend and build a Qt frontend for it, and as a result, have an iOS / Android / Web / Windows / Mac / Linux app. After 200 hours of development combined with learning Qt, I was able to make a demo with the 1st milestone functionalities. I feel I am productive now, I can predict how much time I need for completing user stories, which wasn't the same while I was trying to do the same with JS or Flutter.
During this learning & development curve, I have never ever felt that my project folder is a house of cards which can collapse any time I update or try some configuration setting. No need to start over by reinstalling, creating a new project folder, importing the actual source code or doing a painfully long research just to make the already OK code work again as it worked yesterday.
When I take a look at my Qt project folder, I only can see one file I didn't write by hand, the Makefile. I don't have hundreds of megabytes there, but hundreds of kilobytes of my own code, a couple of images and icons, and that's all. While writing this article I got a Qt update. Besides doing a project cleanup and build, it worked the same way as yesterday, no code refactor needed. This is what I got used to in embedded development, and this is what I demand when learning new systems.
Is It From Here?
At first, Qt seemed like it was from a strange parallel universe, where every important and already well known phenomenon has its own name starting with Q, like “QString”. Why does it have QString, why did they reinvent the wheel? I was just about to avoid the world of the web that reinvents things every 4-5 years. But it turned out it is the other way around: QSting had been part of the Qt library way before std::string came to life.
On top of that, QString is more rich and platform independent. Another interesting part of the Qt ecosystem is Signals and Slots, which allows you to do bidirectional communication between objects. Sure you could achieve something similar by exchanging and storing object references, but Qt Signals is an elegant and thread safe solution to build and maintain complex applications.
Learning a new environment takes a lot of time and effort. It is obvious that a few hundreds of working hours are not enough to cover even the most important components of a cross platform system. There are many types of widgets and UI elements that we need to understand in order to create a modern application. Most probably we have to deal with networking, memory management, threads, database access, and many other things related to mobile devices.
Who has the chance to discover all of that in their free time? Who will pay for the learning sessions? Clients in general are reluctant to pay a developer just to build up a new skill.
To make learning or adopting Qt (or any new framework) faster and more cost-effective; developers should consider creating practical, reusable projects rather than experimental ones in order to learn Qt. You should also separate the Qt-dependent code from the core business logic.
For instance, if you happen to try Qt to build a nice UI for your business logic, separate your source code into at least 2 parts: Qt dependent part, and Qt independent part. If Qt doesn’t meet long-term needs, the business logic can still be paired with another UI framework, safeguarding the investment of time and effort.
If you would like to read more about why it is a good idea to separate certain parts of your source codes inside your project, take a look at my previous articles about Test Driven Development (TDD) Part1 and Part2
Conclusion
Choosing a cross-platform framework for app development can be daunting, given the variety of options available. Each with their own strengths and weaknesses. Qt stands out as a powerful but unrecognized choice; particularly for developers who value flexibility and performance as well as the other benefit of supporting embedded systems.
While JavaScript-based frameworks like Flutter, React Native, and Ionic dominate the scene due to their speed and widespread developer familiarity, Qt offers distinct advantages. Its foundation in C++ and Python allows for robust, high-performance applications, and it excels in scenarios requiring advanced graphical interfaces or embedded systems support - areas where many JavaScript-based platforms fall short. However, Qt’s reliance on C++ and its licensing costs may deter businesses without C++ expertise or budget flexibility.
For those willing to navigate its challenges, Qt provides a versatile and mature platform backed by a supportive community, making it an excellent option for many cross-platform development needs.
Please contact ScreamingBox for any information you need on QT or for developing your next cross-platform digital product.
ScreamingBox's digital product experts are ready to help you grow. What are you building now?
ScreamingBox provides quick turn-around and turnkey digital product development by leveraging the power of remote developers, designers, and strategists. We are able to deliver the scalability and flexibility of a digital agency while maintaining the competitive cost, friendliness and accountability of a freelancer. Efficient Pricing, High Quality and Senior Level Experience is the ScreamingBox result. Let's discuss how we can help with your development needs, please fill out the form below and we will contact you to set-up a call.