Porting from Qt 5 to Qt 6 – Top 3 reasons and steps to follow

Qt Qml development
12 minutes
Porting from Qt 5 to Qt 6

The release of Qt 6 marks a significant milestone, offering a host of new features and improvements over Qt 5. If you’re currently using the fifth version, now is the perfect time to consider migrating to the next one. This blog post will guide you through the key reasons to make the switch and provide a comprehensive overview of the steps involved in the porting process. If you have any questions or need assistance with porting your application, feel free to write to us.

Let’s dive in and discover why Qt 6 is the optimal choice for your future development projects.

Differences between Qt 5 and Qt 6

The Qt Company has long been known for its frequent updates and continuous improvements, ensuring that developers have access to the latest tools and features to create robust, high-performance applications. With the release of the new version, this tradition of innovation continues, bringing a lot of significant changes over the previous version. Understanding these differences is crucial for developers looking to leverage the full potential of the latest release.


Qt Quick Changes

Qt Quick has undergone several changes. These updates are aimed at improving performance, flexibility, and ease of use for developers working with the Qt framework. The minor things are:

Qt 5 relied on the Qt Quick Scene Graph primarily using OpenGL, whereas 6 uses the new Qt Rendering Hardware Interface (RHI), supporting multiple backends like Vulkan, Metal, Direct3D, and OpenGL. RHI provides not only support for other systems but also improves rendering performance. It benefits Qt Quick, with notable improvements in Qt Quick 3D for handling complex scenes with numerous renderable objects. This results in smoother and more efficient rendering, especially in graphics-intensive applications.

The newest version introduces changes in shader support, offering developers increased flexibility and performance for custom graphical effects. Additionally, Qt 6 supports modern shading languages like GLSL, HLSL, and MSL, enabling shaders to fully utilize each platform’s graphics capabilities. Shaders are now compiled at runtime for the target platform, optimizing performance and making better use of hardware capabilities. It also includes Qt Shader Tools, which assist in managing shaders, debugging them, and converting shader code between different shading languages, simplifying the development process.


Changes in QML

Qt 6 introduces several improvements to QML and QML files to improve functionality and usability. Changes include converting font.weight to int, making FontLoader.name read-only, and replacing OpenGLInfo with GraphicsInfo. Additionally, ShaderEffect now uses URLs for shader source properties instead of inline GLSL strings (Qt 6 QML changes page).

These updates, and much more, streamline QML development and make it more flexible.


Modules and features

As Qt evolves, Qt 6.5 enhances the framework with new modules and re-architects existing ones. Some modules and add ons have been removed to streamline the framework and focus on more relevant features. These updates ensure Qt remains a cutting-edge tool for modern application development.


Table of dropped features in Qt 5 and new features in Qt6

You can read the complete list of module changes and feature updates on Qt 5.15 LTS / 6.5 LTSFeature Comparison post.



CMake API also changed, improving usability and modernizing the build process. Here are some key improvements:

  1. Versionless Targets and Commands– Qt 5.15 introduced version-less targets and commands to simplify CMake code that works with Qt 5 and Qt 6. This means you can use Qt::Core instead of Qt5::Core or Qt6::Core.

  2. Mix Qt versions– You can load Qt 5 and Qt 6 in one CMake context.

  3. Unicode Support– UNICODE and _UNICODE compiler definitions are set by default for Windows targets, aligning with qmake behavior but differing from Qt 5’s CMake behavior.

  4. Improved Documentation and Practices– Enhanced documentation and recommended practices for better compatibility and transition ease.

  5. qt_add_qml_module – This new CMake function simplifies the configuration and integration of QML modules, reducing boilerplate code and making the build process more intuitive (Qt Documentation).

  6. qt_add_resources – Another new CMake function, which automates the inclusion and management of resources. This reduces manual overhead and potential errors, allowing for more dynamic handling of resource paths (Qt documentation).

These improvements aim to streamline development and ensure compatibility across Qt versions.

For more details, visit the CMake Qt 5 and Qt 6 compatibility page.


Qt Rendering Hardware Interface – new graphical backend


Instead of Utilizing the Qt Quick Scene Graph for rendering, which was primarily based on OpenGL calls in Qt 5, Qt 6 introduces the Qt Rendering Hardware Interface (RHI), which abstracts the graphics API layer, supporting multiple back-ends like Vulkan, Metal, Direct3D, and OpenGL. This makes Qt Quick more versatile and better suited for different platforms and hardware.

Qt in their Graphics in Qt 6.0: QRhi, Qt Quick, Qt Quick 3D article provides us with the main layers of the Qt 6.0 graphics stack visualization.


Why port to Qt 6?


After understanding the key differences between Qt 5 and Qt 6, it’s clear that migrating offers substantial benefits. Porting allows you to leverage significant performance optimizations. Additionally, the latest version introduces new modules and features, providing a richer and more versatile framework for your applications. By making the transition, you not only future-proof your projects but also gain access to ongoing updates and the latest advancements in the Qt ecosystem. Here are some other reasons why porting is a good idea.



1. Staying up-to-date

After detailing the differences, it’s clear that the latest version is the ideal choice for staying current with the latest advancements in application development. Moreover, new features and updates will be exclusive to the latest release, ensuring that your applications leverage the most recent innovations and improvements. By migrating, you ensure that your projects remain at the forefront of technology, benefiting from ongoing updates and the latest in the ecosystem.

By porting to the new version, developers benefit from ongoing updates and support, ensuring access to the latest features and security improvements. This transition also presents an excellent opportunity to refactor and optimize code, reducing technical debt and improving maintainability. Overall, moving to the latest version ensures that your applications remain competitive, efficient, and future-proof.



2. Better performance

Qt 6 introduces substantial performance improvements over Qt 5, making it a more efficient and responsive framework for modern application development. One of the most significant enhancements is the introduction of the QRHI. This abstraction layer enables Qt 6 to leverage the best-suited graphics API for each platform, resulting in improved rendering performance and flexibility. In contrast to Qt 5’s heavy reliance on OpenGL, this approach ensures smoother animations and faster rendering times, particularly for applications with complex graphical requirements (Qt DevLifecycle) (Qt Wiki).

Additionally, Qt Quick and Qt Quick 3D have been significantly enhanced in Qt 6. The scenegraph in Qt Quick now supports multiple graphics APIs, providing better performance across different platforms. Qt Quick 3D benefits from a unified 2D-3D rendering approach, improved material and shader handling, and better integration with the underlying graphics stack. These improvements lead to more efficient and powerful rendering capabilities compared to the limitations faced in Qt 5 (Qt Wiki) (Qt Documentation).

The multimedia module in Qt 6 has been re-architected for better cross-platform support and optimized performance. This includes improved handling of audio and video streams, lower latency, and more efficient resource utilization, providing a more robust multimedia experience than Qt 5 (Qt Wiki) (Qt DevLifecycle). These comprehensive performance enhancements make Qt 6 a more powerful and efficient framework, ensuring that applications are more responsive, scalable, and capable of delivering high-quality user experiences across various platforms and devices.



3. Prime opportunity to refactor code

Porting your application from Qt 5 to Qt 6 is an excellent opportunity to refactor your codebase, which can significantly help in fighting technical debt. As software projects evolve, technical debt often accumulates in the form of outdated code structures, inefficient algorithms, and deprecated libraries. The migration to Qt 6, with its modernized architecture and improved performance features, naturally necessitates revisiting and updating your existing code. This process allows you to identify and eliminate redundant or obsolete code, streamline your codebase, and implement more efficient and maintainable coding practices.

Refactoring during the porting process ensures that your application not only benefits from the new features and performance enhancements of Qt 6 but also becomes more robust and easier to maintain. Addressing technical debt at this stage helps prevent future issues, reduces the complexity of adding new features, and improves the overall quality and stability of your application. Additionally, the transition provides a perfect occasion to adopt modern coding standards and best practices, ensuring that your application is built on a solid foundation that can adapt to future technological advancements and also sets your project up for long-term success and sustainability.


Porting Qt applications from Qt5 to Qt6 step by step



1. Prepare Your Codebase

Update to the Latest Qt 5 Version: Before starting the porting process, make sure your application is updated to the latest Qt 5.15 version. You may ask yourself why. This method minimizes the changes needed when moving to Qt 6 for those reasons:

  • Qt 5.15 is the latest version of Qt 5 and contains the least amount of deprecated and obsolete APIs compared to earlier versions. This means the transition to Qt 6 will involve fewer changes and will be smoother as the APIs in Qt 5.15 are closer to those in Qt 6

  • Qt 5.15 provides a deprecation compiler warning for APIs that will be removed or changed in Qt 6. By addressing these warnings in Qt 5.15, you can preemptively handle most of the breaking changes before starting the actual porting process.

  • Qt 5.15 includes the latest features, bug fixes, and optimizations available in the Qt 5 series. This ensures your application is as robust and up-to-date as possible before making the transition to Qt 6, thereby reducing the risk of encountering unforeseen issues.

  • Many APIs in Qt 5.15 are designed to be forward-compatible with Qt 6. This intentional design choice by the Qt developers means that starting from Qt 5.15 can simplify the process of adapting your code to the new version

Clean Up Deprecated APIs: Remove or replace any usage of APIs that exist but were marked as deprecated in Qt 5. This will simplify the moving process since these APIs may have been removed in Qt 6.


2. Set Up Your Development Environment

Install Qt 6: Download and install the latest version of Qt 6 from the maintenance tool.


3. Update Project Configuration

CMake Migration: If your project uses qmake, convert the qmake project file or files to CMake. This involves creating CMakeLists.txt files and configuring them to find and use Qt 6 modules.

Update Include Paths: Change your include paths from Qt 5 to Qt 6 modules. For example, replace #include <Qt5Module> with #include <Qt6Module>.


4. Adjust Code for Qt 6 Changes

Run clazy checks: Set all the clazy checks dedicated to Qt 6 porting and run those on your project. You can read in detail how to do it in this blog post: Porting from Qt 5 to Qt 6 using Clazy checks.

Replace Removed APIs: Identify and replace any Qt 5 APIs that have been removed in Qt 6 with their new equivalents.

Adapt to New Module Structures: Some modules have been restructured or renamed in Qt 6. Update your code to use the new module structures.

You can also use the Qt5Compat library which is a module that contains the Qt 5 Core APIs that were removed in Qt 6. You can read about it more in the Qt blog post Porting from Qt 5 to Qt 6 using Qt5Compat library.


5. Handle Rendering Changes

Adopt QRHI: If your application relies on OpenGL, you may need to adapt it to use the Qt Rendering Hardware Interface (QRHI) which supports multiple graphics APIs.

Update Shader Code: If your application uses custom shaders, update them to be compatible with the new unified shader pipeline in Qt 6.


6. Testing and Debugging

Run Unit Tests: Ensure all existing tests pass and add new tests if necessary to cover new Qt 6 features.

Graphical Testing: Verify that the graphical output is as expected, especially if you have made changes to the rendering code or shaders.

High-DPI Support: Test your application on high-DPI displays to ensure that scaling and rendering are handled correctly.


7. Performance Optimization

Profiling: Use profiling tools in qt creator to identify and optimize performance bottlenecks in your application.

Memory Management: Check for memory leaks and optimize memory usage with the improved memory management features in Qt 6.


8. Documentation and Maintenance

Update Documentation: Ensure that your project documentation is updated to reflect the changes made during the porting process.

Continuous Integration: Update your CI/CD pipelines to use Qt 6, ensuring that builds and tests are performed in the new environment.

By following these steps, you can successfully port your Qt 5 application to Qt 6, taking advantage of the latest features and performance enhancements.

For more detailed guidance and examples, refer to the official Qt 6 porting guide and the Qt 5 to Qt 6 compatibility documentation.


What If I have a project based on Yocto?

We’re not strangers to the Yocto Project, we have a blog post (Yocto Linux- Build Your Own Embedded Linux Distribution) where we teach what the Yocto Project is and how to build a Linux distribution on your own. With that knowledge, we can tell that porting a Yocto-based application from Qt 5 to Qt 6 is not that different from porting a regular application. Here are some additional steps to consider:

  1. Update Yocto Recipes: Switch from the meta-qt5 layer to meta-qt6 to support Qt 6.

  2. Check Dependencies: Ensure all required libraries for Qt 6 are included in your Yocto build.

  3. Testing: Test the application on the new build to ensure compatibility and performance.

These steps will help ensure a smooth transition to Qt 6 in a Yocto-based environment.

Scythe-Studio - Qt Developer

Mateusz Fejcher Qt Developer

Need Qt QML development services?

service partner

Let's face it? It is a challenge to get top Qt QML developers on board. Help yourself and start the collaboration with Scythe Studio - real experts in Qt C++ framework.

Discover our capabilities

Latest posts

[ 134 ]