aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/doc/considerations.rst
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/doc/considerations.rst')
-rw-r--r--sources/pyside6/doc/considerations.rst239
1 files changed, 228 insertions, 11 deletions
diff --git a/sources/pyside6/doc/considerations.rst b/sources/pyside6/doc/considerations.rst
index 08e53e329..dda1d8b0d 100644
--- a/sources/pyside6/doc/considerations.rst
+++ b/sources/pyside6/doc/considerations.rst
@@ -1,7 +1,7 @@
.. _pysideapi2:
-|project| Considerations
-========================
+Considerations
+==============
API Changes
-----------
@@ -10,7 +10,7 @@ One of the goals of |pymodname| is to be API compatible with PyQt,
with certain exceptions.
The latest considerations and known issues will be also reported
-in the `wiki <https://wiki.qt.io/Qt_for_Python/Considerations>`_.
+in the :ref:`developer-notes`.
__hash__() function return value
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -149,15 +149,15 @@ There was a long-standing bug in the ``tp_richcompare`` implementation of PySide
This oversight was fixed in version 5.15.1 .
-|project| Features
-==================
+Features
+--------
In |project|, we begin for the first time to support a more pythonic user interface.
With a special import statement, you can switch on features which replace certain aspects of
the Python interpreter. This is done by an import statement right after the PySide6 import.
snake_case
-----------
+~~~~~~~~~~
With the statement:
@@ -169,7 +169,7 @@ all methods in the current module are switched from ``camelCase`` to ``snake_cas
A single upper case letter is replaced by an underscore and the lower case letter.
true_property
--------------
+~~~~~~~~~~~~~
With the statement:
@@ -182,7 +182,7 @@ are replaced by Python property objects. Properties are also listed as such
in the according QMetaObject of a class.
Example for both features
--------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~
Some |project| snippet might read:
@@ -200,14 +200,14 @@ Additionally, properties can also be declared directly in Shiboken for
non Qt-libraries, see :ref:`property-declare`.
More about features
--------------------
+~~~~~~~~~~~~~~~~~~~
Detailed info about features can be found here: :ref:`feature-why`
Tools
------
+~~~~~
-|project| ships some Qt tools:
+|project| ships some Qt tools:
* ``pyside6-rcc``: Qt Resource Compiler. This is a command line tool
that compiles ``.qrc`` files containing binary data, for example images,
@@ -222,3 +222,220 @@ Tools
* ``pyside6-designer``: Qt User Interface Designer. This is a graphical tool
to create designs of Qt Widget-based forms and use custom widgets
(see :ref:`using_ui_files`, :ref:`designer_custom_widgets`).
+
+
+.. _NewEnumSystem:
+
+The New Python Enums
+--------------------
+
+The Motivation to use new Enums
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For a long time, there were just the Shiboken enums, which were modelled as exact as possible
+after the existing enums in Qt. These enums are small classes which also inherit from
+int.
+
+Meanwhile, Python enums have been developed over the years. They have become a natural
+part of modern Python. The implementation is perfectly modelled after the needs of Python
+users. It is therefore just consequent to stop having two different enum implementations
+in the same application and instead to use the new Python implementation everywhere.
+
+
+Existing Work
+~~~~~~~~~~~~~
+
+The new enums beginning with PySide 6.3, replace the Shiboken enums
+with Python variants, which harmonize the builtin enums with the already existing
+``QEnum`` "macro" shown in the :ref:`QEnum` section.
+
+
+Enums behavior in PySide
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+In ``PySide 6.3`` there was a double implementation of old and new enums, where the
+default was old enums.
+The new approach to enum is the default in ``PySide 6.4`` and becomes mandatory
+in ``PySide 6.6``. There exists the environment variable ``PYSIDE6_OPTION_PYTHON_ENUM``
+with the default value of "1". There can also variations be selected by specifying
+different flags, but the value of "0" (switching off) is no longer supported.
+
+The still available options for switching some enum features off can be found in the
+:ref:`enum-features` section.
+
+
+The Differences between old and new Enums
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Python enums and Shiboken enums are more or less compatible with each other.
+Tiny differences are in restrictions:
+
+* Python enums cannot inherit from each other, whereas Shiboken enums can
+* Python enums don't allow undefined values, Shiboken enums do
+* Python enums always need exactly one argument, Shiboken enums have a default zero value
+* Python enums rarely inherit from int, Shiboken enums always do
+
+More visible are the differences between flags, as shown in the following:
+
+The Shiboken flag constructor example has been in PySide prior to 6.3:
+
+::
+
+ flags = Qt.Alignment()
+ enum = Qt.AlignmentFlag
+
+with enum shortcuts like
+
+::
+
+ Qt.AlignLeft = Qt.AlignmentFlag.AlignLeft
+ Qt.AlignTop = Qt.AlignmentFlag.AlignTop
+
+In PySide 6.3, these shortcuts and flags no longer exist (officially).
+Instead, Python has an enum.Flags class which is a subclass of the enum.Enum class.
+But don't be too scared, here comes the good news...
+
+
+Doing a Smooth Transition from the Old Enums
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Changing all the enum code to suddenly use the new syntax is cumbersome and error-prone,
+because such necessary changes are not easy to find.
+Therefore a ``forgiveness mode`` was developed:
+
+The ``forgiveness mode`` allows you to continue using the old constructs but translates them
+silently into the new ones. If you for example write
+
+::
+
+ flags = Qt.Alignment()
+ enum = Qt.AlignLeft
+
+ item.setForeground(QColor(Qt.green))
+
+ flags_type = QPainter.RenderHints
+ flags = QPainter.RenderHints()
+
+ chart_view.setRenderHint(QPainter.Antialiasing)
+
+you get in reality a construct that mimics the following code which is the
+recommended way of writing Flags and Enums:
+
+::
+
+ flags = Qt.AlignmentFlag(0)
+ enum = Qt.AlignmentFlag.AlignLeft
+
+ item.setForeground(QColor(Qt.GlobalColor.green))
+
+ flags_type = QPainter.RenderHint
+ flags = QPainter.RenderHint(0)
+
+ chart_view.setRenderHint(QPainter.RenderHint.Antialiasing)
+
+This has the effect that you can initially ignore the difference between old and new enums,
+as long as the new enums are properties of classes. (This does not work on global enums
+which don't have a class, see ``Limitations`` below.)
+
+
+Forgiveness Mode and Type Hints
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When you inspect for instance ``QtCore.pyi``, you will only find the new enums, although
+the old ones are still allowed. Also, line completion will only work with the new constructs
+and never propose the old ones.
+
+The reason to implement ``forgiveness mode`` this way was
+
+* to make the transition as smooth as possible, but
+* to encourage people to use the new enums whenever new code is written.
+
+So you can continue to write:
+
+::
+
+ self.text.setAlignment(Qt.AlignCenter)
+
+but this construct is used and recommended for the future:
+
+::
+
+ self.text.setAlignment(Qt.AlignmentFlag.AlignCenter)
+
+
+Limitations
+~~~~~~~~~~~
+
+The forgiveness mode works very well whenever the enum class is embedded in a normal
+PySide class. But there are a few global enums, where especially the ``QtMsgType``
+is a problem:
+
+::
+
+ t = QtMsgType.QtDebugMsg
+
+cannot be written in the shortcut form
+
+::
+
+ t = QtDebugMsg
+
+because there is no surrounding PySide class that provides the forgiving mode
+implementation. Typically, the needed changes are easily found because they often occur
+in an import statement.
+
+Permission API
+--------------
+
+The cross-platform permission APIs were introduced to Qt in version 6.5 which are currently relevant
+to platforms macOS, iOS, Android and WebAssembly. With this API, your Qt application can check and
+request permission for certain features like Camera, Microphone, Location, Bluetooth, Contacts,
+Calendar. More about permission API can be read in this `Blog post`_.
+
+When a PySide6 application that uses the permission API is run in interpreted mode, i.e.,
+``python <main_file>.py``, the code implementing the permission API *will not work*. The only way
+to make your PySide6 application using permission API work is to bundle the application. For Android,
+this means using the `pyside6-android-deploy`_ tool and for macOS, this means using the
+`pyside6-deploy`_ tool.
+
+When running in interpreted mode, you can skip over the permission check/request using the following
+*if* condition
+
+::
+
+ is_deployed = "__compiled__" in globals()
+ if not is_deployed and sys.platform == "darwin":
+ # code implementing permission check and request
+
+This can also be seen in the PySide6 `Camera example`_. * __compiled__ * is a Nuitka attribute to
+check if the application is run as a standalone application or run in interpreted mode with Python.
+
+Android
+~~~~~~~~
+
+For Android, `pyside6-android-deploy`_ takes care of identifying the necessary permissions needed by
+the application and adding those permissions to the *AndroidManifest.xml* using the
+*<uses-permission>* element.
+
+macOS
+~~~~~
+
+Since the Android platform does not automatically come bundled with a Python interpreter, it is
+evident that to make a PySide6 application run on Android you have to package the PySide6
+application. This is not the case for desktop platforms like macOS where a Python interpreter and
+its packages can be installed and run quite easily.
+
+The problem for macOS is that for the permission API to work you need a macOS bundle with an
+*Info.plist* file that lists all the permissions required using the *usage description* string for
+each permission used. When Python is run in interpreted mode, i.e., when you run Python, the Qt
+permission API fetches the *Info.plist* from the Python interpreter by default which does not
+contain the *usage description* strings for the permissions required. You can certainly modify the
+*Info.plist* of the Python framework installation to make the Qt permission API work when running
+a PySide6 application from the terminal. However, this is not recommended. Therefore, the only
+viable solution is to bundle the PySide6 application as a macOS application bundle using
+`pyside6-deploy`_. This macOS application bundle will have its own Info.plist file.
+
+.. _`Blog post`: https://www.qt.io/blog/permission-apis-in-qt-6.5
+.. _`Camera Example`: https://doc.qt.io/qtforpython-6/examples/example_multimedia_camera.html#camera-example
+.. _`pyside6-android-deploy`: https://doc.qt.io/qtforpython-6/gettingstarted/package_details.html#deployment
+.. _`pyside6-deploy`: https://doc.qt.io/qtforpython-6/gettingstarted/package_details.html#deployment