aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2021-12-07 15:21:37 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2021-12-08 12:12:16 +0100
commitf029a27152cf7c7a741ce03a6f91be71729093ca (patch)
tree06fab915acc36e5598f3b6469706a03d16453d0a /examples
parentf3972822d254ad20b8e9582f89fe8e30ce931f5c (diff)
Document the scriptableapplication, samplebinding examples
Add a dummy .pyproject file into the doc directory for the example gallery script to collect it. Convert the .md files to .rst files for the documentation. Pick-to: 6.2 Change-Id: I87ea5b980d3d2177a7851f71462ca0b0bd0eba7e Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'examples')
-rw-r--r--examples/samplebinding/doc/samplebinding.pyproject10
-rw-r--r--examples/samplebinding/doc/samplebinding.rst (renamed from examples/samplebinding/README.md)232
-rw-r--r--examples/scriptableapplication/doc/scriptableapplication.pyproject9
-rw-r--r--examples/scriptableapplication/doc/scriptableapplication.rst (renamed from examples/scriptableapplication/README.md)148
4 files changed, 233 insertions, 166 deletions
diff --git a/examples/samplebinding/doc/samplebinding.pyproject b/examples/samplebinding/doc/samplebinding.pyproject
new file mode 100644
index 000000000..82c485a09
--- /dev/null
+++ b/examples/samplebinding/doc/samplebinding.pyproject
@@ -0,0 +1,10 @@
+{
+ "files": ["../bindings.h",
+ "../icecream.cpp",
+ "../icecream.h",
+ "../macros.h",
+ "../main.py",
+ "../truck.cpp",
+ "../truck.h",
+ "../CMakeLists.txt"]
+}
diff --git a/examples/samplebinding/README.md b/examples/samplebinding/doc/samplebinding.rst
index 26ff2b383..af2e917dc 100644
--- a/examples/samplebinding/README.md
+++ b/examples/samplebinding/doc/samplebinding.rst
@@ -1,45 +1,49 @@
-# Sample bindings example
+Sample Bindings Example
+=======================
This example showcases how to generate Python bindings for a
non-Qt C++ library.
The example defines a CMake project that builds two libraries:
-* `libuniverse` - a sample library with two C++ classes.
-* `Universe` - the generated Python extension module that contains
+
+* ``libuniverse`` - a sample library with two C++ classes.
+
+* ``Universe`` - the generated Python extension module that contains
bindings to the library above.
The project file is structured in such a way that a user can copy-paste
in into their own project, and be able to build it with a minimal amount
of modifications.
-## Description
+Description
++++++++++++
-The libuniverse library declares two classes: `Icecream` and `Truck`.
+The libuniverse library declares two classes: ``Icecream`` and ``Truck``.
-`Icecream` objects have a flavor, and an accessor for returning the
+``Icecream`` objects have a flavor, and an accessor for returning the
flavor.
-`Truck` instances store a vector of `Icecream` objects, and have various
+``Truck`` instances store a vector of ``Icecream`` objects, and have various
methods for adding new flavors, printing available flavors, delivering
icecream, etc.
-From a C++ perspective, `Icecream` instances are treated as
-**object types** (pointer semantics) because the class declares virtual
+From a C++ perspective, ``Icecream`` instances are treated as
+*object types* (pointer semantics) because the class declares virtual
methods.
-In contrast `Truck` does not define virtual methods and is treated as
-a **value type** (copy semantics).
+In contrast ``Truck`` does not define virtual methods and is treated as
+a *value type* (copy semantics).
-Because `Truck` is a value type and it stores a vector of `Icecream`
+Because ``Truck`` is a value type and it stores a vector of ``Icecream``
pointers, the rule of three has to be taken into account (implement the
copy constructor, assignment operator, destructor).
-And due to `Icecream` objects being copyable, the type has to define an
-implementation of the *clone()* method, to avoid type slicing issues.
+And due to ``Icecream`` objects being copyable, the type has to define an
+implementation of the ``clone()`` method, to avoid type slicing issues.
Both of these types and their methods will be exposed to Python by
-generating CPython code. The code is generated by **shiboken** and
-placed in separate ".cpp" files named after each C++ type. The code is
+generating CPython code. The code is generated by ``shiboken`` and
+placed in separate ``.cpp`` files named after each C++ type. The code is
then compiled and linked into a shared library. The shared library is a
CPython extension module, which is loaded by the Python interpreter.
@@ -48,180 +52,203 @@ needs help in figuring out how to generate the bindings code. This is
done by specifying a special XML file called a typesystem file.
In the typesystem file you specify things like:
+
* which C++ primitive types should have bindings (int, bool, float)
+
* which C++ classes should have bindings (Icecream) and what kind of
semantics (value / object)
+
* Ownership rules (who deletes the C++ objects, C++ or Python)
+
* Code injection (for various special cases that shiboken doesn't know
about)
+
* Package name (name of package as imported from Python)
-In this example we declare `bool` and `std::string` as primitive types,
-`Icecream` as an object type, `Truck` as a value type,
-and the `clone()` and `addIcecreamFlavor(Icecream*)` need additional
+In this example we declare ``bool`` and ``std::string`` as primitive types,
+``Icecream`` as an object type, ``Truck`` as a value type,
+and the ``clone()`` and ``addIcecreamFlavor(Icecream*)`` need additional
info about who owns the parameter objects when passing them across
language boundaries (in this case C++ will delete the objects).
-The `Truck` has getters and setters for the string `arrivalMessage`.
+The ``Truck`` has getters and setters for the string ``arrivalMessage``.
In the type system file, we declare this to be a property in Python:
-```
-<property type="std::string" name="arrivalMessage" get="getArrivalMessage" set="setArrivalMessage"/>
-```
+.. code-block:: xml
+
+ <property type="std::string" name="arrivalMessage" get="getArrivalMessage" set="setArrivalMessage"/>
+
It can then be used in a more pythonic way:
-```
-special_truck.arrivalMessage = "A new SPECIAL icecream truck has arrived!\n"
-```
+.. code-block:: python
+
+ special_truck.arrivalMessage = "A new SPECIAL icecream truck has arrived!\n"
After shiboken generates the C++ code and CMake makes an extension
module from the code, the types can be accessed in Python simply by
importing them using the original C++ names.
-```
-from Universe import Icecream, Truck
-```
+.. code-block:: python
+
+ from Universe import Icecream, Truck
+
Constructing C++ wrapped objects is the same as in Python
-```
-icecream = Icecream("vanilla")
-truck = Truck()
-```
+
+.. code-block:: python
+
+ icecream = Icecream("vanilla")
+ truck = Truck()
And actual C++ constructors are mapped to the Python `__init__` method.
-```
-class VanillaChocolateIcecream(Icecream):
- def __init__(self, flavor=""):
- super().__init__(flavor)
-```
+
+.. code-block:: python
+
+ class VanillaChocolateIcecream(Icecream):
+ def __init__(self, flavor=""):
+ super().__init__(flavor)
C++ methods can be accessed as regular Python methods using the C++
names
-```
-truck.addIcecreamFlavor(icecream)
-```
+.. code-block:: python
+
+ truck.addIcecreamFlavor(icecream)
Inheritance works as with regular Python classes, and virtual C++
methods can be overridden simply by definining a method with the same
name as in the C++ class.
-```
-class VanillaChocolateIcecream(Icecream):
- # ...
- def getFlavor(self):
- return "vanilla sprinked with chocolate"
-```
+.. code-block:: python
+
+ class VanillaChocolateIcecream(Icecream):
+ # ...
+ def getFlavor(self):
+ return "vanilla sprinked with chocolate"
-The `main.py` script demonstrates usages of these types.
+The ``main.py`` script demonstrates usages of these types.
The CMake project file contains many comments explaining all the build
rules for those interested in the build process.
-## Building the project
+Building the project
+++++++++++++++++++++
-This example can only be built using **CMake**.
+This example can only be built using ``CMake``.
The following requirements need to be met:
* A PySide package is installed into the current active Python
environment (system or virtualenv)
-* A new enough version of CMake (**3.1+**).
+
+* A new enough version of CMake (3.1+).
+
* ninja
For Windows you will also need:
+
* a Visual Studio environment to be active in your terminal
+
* Correct visual studio architecture chosen (32 vs 64 bit)
+
* Make sure that your Python intepreter and bindings project build
configuration is the same (all Release, which is more likely,
or all Debug).
-The build uses the `pyside_config.py` file to configure the project
+The build uses the ``pyside_config.py`` file to configure the project
using the current PySide/Shiboken installation.
-### Using CMake
+Using CMake
+===========
You can build and run this example by executing the following commands
(slightly adapted to your file system layout) in a terminal:
macOS/Linux:
-```bash
-cd ~/pyside-setup/examples/samplebinding
-```
+
+.. code-block:: bash
+
+ cd ~/pyside-setup/examples/samplebinding
On Windows:
-```bash
-cd C:\pyside-setup\examples\samplebinding
-```
-
-```bash
-mkdir build
-cd build
-mkdir build
-cd build
-cmake -H.. -B. -G Ninja -DCMAKE_BUILD_TYPE=Release
-ninja
-ninja install
-cd ..
-```
+
+.. code-block:: bash
+
+ cd C:\pyside-setup\examples\samplebinding
+
+.. code-block:: bash
+
+ mkdir build
+ cd build
+ mkdir build
+ cd build
+ cmake -H.. -B. -G Ninja -DCMAKE_BUILD_TYPE=Release
+ ninja
+ ninja install
+ cd ..
The final example can then be run by:
-```bash
-python main.py
-```
-#### Windows troubleshooting
+.. code-block:: bash
+
+ python main.py
+
+Windows troubleshooting
++++++++++++++++++++++++
-It is possible that **CMake** can pick up the wrong compiler
+It is possible that ``CMake`` can pick up the wrong compiler
for a different architecture, but it can be addressed explicitly
-by setting the **CC** environment variable:
+by setting the ``CC`` environment variable:
-```bash
-set CC=cl
-```
+.. code-block:: bash
+
+ set CC=cl
or by using the -G option:
-```bash
-cmake -H.. -B. -G "Visual Studio 14 Win64"
-```
+.. code-block:: bash
+
+ cmake -H.. -B. -G "Visual Studio 14 Win64"
-If the `-G "Visual Studio 14 Win64"` option is used, a `sln` file
-will be generated, and can be used with `MSBuild`
-instead of `nmake/jom`.
+If the ``-G "Visual Studio 14 Win64"`` option is used, a ``sln`` file
+will be generated, and can be used with ``MSBuild``
+instead of ``nmake/jom``.
The easiest way to both build and install in this case, is to use
the cmake executable:
-```bash
-cmake --build . --target install --config Release
-```
+.. code-block:: bash
-Note that using the "NMake Makefiles JOM" generator is preferred to
+ cmake --build . --target install --config Release
+
+Note that using the ``"NMake Makefiles JOM"`` generator is preferred to
the MSBuild one, because the MSBuild one generates configs for both
Debug and Release, and this might lead to building errors if you
accidentally build the wrong config at least once.
-## Virtualenv Support
+Virtualenv Support
+++++++++++++++++++
If the python application is started from a terminal with an activated
python virtual environment, that environment's packages will be used for
the python module import process.
In this case, make sure that the bindings were built while the
-`virtualenv` was active, so that the build system picks up the correct
+``virtualenv`` was active, so that the build system picks up the correct
python shared library and PySide6 / shiboken package.
-## Linux Shared Libraries Notes
+Linux Shared Libraries Notes
+++++++++++++++++++++++++++++
For this example's purpose, we link against the absolute path of the
-dependent shared library `libshiboken` because the
+dependent shared library ``libshiboken`` because the
installation of the library is done via a wheel, and there is
no clean solution to include symbolic links in a wheel package
(so that passing -lshiboken to the linker would work).
-## Windows Notes
+Windows Notes
++++++++++++++
The build config of the bindings (Debug or Release) should match
the PySide build config, otherwise the application will not properly
@@ -229,17 +256,18 @@ work.
In practice this means the only supported configurations are:
-1. release config build of the bindings +
- PySide `setup.py` without `--debug` flag + `python.exe` for the
- PySide build process + `python36.dll` for the linked in shared
+#. release config build of the bindings +
+ PySide ``setup.py`` without ``--debug`` flag + ``python.exe`` for the
+ PySide build process + ``python36.dll`` for the linked in shared
library.
-2. debug config build of the application +
- PySide `setup.py` **with** `--debug` flag + `python_d.exe` for the
- PySide build process + `python36_d.dll` for the linked in shared
+
+#. debug config build of the application +
+ PySide ``setup.py`` *with* ``--debug`` flag + ``python_d.exe`` for the
+ PySide build process + ``python36_d.dll`` for the linked in shared
library.
This is necessary because all the shared libraries in question have to
-link to the same C++ runtime library (`msvcrt.dll` or `msvcrtd.dll`).
+link to the same C++ runtime library (``msvcrt.dll`` or ``msvcrtd.dll``).
To make the example as self-contained as possible, the shared libraries
-in use (`pyside6.dll`, `shiboken6.dll`) are hard-linked into the build
+in use (``pyside6.dll``, ``shiboken6.dll``) are hard-linked into the build
folder of the application.
diff --git a/examples/scriptableapplication/doc/scriptableapplication.pyproject b/examples/scriptableapplication/doc/scriptableapplication.pyproject
new file mode 100644
index 000000000..eee541125
--- /dev/null
+++ b/examples/scriptableapplication/doc/scriptableapplication.pyproject
@@ -0,0 +1,9 @@
+{
+ "files": ["../main.cpp",
+ "../mainwindow.cpp",
+ "../mainwindow.h",
+ "../pythonutils.cpp",
+ "../pythonutils.h",
+ "../wrappedclasses.h",
+ "../CMakeLists.txt"]
+}
diff --git a/examples/scriptableapplication/README.md b/examples/scriptableapplication/doc/scriptableapplication.rst
index d7773c320..46a29bd2f 100644
--- a/examples/scriptableapplication/README.md
+++ b/examples/scriptableapplication/doc/scriptableapplication.rst
@@ -1,28 +1,31 @@
-# Scriptable Application
+Scriptable Application Example
+==============================
This example demonstrates how to make a Qt C++ application scriptable.
-It has a class **MainWindow** (`mainwindow.{cpp,h}`)
-that inherits from *QMainWindow*, for which bindings are generated
+It has a class ``MainWindow`` (files ``mainwindow.cpp,h``)
+that inherits from ``QMainWindow``, for which bindings are generated
using Shiboken.
-The header `wrappedclasses.h` is passed to Shiboken which generates
-class wrappers and headers in a sub directory called **AppLib/**
+The header ``wrappedclasses.h`` is passed to Shiboken which generates
+class wrappers and headers in a sub directory called ``AppLib/``
which are linked to the application.
-The files `pythonutils.{cpp,h}` contain some code which binds the
-instance of **MainWindow** to a variable called **'mainWindow'** in
-the global Python namespace (`__main___`).
+The files ``pythonutils.cpp,h`` contain some code which binds the
+instance of ``MainWindow`` to a variable called ``mainWindow`` in
+the global Python namespace (``__main___``).
It is then possible to run Python script snippets like:
-```python
-mainWindow.testFunction1()
-```
+.. code-block:: python
+
+ mainWindow.testFunction1()
+
which trigger the underlying C++ function.
-## Building the project
+Building the project
+********************
-This example can be built using *CMake* or *QMake*,
+This example can be built using ``CMake`` or ``QMake``,
but there are common requirements that you need to take into
consideration:
@@ -30,9 +33,11 @@ consideration:
is installed into the current active Python environment
(system or virtualenv)
* qmake has to be in your PATH:
+
* so that CMake find_package(Qt6 COMPONENTS Core) works (used for include
headers),
* used for building the application with qmake instead of CMake
+
* use the same Qt version for building the example application, as was used
for building PySide, this is to ensure binary compatibility between the
newly generated bindings libraries, the PySide libraries and the
@@ -40,20 +45,24 @@ consideration:
For Windows you will also need:
* a Visual Studio environment to be active in your terminal
+
* Correct visual studio architecture chosen (32 vs 64 bit)
+
* Make sure that your Qt + Python + PySide package + app build configuration
is the same (all Release, which is more likely, or all Debug).
+
* Make sure that your Qt + Python + PySide package + app are built with the
same version of MSVC, to avoid mixing of C++ runtime libraries.
In principle this means that if you use the python.org provided Python
interpreters, you need to use MSVC2015 for Python 3 projects.
-Both build options will use the `pyside_config.py` file to configure the project
-using the current PySide/Shiboken installation (for qmake via pyside.pri,
-and for CMake via the project CMakeLists.txt).
+Both build options will use the ``pyside_config.py`` file to configure the project
+using the current PySide/Shiboken installation (for qmake via ``pyside.pri``,
+and for CMake via the project ``CMakeLists.txt``).
-### Using CMake
+Using CMake
++++++++++++
To build this example with CMake you will need a recent version of CMake (3.1+).
@@ -61,61 +70,69 @@ You can build this example by executing the following commands
(slightly adapted to your file system layout) in a terminal:
macOS/Linux:
-```bash
-cd ~/pyside-setup/examples/scriptableapplication
-```
+
+.. code-block:: bash
+
+ cd ~/pyside-setup/examples/scriptableapplication
On Windows:
-```bash
-cd C:\pyside-setup\examples\scriptableapplication
-```
-```bash
-mkdir build
-cd build
-cmake -H.. -B. -G Ninja -DCMAKE_BUILD_TYPE=Release
-ninja
-./scriptableapplication
-```
+.. code-block:: bash
+
+ cd C:\pyside-setup\examples\scriptableapplication
-### Using QMake
-The file `scriptableapplication.pro` is the project file associated
+.. code-block:: bash
+
+ mkdir build
+ cd build
+ cmake -H.. -B. -G Ninja -DCMAKE_BUILD_TYPE=Release
+ ninja
+ ./scriptableapplication
+
+Using QMake
++++++++++++
+
+The file ``scriptableapplication.pro`` is the project file associated
to the example when using qmake.
You can build this example by executing:
-```bash
-mkdir build
-cd build
-qmake ..
-make # or nmake / jom for Windows
-```
-#### Windows troubleshooting
+.. code-block:: bash
+
+ mkdir build
+ cd build
+ qmake ..
+ make # or nmake / jom for Windows
+
-Using **qmake** should work out of the box, there was a known issue
+Windows troubleshooting
+***********************
+
+Using ``qmake`` should work out of the box, there was a known issue
with directories and white spaces that is solved by using the
"~1" character, so the path will change from:
-c:\Program Files\Python34\libs
+``c:\Program Files\Python34\libs``
to
-c:\Progra~1\Python34\libs
+``c:\Progra~1\Python34\libs``
this will avoid the issues when the Makefiles are generated.
-It is possible when using **cmake** to pick up the wrong compiler
+It is possible when using ``CMake`` to pick up the wrong compiler
for a different architecture, but it can be addressed explicitly
using the -G option:
-```bash
-cmake -H.. -B. -G "Visual Studio 14 Win64" -DCMAKE_BUILD_TYPE=Release
-```
+.. code-block:: bash
+
+ cmake -H.. -B. -G "Visual Studio 14 Win64" -DCMAKE_BUILD_TYPE=Release
+
+
+If the ``-G "Visual Studio 14 Win64"`` option is used, a ``sln`` file
+will be generated, and can be used with ``MSBuild``
+instead of ``nmake/jom``.
-If the `-G "Visual Studio 14 Win64"` option is used, a `sln` file
-will be generated, and can be used with `MSBuild`
-instead of `nmake/jom`.
+.. code-block:: bash
-```bash
-MSBuild scriptableapplication.sln "/p:Configuration=Release"
-```
+ MSBuild scriptableapplication.sln "/p:Configuration=Release"
Note that using the "NMake Makefiles JOM" generator is preferred to
the MSBuild one, because in the latter case the executable is placed
@@ -124,7 +141,8 @@ dlls (shiboken, pyside). This leads to execution problems if the
application is started within the Release subdirectory and not the
one containing the dependencies.
-## Virtualenv Support
+Virtualenv Support
+******************
If the application is started from a terminal with an activated python
virtual environment, that environment's packages will be used for the
@@ -133,15 +151,17 @@ In this case, make sure that the application was built while the
`virtualenv` was active, so that the build system picks up the correct
python shared library and PySide package.
-## Linux Shared Libraries Notes
+Linux Shared Libraries Notes
+****************************
For this example's purpose, we link against the absolute paths of the
-shared libraries (`libshiboken` and `libpyside`) because the
+shared libraries (``libshiboken`` and ``libpyside``) because the
installation of the modules is being done via wheels, and there is
no clean solution to include symbolic links in the package
(so that regular -lshiboken works).
-## Windows Notes
+Windows Notes
+*************
The build config of the application (Debug or Release) should match
the PySide6 build config, otherwise the application will not properly
@@ -149,17 +169,17 @@ work.
In practice this means the only supported configurations are:
-1. release config build of the application +
- PySide `setup.py` without `--debug` flag + `python.exe` for the
- PySide build process + `python36.dll` for the linked in shared
+#. release config build of the application +
+ PySide ``setup.py`` without ``--debug`` flag + ``python.exe`` for the
+ PySide build process + ``python36.dll`` for the linked in shared
library + release build of Qt.
-2. debug config build of the application +
- PySide `setup.py` **with** `--debug` flag + `python_d.exe` for the
- PySide build process + `python36_d.dll` for the linked in shared
+#. debug config build of the application +
+ PySide ``setup.py`` *with* ``--debug`` flag + ``python_d.exe`` for the
+ PySide build process + ``python36_d.dll`` for the linked in shared
library + debug build of Qt.
This is necessary because all the shared libraries in question have to
-link to the same C++ runtime library (`msvcrt.dll` or `msvcrtd.dll`).
+link to the same C++ runtime library (``msvcrt.dll`` or ``msvcrtd.dll``).
To make the example as self-contained as possible, the shared libraries
-in use (`pyside6.dll`, `shiboken6.dll`) are hard-linked into the build
+in use (``pyside6.dll``, ``shiboken6.dll``) are hard-linked into the build
folder of the application.