Qt for Python: the new 6.5 version is out!

You may have seen the many cool things that Qt 6.5 includes, so now we want to talk about everything being developed by the Qt for Python team. 

qtforpython_thin_banner

New modules and classes 

This time we saw an opportunity to expose a few other modules due to feedback from our users and the new capabilities of Qt 6.5. For that, we have now included QtTextToSpeech, QtSerialBus, and QtLocation. 

Also, we are in the process of adapting and improving the classes from the existing modules, and so far, we have managed to include QtCore.QHashSeed, QWebEngineFileSystemAccessRequest, QOpenGLContext.getProcAddressQSGeometry.vertexDataAsPoint2D, QSGGeometry.setVertexDataAsPoint2D, QAbstractTextDocumentLayout::PaintContext, QRunnable.create and QMetaMethod.fromSignal. 

Additionally, many shared pointer types of Qt 3D are included as well: PropertyReaderInterface, QTextureImageData, and QTextureImageDataGenerator. 

The few missing modules from Qt for Python have usually been left aside for lack of use cases or because there are Python counterparts that might be chosen over Qt modules. 

 
Fine tuning: __features__ and multiple-inheritance 

Meanwhile, quite well known __feature__ switching was again totally revised. On the one hand, the switching was strongly optimized so that the Dictionary of a class must be changed only approximately every fifth time. Furthermore, the criteria for switching have been tightened so that complex cases with many context changes in expressions can be handled safely. 

At the same time, during this revision, a poorly understood corner was refactored, and a number of hard-to-locate errors were finally eliminated. 

Cooperative multiple inheritance has also been a misunderstood thing for a long time. Actually, multiple inheritance in PySide has nothing to do with Python, but users expect the super() function to behave the same way when used in a PySide class as in a normal Python class. We have extended the __init__ function accordingly, as other implementations have done. But that's not the final word. In fact, you need to implement multiple inheritance quite differently so that super() behaves like normal Python everywhere, in all methods and even in metaclasses. To do this, you have to improve the super() function itself so that it behaves properly on PySide classes on its own.  

⭐ But we'll tell more about that in the next release. Stay tuned! 

 

Improving our binding generation tool: Shiboken 

For each minor release, we have the option to clean a bit of the current implementation of our binding generator tool and add new features.  

For the generated wrapper code, we used to rely on goto statements that are now safely removed and replaced for a better implementation. 

There is now a new option called --lean-header to generate forward declarations instead of includes into the module header, from which we can get improvements regarding the dependencies of each wrapper. Still, it might require extra additional includes for the injected code. 

To continue improving our support for shared pointers, it is now possible to specify names and namespaces for smart pointer instantiations, for example: 

<smart-pointer-type name="SharedPtr" type="shared"

    getter="data" ref-count-method="useCount"

    null-check-method="isNull"

         instantiations="Integer,Smart::Integer2,Obj"/> 

 

Where you can see that the “Smart::Integer2” is being renamed as “SmartInteger2Ptr”. 

A typesystem XML element for opaque containers has been added, removing the need to repeat the container element: 

<opaque-container name="QList"

    opaque-containers="QVector2D:QVector2DList

        QVector3D:QVector3DList;QVector4D:QVector4DList"/> 

Starting from 6.5.0, Shiboken has support for std::array (C++ 11). There is now experimental support for std::span (C++20). 

Finally, we have improved the documentation by refreshing the diagrams and highlighting some of our examples. 

Modern looking Qt Quick applications UIs for your Python code

As you might know, Qt for Python works well with Qt Widgets and also with Qt Quick. However many people has been asking us to get a nice modern-looking Qt Quick application example, which also include a tutorial that explains the details. Due to the nature of Qt Quick, you can have a backend in C++ or Python, also most of the graphical aspects are written mostly in QML.

We are pleased to introduce the Filesystem Explorer, a new Qt Quick example that demonstrates the flexibility and adaptability of Qt Quick Controls. This example provides a user-friendly interface for browsing and visualizing the file system, allowing users to open local text files effortlessly. 

extendedexplorer

This project showcases how to jazz up a Qt Quick application by personalizing and arranging its essential components to achieve a visually stunning and modern appearance. We will explore ways to refine the user interface elements and organize different parts of the application to improve usability and user experience. The primary objective is to exhibit the art of application customization and layout. Specifically, we will delve into the distribution of color schemes and frameless windows, which can enable you to design a distinct and visually appealing interface for your application. Our aim is to enable developers to create a highly personalized and specific appearance for their application, avoiding reliance on system settings and achieving a fully customized look. 

Additionally, we have expanded upon the initial example and created the Extended Explorer tutorial. This tutorial improves the functionality by showcasing how to implement a scheme manager, enabling the ability to switch color schemes dynamically during runtime. This feature demonstrates how to modify the application's appearance on-the-fly by using QML bindings and parsing schemes in JSON format. As a result, developers are given greater flexibility and customization options when designing their applications. 

In case you are interested in the C++ counterpart, you can check that example here.

qtpip: a better way to install commercial wheels (in progress) 

Many of our commercial customers have been struggling with getting the commercial packages of Qt for Python, mainly because it involves a couple of extra steps, which are a bit more complicated than the simple ‘pip install pyside6’. That is why we have been working on a simple pip wrapper to enable the installation of commercial wheels 🛞.

Even though it is not included in this release, the tool will have its own development cycle and be available during 6.5. People will be able to get this tool independently and use it to interact with their Qt accounts. 

⭐ Once the tool is fully ready, we will follow up with a dedicated blog post. 

Asynchronous support 

Qt for Python is not just Qt, and not just Python: It’s the best of both worlds! 💪 But the world of Python is more than just a language: Python users expect wide interoperability between their favorite libraries and modules of the huge Python ecosystem. 

Today, Python developers who want to write an application with asynchronous I/O have a choice between the asyncio and trio libraries, among others. As you surely know, like these two, Qt is also based on an event loop. This positions Qt for Python as a good choice for asynchronous program logic in combination with one of the established libraries of the Python ecosystem, enabling developers to leverage their respective strengths.  

We are currently exploring how to make Qt and asynchronous frameworks play well together. During the past months, we have added two examples showcasing how to combine Qt for Python with Trio via its guest run mechanism, plus two exploratory examples for an analogous implementation with asyncio 

During the 6.5 release cycle, you can expect additional progress, including Qt for Python’s own implementation of asyncio’s abstract event loop, so that you can use the asyncio library with Qt’s event loop underpinning it.

Be sure to “await PySide6.more_async_support()” in the coming months. 😉 

Initial support for Android deployment 

The much-requested and long-awaited feature of taking your PySide6 application to Android is ALMOST here. With 6.5, we release a technical preview (TP) of a new tool, 'pyside6-android-deploy' that provides a simple, easy-to-use solution to package your PySide6 application from a Linux-based desktop OS to different Android platforms. It can be run as simply as:  

pyside6-android-deploy

    --wheel-pyside=<path_to_pyside6_android_wheel>

    --wheel-shiboken=<path_to_shiboken6_android_wheel>

  --name=<app_name> 

The tool internally uses a custom fork for the python-for-android project with a new bootstrap for Qt. Eventually, we hope to create a pull request and get this fork merged into the python-for-android project. 

You may have noticed that the tool requires the path to PySide6 and Shiboken6 Android wheels. So, where do you get them? Do we provide official Android wheels now? 

For the time being, we don't provide official Android wheels yet, so you will have to build the Android wheels yourself. But don't worry; check out another tool to cross-compile Qt for Python wheels to a specific Android platform. However, you can't find this tool with your PySide6 version 6.5 installation. We kept the tool separate in hopes that we could have official Android wheels in the future. The tool builds CPython for the specified Android platform and uses the built CPython to cross-compile PySide6 Android wheels. 

python tools/cross_compile_android/main.py

    --plat-name=<android_platform>

   --ndk-path=<path_to_android_ndk>

   --qt-install-path=<path_to_local_Qt_installation>

   --sdk-path=<path_to_android_sdk> 

Ideally, the entire deployment process is a 3-step process. 

  1. Download Android NDK and SDK
  2. Run the cross-compile tool to generate Qt for Python Android wheels
  3. Run the 'pyside6-android-deploy' tool

At the end of step 3, you will have an apk/aab to publish or install onto your Android device. 

If the few sentences above poked your interest, we are sure you will have many open questions and would love more detailed instructions on taking your PySide6 application to Android. 

⭐ Stay tuned for a more detailed blog post on Android compatibility in the coming weeks. 

(if you have issues playing the video, you can find it here)

Preparing for the future of Python

Python 3.11 came with many improvements for the Python ecosystem, and we managed to keep up with our internal implementation to remain compatible. As you might know, 3.12 will continue in the same direction, focusing mainly on performance. 

Being compatible requires us to revisit our internal CPython implementations, so we started testing 3.12 as soon as we could. Even though it is still not fully compatible, we managed to unblock the build process with a couple of changes. 

Orthogonal to this topic, we have been following the latest developments in the Python community regarding the evolution of the language, particularly the latest attempts to remove the GIL from the interpreter. We also aim to provide full compatibility with the NoGIL project. 

The NoGIL branch is still in an unsuitable condition for inclusion into Python. We have therefore researched it only far enough until the feasibility was clear. The outlook for the future looks positive so far 🥳. PySide itself must now ensure that unprotected objects are not used more than once. But the resulting efficiency by parallel execution is very promising 🎉, and we hope that this path will be taken officially soon. 

What’s next? 

We want to keep trying new experimental support, features, and python module integration. What should we do next? Drop us a message or open a suggestion on JIRA 👍. 

We hope you enjoy the release, and as always drop by our community platforms and let us know if something is not properly working by opening bug reports in JIRA .


Blog Topics:

Comments