aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorCristian Maureira-Fredes <cristian.maureira-fredes@qt.io>2018-04-17 17:51:11 +0200
committerCristian Maureira-Fredes <cristian.maureira-fredes@qt.io>2018-05-04 15:25:32 +0000
commite124f12e95cbf44bc5fc391846ddeedf2c042680 (patch)
tree39eed87665c53c4694b81a3103313a160ce0c10a /examples
parent8ed37563888f7956da99636c62f18459729d5966 (diff)
Update scriptableapplication example
Absolute paths are used to link the PySide2 libraries on Linux, since it's not possible to ship symbolic links inside a wheel. The README.txt was renamed to README.md to allow syntax highlight on modern editors and also to be compatible with online platforms. The README.CMake.txt was merge to the README.md to include the instruction on the same file. Change-Id: Ie0fcb8cda770ff552576f6014b5822f8d278bfe6 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'examples')
-rw-r--r--examples/scriptableapplication/CMakeLists.txt8
-rw-r--r--examples/scriptableapplication/README.CMake.txt28
-rw-r--r--examples/scriptableapplication/README.md155
-rw-r--r--examples/scriptableapplication/README.txt33
-rw-r--r--examples/scriptableapplication/pyside2.pri6
-rw-r--r--examples/scriptableapplication/pyside2_config.py39
-rw-r--r--examples/scriptableapplication/scriptableapplication.pro4
7 files changed, 198 insertions, 75 deletions
diff --git a/examples/scriptableapplication/CMakeLists.txt b/examples/scriptableapplication/CMakeLists.txt
index 368fd7d25..be5b17398 100644
--- a/examples/scriptableapplication/CMakeLists.txt
+++ b/examples/scriptableapplication/CMakeLists.txt
@@ -45,8 +45,12 @@ endif()
pyside2_config(--python-include PYTHON_INCLUDE_DIR)
pyside2_config(--pyside2-include PYSIDE2_INCLUDE_DIR 1)
-pyside2_config(--python-link-cmake PYTHON_LINKING_DATA 1)
pyside2_config(--pyside2-shared-libraries-cmake PYSIDE2_SHARED_LIBRARIES 1)
+if(WIN32)
+pyside2_config(--python-link-cmake PYTHON_LINKING_DATA 0)
+else()
+pyside2_config(--python-link-cmake PYTHON_LINKING_DATA 1)
+endif()
# Get all relevant Qt include dirs, to pass them on to shiboken.
get_property(QT_CORE_INCLUDE_DIRS TARGET Qt5::Core PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
@@ -148,7 +152,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${PYSIDE2_SHARED_LIBRARIES})
# Find and link to the python library.
list(GET PYTHON_LINKING_DATA 0 PYTHON_LIBDIR)
list(GET PYTHON_LINKING_DATA 1 PYTHON_LIB)
-find_library(PYTHON_LINK_FLAGS ${PYTHON_LIB} HINTS ${PYTHON_LIBDIR})
+find_library(PYTHON_LINK_FLAGS ${PYTHON_LIB} PATHS ${PYTHON_LIBDIR} HINTS ${PYTHON_LIBDIR} NO_DEFAULT_PATH)
target_link_libraries(${PROJECT_NAME} PRIVATE ${PYTHON_LINK_FLAGS})
# Same as CONFIG += no_keywords to avoid syntax errors in object.h due to the usage of the word Slot
diff --git a/examples/scriptableapplication/README.CMake.txt b/examples/scriptableapplication/README.CMake.txt
deleted file mode 100644
index ea658efd5..000000000
--- a/examples/scriptableapplication/README.CMake.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-For general information read README.txt instead.
-
-To build this example you will need:
-* A recent version of CMake (3.1+)
-* Make sure that a --standalone PySide2 package (bundled with Qt libraries) is installed into the
- current active Python environment (system or virtualenv)
-* qmake to be in your PATH (so that CMake find_package(Qt5) works; used for include headers)
-* 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:
-* 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 + CMake app build configuration is the same (either or
- all Release (which is more likely) or all Debug).
-
-You can build this example by executing the following commands (slightly adapted to your file
-system) in a terminal:
-
-cd ~/pyside-setup/examples/scriptableapplication
-(or cd C:\pyside-setup\examples\scriptableapplication)
-mkdir build
-cd build
-cmake -H.. -B. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
-(or cmake -H.. -B. -G "NMake Makefiles JOM" -DCMAKE_BUILD_TYPE=Release)
-make (or nmake / jom)
-./scriptableapplication (or scriptableapplication.exe)
diff --git a/examples/scriptableapplication/README.md b/examples/scriptableapplication/README.md
new file mode 100644
index 000000000..98e12b7b4
--- /dev/null
+++ b/examples/scriptableapplication/README.md
@@ -0,0 +1,155 @@
+# 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}` contains 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 to be in your PATH:
+ * so that CMake find_package(Qt5) works (used for include headers),
+ * and also for using the proper qmake version when building with qmake
+* 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:
+* 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 + app build configuration
+ is the same (either or all Release, which is more likely, or all Debug).
+
+Both build options will use the `pyside2.pri` file to configure the project
+using the current PySide2/Shiboken2 installation (via `pyside2_config.py`).
+
+Keep in mind that Clang libraries must be on your path.
+
+
+### 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) 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 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 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:DebugType=None"
+```
+
+## 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.
+
+## Shared Libraries Notes
+
+For this example's purpose, we are using the absolute path of the
+shared libraries (`libshiboken` and `libpyside`) because the
+installation of the modules is being made via wheels, and there is
+no clean solution to include symbolic links into the package.
+
+## 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.
diff --git a/examples/scriptableapplication/README.txt b/examples/scriptableapplication/README.txt
deleted file mode 100644
index 28bdb44ae..000000000
--- a/examples/scriptableapplication/README.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-scriptableapplication demonstrates how to make a Qt C++ application scriptable.
-
-It has a class MainWindow inheriting QMainWindow for which bindings are generated
-using PySide2's shiboken2 bindings generator.
-
-The header wrappedclasses.h is passed to shiboken2 which generates class
-wrappers and headers in a subdirectory which are linked into the application.
-
-pythonutils.cpp has some code which binds the instance of MainWindow
-to a variable 'mainWindow' in the global (__main___) namespace.
-It is then possible to run Python script snippets like
-mainWindow.testFunction1() which trigger the underlying C++ function.
-
-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.
-
-Windows Notes
-The build config of the application (Debug or Release) should match the PySide2 build config,
-otherwise the application will not function correctly. In practice this means the only supported
-configurations are:
-1) qmake 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) qmake 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.
diff --git a/examples/scriptableapplication/pyside2.pri b/examples/scriptableapplication/pyside2.pri
index bd0eeef9e..acab9e961 100644
--- a/examples/scriptableapplication/pyside2.pri
+++ b/examples/scriptableapplication/pyside2.pri
@@ -9,8 +9,12 @@ PYSIDE2_LFLAGS = $$system(python $$PWD/pyside2_config.py --pyside2-link)
PYSIDE2_SHARED_LIBRARIES = $$system(python $$PWD/pyside2_config.py --pyside2-shared-libraries)
CLANG_BIN_DIR = $$system(python $$PWD/pyside2_config.py --clang-bin-dir)
-INCLUDEPATH += $$PYTHON_INCLUDE $$PYSIDE2_INCLUDE
+INCLUDEPATH += "$$PYTHON_INCLUDE" $$PYSIDE2_INCLUDE
LIBS += $$PYTHON_LFLAGS $$PYSIDE2_LFLAGS
+LIBPATH += $$PYTHON_LFLAGS $$PYSIDE2_LFLAGS
+!build_pass:message(INCLUDEPATH is $$INCLUDEPATH)
+!build_pass:message(LIBS are $$LIBS)
+!build_pass:message(LIBPATH is $$LIBPATH)
!build_pass:message(Using $$PYSIDE2)
diff --git a/examples/scriptableapplication/pyside2_config.py b/examples/scriptableapplication/pyside2_config.py
index a26d2b490..781c30b64 100644
--- a/examples/scriptableapplication/pyside2_config.py
+++ b/examples/scriptableapplication/pyside2_config.py
@@ -67,7 +67,9 @@ def sharedLibrarySuffix():
return 'lib'
elif sys.platform == 'darwin':
return 'dylib'
- return 'so'
+ # Linux
+ else:
+ return 'so.*'
def sharedLibraryGlobPattern():
glob = '*.' + sharedLibrarySuffix()
@@ -84,12 +86,18 @@ def filterPySide2SharedLibraries(list):
# Return qmake link option for a library file name
def linkOption(lib):
- baseName = os.path.splitext(os.path.basename(lib))[0]
+ # On Linux:
+ # Since we cannot include symlinks with wheel packages
+ # we are using an absolute path for the libpyside and libshiboken
+ # libraries when compiling the project
+ baseName = os.path.basename(lib)
link = ' -l'
- if sys.platform in ['linux', 'linux2', 'darwin']: # Linux: 'libfoo.so' -> '-lfoo'
- link += baseName[3:]
+ if sys.platform in ['linux', 'linux2']: # Linux: 'libfoo.so' -> '-lfoo'
+ link = lib
+ elif sys.platform in ['darwin']: # Linux: 'libfoo.so' -> '-lfoo'
+ link += os.path.splitext(baseName[3:])[0]
else:
- link += baseName
+ link += os.path.splitext(baseName)[0]
return link
# Locate PySide2 via package path
@@ -110,17 +118,30 @@ def pythonInclude():
def pythonLinkQmake():
flags = pythonLinkData()
- if sys.platform == 'win32' or sys.platform == 'darwin':
+ if sys.platform == 'win32':
+ libdir = flags['libdir']
+ # This will add the "~1" shortcut for directories that
+ # contain white spaces
+ # e.g.: "Program Files" to "Progra~1"
+ for d in libdir.split("\\"):
+ if " " in d:
+ libdir = libdir.replace(d, d.split(" ")[0][:-1]+"~1")
+ return '-L{} -l{}'.format(libdir, flags['lib'])
+ elif sys.platform == 'darwin':
return '-L{} -l{}'.format(flags['libdir'], flags['lib'])
- # Linux and anything else
- return '-l{}'.format(flags['lib'])
+ else:
+ # Linux and anything else
+ return '-L{} -l{}'.format(flags['libdir'], flags['lib'])
def pythonLinkCmake():
flags = pythonLinkData()
libdir = flags['libdir']
lib = re.sub(r'.dll$', '.lib', flags['lib'])
- return '{} {}'.format(libdir, lib)
+ if sys.platform == 'win32':
+ return '{};{}'.format(libdir, lib)
+ else:
+ return '{} {}'.format(libdir, lib)
def pythonLinkData():
# @TODO Fix to work with static builds of Python
diff --git a/examples/scriptableapplication/scriptableapplication.pro b/examples/scriptableapplication/scriptableapplication.pro
index bcb05c115..ee96afde0 100644
--- a/examples/scriptableapplication/scriptableapplication.pro
+++ b/examples/scriptableapplication/scriptableapplication.pro
@@ -9,8 +9,8 @@ WRAPPED_HEADER = wrappedclasses.h
WRAPPER_DIR = $$OUT_PWD/AppLib
TYPESYSTEM_FILE = scriptableapplication.xml
-QT_INCLUDEPATHS = -I$$[QT_INSTALL_HEADERS] -I$$[QT_INSTALL_HEADERS]/QtCore \
- -I$$[QT_INSTALL_HEADERS]/QtGui -I$$[QT_INSTALL_HEADERS]/QtWidgets
+QT_INCLUDEPATHS = -I"$$[QT_INSTALL_HEADERS]" -I"$$[QT_INSTALL_HEADERS]/QtCore" \
+ -I"$$[QT_INSTALL_HEADERS]/QtGui" -I"$$[QT_INSTALL_HEADERS]/QtWidgets"
# On macOS, check if Qt is a framework build. This affects how include paths should be handled.
qtConfig(framework): QT_INCLUDEPATHS += --framework-include-paths=$$[QT_INSTALL_LIBS]