Qt for Python

General Introduction

For internal and external distribution

Naming

Qt for Python is the global name of the project.

The story of PySide

2008

Qt4
Development
(PySide)

2016

Back
to the
Qt Project

2015

Qt5
Port
(PySide6)

2018

Released
(Qt for Python)

Release information

  • Qt for Python (Qt 5.11) - Technical Preview
  • Qt for Python (Qt 5.12) - Official Release
  • Releases follow the Qt releases
    • Qt5 latest is 5.15.2 OSS and 5.15.12 Commercial LTS
    • Qt6 latest is 6.4.2 OSS and 6.2.7 Commercial LTS

(Slide updated on 14.02.2023)

Python Compatibility

  • PySide2 (5.15)
    • Python 2.7
    • Python 3.6 or greater
  • PySide6 (6.x)
    • Python 3.6+ is required for 6.0, 6.1, 6.2 and 6.3
    • Python 3.7+ is required for 6.4+

License (1/3)

  • LGPLv3/GPLv3 for Community users (OSS)
    • The tools we included are GPLv3
      pyside6-uic, pyside6-rcc,
      pyside6-designer
      etc.
    • shiboken_generator is GPLv3
    • Qt libraries licenses depend on the module
      (*.so, *.dll, *.dylib)
    • Everything else is LGPLv3

License (2/3)

  • Commercial features included in the
    "Qt for Application Development Professional".
    • Community content
    • LTS releases
    • Shiboken Wizard

License (3/3)

  • Commercial features included in the
    "Qt for Application Development Enterprise" onward.
    • AD Professional content
    • Only 3 modules from the Qt M2M (previously Qt for Automation) Protocols
      (QtOpcUa, QtMqtt, QtCoAp)

Setup πŸ”¨

Installation (1/3)

  • Installing Qt doesn't include Qt for Python
    • Not listed on the Qt Maintenance Tool (*)
    • Only allowed via account.qt.io

(*) Work is being done to include it.

Installation (2/3)

  • Qt for Python is distributed via Python Packages (.whl files)
    • The official Python interpreter is supported - python.org
    • The official PyPy interpreter is supported - pypy.org
    • conda is supported(starting from 6.4.3) - anaconda.com
  • Distribution via Python Package Index is supported (only for OSS users)- pypi.org

Installation (3/3)

  • Community (OSS) and Commercial installations are different processes.

Community Edition (OSS)

How to install

Community Edition (OSS)

What is installed?


     β–ͺ️PySide6
      β”œβ”€β”€ Qt modules              βœ…
      β”œβ”€β”€ pyside6-designer        βœ…
      β”œβ”€β”€ pyside6-rcc             βœ…
      β”œβ”€β”€ pyside6-uic             βœ…
      └── ...tools                βœ…
     β–ͺ️Shiboken6 (module)
      └── shiboken6               βœ…
     β–ͺ️Shiboken6_Generator (exe)
      └── shiboken6               ❌
    

Community Edition (OSS)

Installing shiboken_generator

The main issue for not having it public is the dependency with libclang.

Community Edition (OSS)

Installing Shiboken Generator

the simple way


    pip install \
        --index-url=http://download.qt.io/official_releases/QtForPython/ \
        --trusted-host download.qt.io \
        shiboken6 pyside6 shiboken6_generator
    

But one needs to:

  • Set CLANG_INSTALL_DIR to the libclang directory
  • Add to PATH a Qt bin path with the same version
  • Add to LD_LIBRARY_PATH the Qt lib path with the same version

Community Edition (OSS)

Installing Shiboken Generator

the hard way?

  • Set CLANG_INSTALL_DIR to the libclang directory

    python setup.py install
    # there are many other options!
    
doc.qt.io/qtforpython/gettingstarted.html

Commercial Edition (AD, DC)

How to install

  • Download packages (.whl files) from account.qt.io
  • Installing them on a terminal:
  • 
                pip install shiboken6-xxxx.whl pyside6-xxxx.whl
                

(xxxx contains information about architecture, OS and the PySide, Qt, and Python versions)

Commercial Edition (AD Professional)

What is installed?


     β–ͺ️PySide6
      β”œβ”€β”€ Qt modules              βœ…
      β”œβ”€β”€ pyside6-designer        βœ…
      β”œβ”€β”€ pyside6-rcc             βœ…
      β”œβ”€β”€ pyside6-uic             βœ…
      β”œβ”€β”€ ...tools                βœ…
      └── shiboken-wizard         βœ…πŸ†•
     β–ͺ️Shiboken6 (module)
      └── shiboken6               βœ…
     β–ͺ️Shiboken6_Generator (exe)
      └── shiboken6               βœ…
    

Commercial Edition (AD Enterprise, DC Professional/Enterprise)

What is installed?


     β–ͺ️PySide6
      β”œβ”€β”€ Qt modules              βœ…
      β”œβ”€β”€ Qt M2M Protocols        βœ…πŸ†•
      β”œβ”€β”€ pyside6-designer        βœ…
      β”œβ”€β”€ pyside6-rcc             βœ…
      β”œβ”€β”€ pyside6-uic             βœ…
      β”œβ”€β”€ ...tools                βœ…
      └── shiboken-wizard         βœ…πŸ†•
     β–ͺ️Shiboken6 (module)
      └── shiboken6               βœ…
     β–ͺ️Shiboken6_Generator (exe)
      └── shiboken6               βœ…
    

Language differences

Python and C++

C++

  • General purpose and
    Multi-paradigm

C++

  • Statically typed
    
                    int a = 1;
                    float b = 4.3;
                    string c = "hello";

C++

  • Compiled
    
                $ g++ main.cpp -o main
                $ ./main

C++

  • Provides low-level memory manipulation
    
                QObject *obj = new QObject(...);
                delete obj;

C++

  • Code readability
    
                #include <iostream>
    
                int main(int argc, char *argv[]) {
                    std::cout << "Hello World" << endl;
                }

Qt Example

QMainWindow with a QPushButton
C++

        #ifndef MAINWINDOW_H
        #define MAINWINDOW_H

        #include <QMainWindow>
        #include <QPushButton>

        class MainWindow : public QMainWindow
        {
            Q_OBJECT
            public:
                MainWindow(QWidget *parent = nullptr);
            private slots:
                void handleButton();
            private:
                QPushButton *m_button;
        };

        #endif // MAINWINDOW_H

        #include "mainwindow.h"

        MainWindow::MainWindow(QWidget *parent)
           : QMainWindow(parent)
        {
            m_button = new QPushButton("My Button", this);
            connect(m_button, SIGNAL(clicked()), this, SLOT(handleButton()));
        }

        void MainWindow::handleButton()
        {
            m_button->setText("Ready");
        }

        #include <QApplication>
        #include "mainwindow.h"

        int main(int argc, char *argv[])
        {
            QApplication app(argc, argv);
            MainWindow mainWindow;
            mainWindow.show();
            return app.exec(d);
        }
Python

        import sys
        from pyside6.QtWidgets import QApplication, QMainWindow, QPushButton

        class MainWindow(QMainWindow):
            def __init__(self, parent=None):
                QMainWindow.__init__(self, parent)
                self.button = QPushButton("My Button", self)
                self.button.clicked.connect(self.handleButton)

            def handleButton(self):
                self.button.setText("Ready")

        if __name__ == "__main__":
            app = QApplication(sys.argv)
            mainWindow = MainWindow()
            mainWindow.show()
            sys.exit(app.exec())

Qt Compatibility

Checked on 5.15

(For Qt6, following available modules)

Qt Essentials

Core D-Bus GUI Network
QML Quick Quick Controls Quick Dialogs
Quick Layouts Quick Test Test Widgets

Some modules could be incomplete, please see wiki.qt.io/Qt_for_Python_Missing_Bindings for more information.

Qt Add-Ons

Active Qt 3D Bluetooth Concurrent
Help Image Formats Multimedia NFC
OpenGL PDF Positioning Print Support
Quick Widgets Remote Objects SCXML Sensors
Serial Bus Serial Port SpatialAudio SQL
StateMachine SVG TextToSpeech UI Tools
WebChannel WebEngine WebSockets WebView
XML Charts Data Visualization Network Authorization
Quick 3D Quick Timeline Shader Tools Virtual Keyboard
Wayland Compositor HTTP Server Quick 3D Physics

Some modules could be incomplete, please see wiki.qt.io/Qt_for_Python_Missing_Bindings for more information.

Value-Add Modules

Qt Automotive Suite Qt M2M Protocols (1) Qt for Device Creation Qt for MCU (2)

(1) KNX is not included, Only MQTT, CoAp, and OpcUA.

(2) Python doesn't have official support on Microcontrollers. Micro/Circuit Python are subsets of Python, and we don't support them.

Platforms

Windows Linux
macOS Android (1)
iOS (2) WebAssembly (3)
Embedded (4)

  • (1) No official Python support. PoC with third-party tools (in progress)
  • (2) Python doesn't have official support for iOS
  • (3) Official support from Python 3.12 (not released). Only research (in progress)
  • (4) ARM based Linux distributions (ManjaroARM, ArchLinuxARM) provide PySide as a system package. Cross compilation in RaspberryPi OS is possible.

Binding generation

Shiboken

Generation process

Shiboken
ζ­»ζŸε‰£

doc.qt.io/qtforpython/shiboken6

Shiboken

Module

import shiboken6

  • Helper functions
    • isValid(obj)
    • getCppPointer(obj)
    • isOwnedByPython(obj)
    • VoidPtr class

Qt Creator

Qt Creator compatibility

Qt Creator templates

  • Empty application,
  • Basic Widget application,
  • Basic Widget application (.ui file), from 4.12,
  • QtQuick application (QML), from 4.12.

Qt Creator functionality


Can
  • Create new projects,
  • Syntax highlight,
  • Code completion,
  • Add/remove files,
  • Generate Python code from ui and qrc files,
  • Install PySide wheels,
  • Execute applications,
  • Select Python interpreter.
Cannot
  • Install new Python modules,
  • Remote debugging.

What's there besides the Qt API?

Added value

Qt's a C++ framework, and that might be confusing.
  • camelCase API is not a Python standard
  • The usage of setters/getters is not common, in favor of writable properties
  • Qt has data structures to improve C++'s developers life, but Python too.

The __feature__ option


      # Common Qt structure
      # - Using setter/getter
      # - No writable properties

      table = QTableWidget()
      table.setColumnCount(2)

      button = QPushButton("Add")
      button.setEnabled(False)

      layout = QVBoxLayout()
      layout.addWidget(table)
      layout.addWidget(button)
      

Python compatibility

  • Usage of Python native structures instead of QVariant
  • Sequences (Python Lists, Tuples, etc) instead of Qt Sequences
  • Compatibility with pathlib objects (6.2)
  • Usage of numpy.array instead of numerical arrays

Shiboken Wizard

Easy graphical way to generate Python bindings from a C++ project.

Shiboken Wizard

Overview video

Common Use Cases

Pure Python Applications

Custom Python Bindings (without Qt)

Generating Python bindings
from a C++ library.

  • Library files:
    • CMakeLists.txt
    • icecream.cpp
    • icecream.h
    • truck.cpp
    • truck.h
  • Shiboken files:
    • bindings.h (right top)
    • bindings.xml (right bottom)

β˜… Check the samplebinding example


        #ifndef BINDINGS_H
        #define BINDINGS_H

        #include "icecream.h"
        #include "truck.h"

        #endif // BINDINGS_H
<typesystem package="Universe"> <primitive-type name="bool"/> <primitive-type name="std::string"/> <object-type name="Icecream"> <modify-function signature="clone()"> <modify-argument index="0"> <define-ownership owner="c++"/> </modify-argument> </modify-function> </object-type> <value-type name="Truck"> <!-- Same ownership caveat applies here. --> <modify-function signature="addIcecreamFlavor(Icecream*)"> <modify-argument index="1"> <define-ownership owner="c++"/> </modify-argument> </modify-function> </value-type> </typesystem>

Custom Python Bindings (with Qt)

Simple typesystem

<typesystem package="wiggly"> <load-typesystem name="typesystem_widgets.xml" generate="no"/> <object-type name="WigglyWidget"/> </typesystem>

Python usage

from wiggly import WigglyWidget as WigglyWidgetCPP
from wigglywidget import WigglyWidget as WigglyWidgetPY

# ...
wiggly_widget_py = WigglyWidgetPY(self)
wiggly_widget_cpp = WigglyWidgetCPP(self)
# ...
layout.addWidget(wiggly_widget_py)
layout.addWidget(wiggly_widget_cpp)
      

β˜… Check the widgetbinding example


  • Top: Widget written in Python
  • Bottom: Widget written in C++ (exposed to Python)

Hybrid Applications (Python and C++)

Embedding Python into a Qt/C++ application

The Text editor interprets Python code to access the Qt/C++ application to modify it.

β˜… Check the scriptableapplication example

Final remarks

Future steps

  • Documentation,
  • Continue improving C++/Python interaction,
  • Tooling around Shiboken and PySide,
  • Ready-to-use widgets for other Python modules,
  • Research on embedded systems.

For more details, refer to our vision blog post
qt.io/blog/2019/08/19/technical-vision-qt-python

Where to start

Webinars

Communication channels

More platforms at wiki.qt.io/Qt_for_Python#Community

Qt for Python

General Introduction

Dr. CristiΓ‘n Maureira-Fredes
R&D Manager @ TQtC