Qt for Python release: 6.2 is here! 🐍

We are really happy to tell you that following the Qt release, Qt for Python is also available! 

Many things happened on this release, we decided to communicate a little more on the details of the major milestones that we achieved on this release 🎉.

You might have notice that last week only the Windows wheels are available on PyPi, that was due to the wheel size increase from the new modules, but luckily the PyPi team managed to address this quickly.

Now it's possible to get 6.2.0 with the usual:

  pip install pyside6

Catching up with Qt 6.2 

With all the new modules that are now available with Qt 6.2, we took some time re-add all the modules we previously had, like QtCharts, QtDataVisualization, QtWebEngine and QtMultimedia/QtMultimediaWidgets, which required us to refresh the examples and tests, due to the API improvements. Complementary, we removed some modules, too, like QtX11Extras, and QtMacExtras. 

Additionally, we ported a few new modules like QtDBus, QtNetworkAuth, QtWebEngineQuick, and an initial support for QtBluetooth. 

Missing classes were finally added due to the feedback from PySide users like QChannel, QChannelComponent, QAccessible.installFactory(), QAccessibleActionInterface, QWebEnginePage.setWebChannel and QSignalSpy. 

Improving the 6.1 features 📈

After the initial implementation of the pathlib compatibility, we continued to enable more Qt API to be compatible with the PathLike structure, now we can say that every method that takes std::filesystem::path will accept PathLike. 

Other scenarios also required new methods, like QUrl.fromLocalFile() that now supports PathLike objects in addition to the string arguments. 

With the __feature__ option, a user noticed that there were discrepancies when using it along generated Python code (from .ui files), luckily those problems were solved, and we don’t convert the generated code any longer. 

Support for Python 3.10  

Python 3.10 adds some features which needed support. Our Zip importer implementation needed a rewrite to avoid deprecation warnings. Also, the new optimization in Python 3.10 used some caching which broke our __feature__ switching. This could be fixed by cache invalidation. 

The refcounting of Python 3.10 has become more correct, and we had to fix bugs which were never knew we had. Some adaptations to .pyi generation were necessary because there were side effects of certain improvements in the typing module. 

Python 3.10 was released on Monday 4th of October, so we hope you enjoy it together with PySide 6.2.0 🐍

Qt for Python Tooling 🧰

With the improvements to our .pyi files (Python stubs) we noticed that it would be very beneficial for people using Shiboken exposing C++ code to Python, so the process was converted into a standalone tool. 

And we have more good news! Starting with 6.2.0, lupdate officially supports Python. This means that we added back the pyside6-lupdate executable to the wheels, so you can use it in your applications for i18n. In the past, pyside2-lupdate was removed due to the lack of maintenance, issues, and for being outdated, so we are happy to tell you it’s back in place. 

Additionally, we decided to provide Qt Assistant to Python users via the wheel packages. You can launch it after installing pyside6 using pyside6-assistant. 

Refer to this tutorial to learn how to use it in your applications.

Refreshing our QML code, Documentation and New Examples

We noticed that our QML examples were not using the best practices, so we decided to update them 🧹 to mainly get rid of the many usages of context properties, and replaced them with our QmlElement decorator. Here is an updated tutorial in case you are curious on how this looks like.

As previous releases, we ported a few more examples to cover additional usages of PySide. To highlight a few you have Dynamic Spline, string/object list models, markdowneditor, data surface, Richtext/textedit, qsharedmemory, and opengl under qml, among others. 

Because we added new modules, we were able to add a new example for QtDataVisualization and two tutorials based on QtCharts that we had in the past.

Last but not least, we have seen that the popularity of Nuitka is still growing, so we decided to provide a simple tutorial, so you can use it to distribute your Python applications. Give it a try, it's a really nice project!

Opaque Containers

Currently, Python containers like list can be passed to bound C++ functions taking C++ containers. This means that a conversion from a Python sequence to a C++ list is happening in each call. This can be problematic performance-wise when doing this in a loop, for example creating a moving data plot. 

A solution to this problem is to create bindings to the underlying C++ container and instantiate them directly. Populating the container then happens via bound C++ container functions. 

The function call is then a matter of passing the underlying C++ container with no conversion involved. This is called an opaque container (modelled after a popular pybind11 feature). Experimental support for sequence containers has been added to shiboken (see container-type tag). 

At the moment, QList is represented as a ‘list’ in Python, but that includes the copying, however we included a couple of opaque containers: 

    <container-type name="QList" type="list"  

So, it’s possible to directly import those types, like from PySide6.QtGui import QPointList, and use it. 

Refer to this example to see this feature in action. We are planning to present a benchmark of the Opaque Containers usage compared to C++ and Python applications, to give you a better idea of the perks of using them. Stay tuned!

PyPy compatibility  (In Progress)

PyPy is a very compliant and fast Python compiler. It's speed factor it typically 4.2 against stock CPython. In our Mandelbrot example, the speed factor is nearly 10. 

Using PyPy as a replacement for CPython is not an easy task, because its inner structure is very different and has special rules to add compatibility to CPython extensions like PySide. The ongoing process can be seen here: PySide PyPy status. We hope to support it completely by the end of this year. 

Supporting PyPy as replacement of CPython in PySide is an important step into the future. Not only the speed gain is interesting. In a world that suffers from global heating, software should be as “green” as possible. Using PyPy, you can reduce the power consumption of your software by a factor of four or better, without making any code change. 

Many thanks to the PyPy team who helped us identify problems and fixed issues as well. 

Shiboken Changes

If you are familiar with the Shiboken internals, you might know the SbkObjectType structure, among other similar Sbk* ones. With the continous improvement to its API, we noticed that this structure was just holding a PyTypeObject member, so we decided to remove it. For the next minor versions, it will remain as an alias. 

When porting PySide2 (5.15) to PySide6 (6.x) we noticed an extra level in the Shiboken Module import, so we kept a shiboken6.shiboken6 alias, which is now removed, to access the module use shiboken6.Shiboken instead. 

From the most common usages of Shiboken generator, we got some feedback that some things of the typesystem files could be inferred, or added by default. For this we decided to add CPython types like PyObject, or PySequence into shiboken. You don’t need to specify them in the typesystem file any longer. You can find the full list here

Additionally, it’s possible to use conditional processing instructions in the typesystem file. For example: 

  <?if windows darwin?> 

    <primitive-type name=”Qt::HANDLE” target-lang-api-name=”PyObject”/> 


Finally, it’s now possible to specify a check function for custom types in the typesystem. 

Issues and Other Changes 🗒️

Of all the work that has been done in 6.2, there are a few more things we would like to highlight. In any case, you can check the full changelog here

  • The qtpaths comand line tool is now used to query Qt properties, instead of qmake. 
  • QObject.connect() now returns an instance of QMetaObject.Connection, which can be used to disconnect, instead of a bool. 
  • Crashes were fixed in QClipboard.mimeData(), QTextCursor.currentList(), QTextCursor.currentTable(), QCustom3DVolume::setTextureData, QSurfaceDataProxy::resetArray(), the QImage constructor, QObject.findChild(), and QObject.findChildren(). 
  • The Python Unicode API was updated to the newest version when not in limited API mode. 
  • QMultiMap and QMultiHash are now converted to a dict of key/list of values. (defaultdict) 
  • QThreadPool.start and QThreadPool.tryStart now accept std::function 
  • QmlRegisterSingletonInstance() is now implemented, and we added other functions like qjsEngine(), qmlClearTypeRegistrations(), qmlContext(), qmlEngine(), qmlProtectModule() and qmlRegisterModule(). 

If you find issues, have comments or ideas, let us know if you find something by submitting a new report on JIRA, or contacting us in our community platforms. We hope you enjoy this new release!



Blog Topics: