1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
# Scriptable Application
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
using Shiboken.
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___`).
It is then possible to run Python script snippets like:
```python
mainWindow.testFunction1()
```
which trigger the underlying C++ function.
## Building the project
This example can be built using *CMake* or *QMake*,
but there are common requirements that you need to take into
consideration:
* Make sure that a --standalone PySide2 package (bundled with Qt libraries)
is installed into the current active Python environment
(system or virtualenv)
* qmake has to be in your PATH:
* so that CMake find_package(Qt5) 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 PySide2, this is to ensure binary compatibility between the
newly generated bindings libraries, the PySide2 libraries and the
Qt libraries.
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 + PySide2 package + app build configuration
is the same (all Release, which is more likely, or all Debug).
* Make sure that your Qt + Python + PySide2 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, and MSVC2008
for Python 2 projects. Which also means that you can't use official Qt
packages, because none of the supported ones are built with MSVC2008.
Both build options will use the `pyside2_config.py` file to configure the project
using the current PySide2/Shiboken2 installation (for qmake via pyside2.pri,
and for CMake via the project CMakeLists.txt).
### Using CMake
To build this example with CMake you will need a recent version of CMake (3.1+).
You can build this example by executing the following commands
(slightly adapted to your file system layout) in a terminal:
On macOS/Linux:
```bash
cd ~/pyside-setup/examples/scriptableapplication
mkdir build
cd build
cmake -H.. -B. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
make
./scriptableapplication
```
On Windows:
```bash
cd C:\pyside-setup\examples\scriptableapplication
mkdir build
cd build
cmake -H.. -B. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release
# or if you have jom available
# cmake -H.. -B. -G "NMake Makefiles JOM" -DCMAKE_BUILD_TYPE=Release
nmake # or jom
scriptableapplication.exe
```
### 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
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
to
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
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
```
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`.
```bash
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
into a directory other than the one that contains the dependency
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
If the 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 application was built while the
`virtualenv` was active, so that the build system picks up the correct
python shared library and PySide2 package.
## Linux Shared Libraries Notes
For this example's purpose, we link against the absolute paths of 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
The build config of the application (Debug or Release) should match
the PySide2 build config, otherwise the application will not properly
work.
In practice this means the only supported configurations are:
1. release config build of the application +
PySide2 `setup.py` without `--debug` flag + `python.exe` for the
PySide2 build process + `python36.dll` for the linked in shared
library + release build of Qt.
2. debug config build of the application +
PySide2 `setup.py` **with** `--debug` flag + `python_d.exe` for the
PySide2 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`).
To make the example as self-contained as possible, the shared libraries
in use (`pyside2.dll`, `shiboken2.dll`) are hard-linked into the build
folder of the application.
|