SkillAgentSearch skills...

Qt.py

Minimal Python 2 & 3 shim around all Qt bindings - PySide2, PySide6, PyQt5 and PyQt6.

Install / Use

/learn @mottosso/Qt.py
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<img width=260 src=https://raw.githubusercontent.com/mottosso/Qt.py/master/logo.svg>

Downloads Run Tests PyPI version Anaconda-Server Badge Gitter

Qt.py enables you to write software that runs on any of the 4 supported bindings - PySide6, PyQt6, PySide2, PyQt5.

<br>
News

| Date | Version | Event |:---------|:----------|:---------- | Jan 2025 | 2.0.1 | Dropped support for Qt 4 and python versions older than 3.7 | May 2024 | 1.4.1 | Added support for Qt 6 | Jan 2024 | 1.3.9 | Run CI on Github Actions, instead of Travis CI. | Sep 2020 | 1.3.0 | Stability improvements and greater ability for QtCompat.wrapInstance to do its job | Jun 2019 | 1.2.1 | Bugfixes and additional members | Jan 2018 | 1.1.0 | Adds new test suite, new members | Mar 2017 | 1.0.0 | Increased safety, backwards incompatible | Sep 2016 | 0.6.9 | Stable release | Sep 2016 | 0.5.0 | Alpha release of --convert | Jun 2016 | 0.2.6 | First release of Qt.py

Guides
Table of contents
<br> <br> <br>

Project goals

Write once, run in any binding.

Qt.py was born in the film and visual effects industry to address the growing need for software capable of running with more than one flavor of the Qt bindings for Python - PySide6, PySide2, PyQt6 and PyQt5.

| Goal | Description |:-------------------------------------|:--------------- | Support co-existence | Qt.py should not affect other bindings running in same interpreter session. | Build for one, run with all | Code written with Qt.py should run on any binding. | Explicit is better than implicit | Differences between bindings should be visible to you.

See CONTRIBUTING.md for more details.

<br> <br> <br>

Install

Qt.py is a single file and can either be copy/pasted into your project, downloaded as-is, cloned as-is or installed via pip or conda.

# From PyPI
$ pip install Qt.py
# From Anaconda
$ conda config --add channels conda-forge
$ conda install qt.py
  • Pro tip: Never use the latest commit for production. Instead, use the latest release. That way, when you read bug reports or make one for yourself you will be able to match a version with the problem without which you will not know which fixes apply to you nor would we be able to help you. Installing via pip or conda as above ensures you are provided the latest stable release. Unstable releases are suffixed with a .b, e.g. 1.1.0.b3.
  • Pro tip: Supports vendoring
<br> <br> <br>

Usage

Use Qt.py as you would use PySide6.

image

import sys
from Qt import QtWidgets, QtCompat

app = QtWidgets.QApplication(sys.argv)
button = QtWidgets.QPushButton("Hello World")
button.show()
QtCompat.QApplication.exec_()
<br> <br> <br>

Documentation

All members of Qt stem directly from those available via PySide6, along with these additional members.

| Attribute | Returns | Description |:------------------------|:------------|:------------ | __version__ | str | Version of this project | __binding__ | str | A string reference to binding currently in use | __qt_version__ | str | Reference to version of Qt, such as Qt 5.6.1 | __binding_version__ | str | Reference to version of binding, such as PySide 1.2.6

Example

>>> from Qt import __binding__
>>> __binding__
'PyQt5'

Compatibility

Qt.py also provides compatibility wrappers for critical functionality that differs across bindings, these can be found in the added QtCompat submodule.

| Attribute | Returns | Description |:------------------------------------------|:------------|:------------ | loadUi(uifile=str, baseinstance=QWidget)| QObject | Minimal wrapper of PyQt6.loadUi and PySide6 equivalent | translate(...) | function | Compatibility wrapper around QCoreApplication.translate | wrapInstance(addr=long, type=QObject) | QObject | Wrapper around shiboken6.wrapInstance and PyQt equivalent | getCppPointer(object=QObject) | long | Wrapper around shiboken6.getCppPointer and PyQt equivalent | isValid(object=QObject) | bool | Wrapper around shiboken6.isValid and PyQt equivalent | dataChanged(topLeft=QModelIndex, bottomRight=QModelIndex, roles=[]) | None | Wrapper around QtCore.QAbstractItemModel.dataChanged.emit

Example

>>> from Qt import QtCompat
>>> QtCompat.loadUi

Class specific compatibility objects

Note: Most of these are for Qt4 and Qt5 compatibility. With 2.0 dropping support for Qt4 many of them are no longer needed, but we are leaving them in for backwards compatibility.

Between Qt4 and Qt5 there have been many classes and class members that are obsolete. Under Qt.QtCompat there are many classes with names matching the classes they provide compatibility functions. These will match the PySide2 naming convention.

from Qt import QtCore, QtWidgets, QtCompat
header = QtWidgets.QHeaderView(QtCore.Qt.Horizontal)
QtCompat.QHeaderView.setSectionsMovable(header, False)
movable = QtCompat.QHeaderView.sectionsMovable(header)

This also covers inconsistencies between bindings. For example PyQt4's QFileDialog matches Qt4's return value of the selected. While all other bindings return the selected filename and the file filter the user used to select the file. Qt.QtCompat.QFileDialog ensures that getOpenFileName(s) and getSaveFileName always return the tuple.

<br>
Environment Variables

These are the publicly facing environment variables that in one way or another affect the way Qt.py is run.

| Variable | Type | Description |:--------------------------|:------|:---------- | QT_PREFERRED_BINDING_JSON | str | Override order and content of binding to try. This can apply per Qt.py namespace. | QT_PREFERRED_BINDING | str | Override order and content of binding to try. Used if QT_PREFERRED_BINDING_JSON does not apply. | QT_VERBOSE | bool | Be a little more chatty about what's going on with Qt.py

<br>
Subset (or "common members")

Members of Qt.py is a subset of PySide6. Which means for a member to be made accessible via Qt.py, it will need to (1) be accessible via PySide6 and (2) each of the other supported bindings. This excludes large portions of the Qt framework, including the newly added QtBluetooth and QtQuick3D modules but guarantees that anything you develop with Qt.py will work identically on any binding - PySide2, PySide6, PyQt5 and PyQt6. If you need to use such excluded modules with Qt.py, please see QtSiteConfig.py.

We call this subset "common members" and these can be generated by running the tox tests. The membership tests will output all modul

View on GitHub
GitHub Stars989
CategoryDevelopment
Updated2h ago
Forks259

Languages

Python

Security Score

100/100

Audited on Apr 8, 2026

No findings