diff options
Diffstat (limited to 'examples/scriptableapplication')
-rw-r--r-- | examples/scriptableapplication/CMakeLists.txt | 111 | ||||
-rw-r--r-- | examples/scriptableapplication/README.md | 170 | ||||
-rw-r--r-- | examples/scriptableapplication/doc/scriptableapplication.pyproject | 9 | ||||
-rw-r--r-- | examples/scriptableapplication/doc/scriptableapplication.rst | 196 | ||||
-rw-r--r-- | examples/scriptableapplication/main.cpp | 55 | ||||
-rw-r--r-- | examples/scriptableapplication/mainwindow.cpp | 125 | ||||
-rw-r--r-- | examples/scriptableapplication/mainwindow.h | 57 | ||||
-rw-r--r-- | examples/scriptableapplication/pyside.pri | 52 | ||||
-rw-r--r-- | examples/scriptableapplication/pyside2.pri | 52 | ||||
-rw-r--r-- | examples/scriptableapplication/pythonutils.cpp | 84 | ||||
-rw-r--r-- | examples/scriptableapplication/pythonutils.h | 59 | ||||
-rw-r--r-- | examples/scriptableapplication/scriptableapplication.pro | 14 | ||||
-rw-r--r-- | examples/scriptableapplication/scriptableapplication.xml | 51 | ||||
-rw-r--r-- | examples/scriptableapplication/wrappedclasses.h | 51 |
14 files changed, 405 insertions, 681 deletions
diff --git a/examples/scriptableapplication/CMakeLists.txt b/examples/scriptableapplication/CMakeLists.txt index 999206425..fbfa00b98 100644 --- a/examples/scriptableapplication/CMakeLists.txt +++ b/examples/scriptableapplication/CMakeLists.txt @@ -1,5 +1,8 @@ -cmake_minimum_required(VERSION 3.1) -cmake_policy(VERSION 3.1) +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.18) +cmake_policy(VERSION 3.18) # Enable policy to run automoc on generated files. if(POLICY CMP0071) @@ -8,20 +11,34 @@ endif() project(scriptableapplication) -# Set CPP standard to C++11 minimum. -set(CMAKE_CXX_STANDARD 11) +# Set CPP standard to C++17 minimum. +set(CMAKE_CXX_STANDARD 17) # Find required Qt packages. -find_package(Qt5 5.12 REQUIRED COMPONENTS Core Gui Widgets) +find_package(Qt6 COMPONENTS Core Gui Widgets) # Use provided python interpreter if given. if(NOT python_interpreter) - find_program(python_interpreter "python") + if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + find_program(python_interpreter "python_d") + if(NOT python_interpreter) + message(FATAL_ERROR + "A debug Python interpreter could not be found, which is a requirement when " + "building this example in a debug configuration. Make sure python_d.exe is in " + "PATH.") + endif() + else() + find_program(python_interpreter "python") + if(NOT python_interpreter) + message(FATAL_ERROR + "No Python interpreter could be found. Make sure python is in PATH.") + endif() + endif() endif() message(STATUS "Using python interpreter: ${python_interpreter}") # Macro to get various pyside / python include / link flags. -macro(pyside2_config option output_var) +macro(pyside_config option output_var) if(${ARGC} GREATER 2) set(is_list ${ARGV2}) else() @@ -29,33 +46,33 @@ macro(pyside2_config option output_var) endif() execute_process( - COMMAND ${python_interpreter} "${CMAKE_SOURCE_DIR}/../utils/pyside2_config.py" + COMMAND ${python_interpreter} "${CMAKE_SOURCE_DIR}/../utils/pyside_config.py" ${option} OUTPUT_VARIABLE ${output_var} OUTPUT_STRIP_TRAILING_WHITESPACE) if ("${${output_var}}" STREQUAL "") - message(FATAL_ERROR "Error: Calling pyside2_config.py ${option} returned no output.") + message(FATAL_ERROR "Error: Calling pyside_config.py ${option} returned no output.") endif() if(is_list) string (REPLACE " " ";" ${output_var} "${${output_var}}") endif() endmacro() -# Query for the shiboken2-generator path, PySide2 path, Python path, include paths and linker flags. -pyside2_config(--shiboken2-module-path SHIBOKEN2_MODULE_PATH) -pyside2_config(--shiboken2-generator-path SHIBOKEN2_GENERATOR_PATH) -pyside2_config(--pyside2-path PYSIDE2_PATH) +# Query for the shiboken6-generator path, PySide6 path, Python path, include paths and linker flags. +pyside_config(--shiboken-module-path SHIBOKEN_MODULE_PATH) +pyside_config(--shiboken-generator-path SHIBOKEN_GENERATOR_PATH) +pyside_config(--pyside-path PYSIDE_PATH) -pyside2_config(--python-include-path PYTHON_INCLUDE_DIR) -pyside2_config(--shiboken2-generator-include-path SHIBOKEN2_GENERATOR_INCLUDE_DIR 1) -pyside2_config(--pyside2-include-path PYSIDE2_INCLUDE_DIR 1) +pyside_config(--python-include-path PYTHON_INCLUDE_DIR) +pyside_config(--shiboken-generator-include-path SHIBOKEN_GENERATOR_INCLUDE_DIR 1) +pyside_config(--pyside-include-path PYSIDE_INCLUDE_DIR 1) -pyside2_config(--python-link-flags-cmake PYTHON_LINKING_DATA 0) -pyside2_config(--shiboken2-module-shared-libraries-cmake SHIBOKEN2_MODULE_SHARED_LIBRARIES 0) -pyside2_config(--pyside2-shared-libraries-cmake PYSIDE2_SHARED_LIBRARIES 0) +pyside_config(--python-link-flags-cmake PYTHON_LINKING_DATA 0) +pyside_config(--shiboken-module-shared-libraries-cmake SHIBOKEN_MODULE_SHARED_LIBRARIES 0) +pyside_config(--pyside-shared-libraries-cmake PYSIDE_SHARED_LIBRARIES 0) -set(SHIBOKEN_PATH "${SHIBOKEN2_GENERATOR_PATH}/shiboken2${CMAKE_EXECUTABLE_SUFFIX}") +set(SHIBOKEN_PATH "${SHIBOKEN_GENERATOR_PATH}/shiboken6${CMAKE_EXECUTABLE_SUFFIX}") if(NOT EXISTS ${SHIBOKEN_PATH}) message(FATAL_ERROR "Shiboken executable not found at path: ${SHIBOKEN_PATH}") @@ -63,21 +80,19 @@ 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) -get_property(QT_GUI_INCLUDE_DIRS TARGET Qt5::Gui PROPERTY INTERFACE_INCLUDE_DIRECTORIES) -get_property(QT_WIDGETS_INCLUDE_DIRS TARGET Qt5::Widgets PROPERTY INTERFACE_INCLUDE_DIRECTORIES) -set(QT_INCLUDE_DIRS ${QT_CORE_INCLUDE_DIRS} ${QT_GUI_INCLUDE_DIRS} ${QT_WIDGETS_INCLUDE_DIRS}) +get_property(QT_WIDGETS_INCLUDE_DIRS TARGET Qt6::Widgets PROPERTY INTERFACE_INCLUDE_DIRECTORIES) set(INCLUDES "") -foreach(INCLUDE_DIR ${QT_INCLUDE_DIRS}) +foreach(INCLUDE_DIR ${QT_WIDGETS_INCLUDE_DIRS}) list(APPEND INCLUDES "-I${INCLUDE_DIR}") endforeach() # On macOS, check if Qt is a framework build. This affects how include paths should be handled. -get_target_property(QtCore_is_framework Qt5::Core FRAMEWORK) +get_target_property(QtCore_is_framework Qt6::Core FRAMEWORK) if (QtCore_is_framework) - get_target_property(qt_core_library_location Qt5::Core LOCATION) - get_filename_component(qt_core_library_location_dir "${qt_core_library_location}" DIRECTORY) - get_filename_component(lib_dir "${qt_core_library_location_dir}/../" ABSOLUTE) + get_target_property(qt_core_library_location Qt6::Core LOCATION) + # PYSIDE-623: We move up until the directory contains all the frameworks. + # This is "lib" in ".../lib/QtCore.framework/Versions/A/QtCore". + get_filename_component(lib_dir "${qt_core_library_location}/../../../.." ABSOLUTE) list(APPEND INCLUDES "--framework-include-paths=${lib_dir}") endif() @@ -86,12 +101,12 @@ set(WRAPPED_HEADER ${CMAKE_SOURCE_DIR}/wrappedclasses.h) set(TYPESYSTEM_FILE ${CMAKE_SOURCE_DIR}/scriptableapplication.xml) set(SHIBOKEN_OPTIONS --generator-set=shiboken --enable-parent-ctor-heuristic - --enable-pyside-extensions --enable-return-value-heuristic --use-isnull-as-nb_nonzero + --enable-pyside-extensions --enable-return-value-heuristic --use-isnull-as-nb-bool --avoid-protected-hack ${INCLUDES} -I${CMAKE_SOURCE_DIR} -T${CMAKE_SOURCE_DIR} - -T${PYSIDE2_PATH}/typesystems + -T${PYSIDE_PATH}/typesystems --output-directory=${CMAKE_CURRENT_BINARY_DIR} ) @@ -121,11 +136,11 @@ set(SOURCES ) # We need to include the headers for the module bindings that we use. -set(PYSIDE2_ADDITIONAL_INCLUDES "") -foreach(INCLUDE_DIR ${PYSIDE2_INCLUDE_DIR}) - list(APPEND PYSIDE2_ADDITIONAL_INCLUDES "${INCLUDE_DIR}/QtCore") - list(APPEND PYSIDE2_ADDITIONAL_INCLUDES "${INCLUDE_DIR}/QtGui") - list(APPEND PYSIDE2_ADDITIONAL_INCLUDES "${INCLUDE_DIR}/QtWidgets") +set(PYSIDE_ADDITIONAL_INCLUDES "") +foreach(INCLUDE_DIR ${PYSIDE_INCLUDE_DIR}) + list(APPEND PYSIDE_ADDITIONAL_INCLUDES "${INCLUDE_DIR}/QtCore") + list(APPEND PYSIDE_ADDITIONAL_INCLUDES "${INCLUDE_DIR}/QtGui") + list(APPEND PYSIDE_ADDITIONAL_INCLUDES "${INCLUDE_DIR}/QtWidgets") endforeach() # ============================================================================================= @@ -135,7 +150,7 @@ endforeach() # Enable rpaths so that the example can be executed from the build dir. set(CMAKE_SKIP_BUILD_RPATH FALSE) set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) -set(CMAKE_INSTALL_RPATH ${PYSIDE2_PATH} ${SHIBOKEN2_MODULE_PATH}) +set(CMAKE_INSTALL_RPATH ${PYSIDE_PATH} ${SHIBOKEN_MODULE_PATH}) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # ============================================================================================= # !!! End of dubious section. @@ -152,14 +167,14 @@ target_sources(${PROJECT_NAME} PUBLIC ${SOURCES}) # Apply relevant include and link flags. target_include_directories(${PROJECT_NAME} PRIVATE ${PYTHON_INCLUDE_DIR}) -target_include_directories(${PROJECT_NAME} PRIVATE ${SHIBOKEN2_GENERATOR_INCLUDE_DIR}) -target_include_directories(${PROJECT_NAME} PRIVATE ${PYSIDE2_INCLUDE_DIR}) -target_include_directories(${PROJECT_NAME} PRIVATE ${PYSIDE2_ADDITIONAL_INCLUDES}) +target_include_directories(${PROJECT_NAME} PRIVATE ${SHIBOKEN_GENERATOR_INCLUDE_DIR}) +target_include_directories(${PROJECT_NAME} PRIVATE ${PYSIDE_INCLUDE_DIR}) +target_include_directories(${PROJECT_NAME} PRIVATE ${PYSIDE_ADDITIONAL_INCLUDES}) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}) -target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Widgets) -target_link_libraries(${PROJECT_NAME} PRIVATE ${SHIBOKEN2_MODULE_SHARED_LIBRARIES}) -target_link_libraries(${PROJECT_NAME} PRIVATE ${PYSIDE2_SHARED_LIBRARIES}) +target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Widgets) +target_link_libraries(${PROJECT_NAME} PRIVATE ${SHIBOKEN_MODULE_SHARED_LIBRARIES}) +target_link_libraries(${PROJECT_NAME} PRIVATE ${PYSIDE_SHARED_LIBRARIES}) # Find and link to the python library. list(GET PYTHON_LINKING_DATA 0 PYTHON_LIBDIR) @@ -178,7 +193,7 @@ if(WIN32) # Circumvent some "#pragma comment(lib)"s in "include/pyconfig.h" which might force to link # against a wrong python shared library. - set(PYTHON_VERSIONS_LIST 3 32 33 34 35 36 37 38) + set(PYTHON_VERSIONS_LIST 3 36 37 38 39) set(PYTHON_ADDITIONAL_LINK_FLAGS "") foreach(VER ${PYTHON_VERSIONS_LIST}) set(PYTHON_ADDITIONAL_LINK_FLAGS @@ -189,9 +204,9 @@ if(WIN32) set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "${PYTHON_ADDITIONAL_LINK_FLAGS}") - # Add custom target to hard link PySide2 shared libraries (just like in qmake example), so you - # don't have to set PATH manually to point to the PySide2 package. - set(shared_libraries ${SHIBOKEN2_MODULE_SHARED_LIBRARIES} ${PYSIDE2_SHARED_LIBRARIES}) + # Add custom target to hard link PySide6 shared libraries (just like in qmake example), so you + # don't have to set PATH manually to point to the PySide6 package. + set(shared_libraries ${SHIBOKEN_MODULE_SHARED_LIBRARIES} ${PYSIDE_SHARED_LIBRARIES}) foreach(LIBRARY_PATH ${shared_libraries}) string(REGEX REPLACE ".lib$" ".dll" LIBRARY_PATH ${LIBRARY_PATH}) get_filename_component(BASE_NAME ${LIBRARY_PATH} NAME) @@ -201,7 +216,7 @@ if(WIN32) COMMAND mklink /H "${DEST_PATH}" "${SOURCE_PATH}" DEPENDS ${LIBRARY_PATH} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Creating hardlink to PySide2 shared library ${BASE_NAME}") + COMMENT "Creating hardlink to PySide6 shared library ${BASE_NAME}") # Fake target that depends on the previous one, but has special ALL keyword, which means # it will always be executed. diff --git a/examples/scriptableapplication/README.md b/examples/scriptableapplication/README.md deleted file mode 100644 index d359581f1..000000000 --- a/examples/scriptableapplication/README.md +++ /dev/null @@ -1,170 +0,0 @@ -# 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. 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/doc/scriptableapplication.rst b/examples/scriptableapplication/doc/scriptableapplication.rst new file mode 100644 index 000000000..bbabb1247 --- /dev/null +++ b/examples/scriptableapplication/doc/scriptableapplication.rst @@ -0,0 +1,196 @@ +Scriptable Application Example +============================== + +This example demonstrates how to make a Qt C++ application scriptable. + +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/`` +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: + +.. code-block:: 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 PySide 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(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 + 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 + 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 a + compatible version of MSVC, to avoid mixing of C++ runtime libraries. + +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 ++++++++++++ + +To build this example with CMake you will need a recent version of CMake (3.16+). + +You can build this example by executing the following commands +(slightly adapted to your file system layout) in a terminal: + +macOS/Linux: + +.. code-block:: bash + + cd ~/pyside-setup/examples/scriptableapplication + mkdir build + cd build + cmake .. -B. -G Ninja -DCMAKE_BUILD_TYPE=Release + ninja + ./scriptableapplication + +On Windows: + +.. code-block:: bash + + cd C:\pyside-setup\examples\scriptableapplication + mkdir build + cd build + cmake .. -B. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=cl.exe + ninja + .\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: + +.. code-block:: 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\Python39\libs`` +to +``c:\Progra~1\Python39\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 +by setting the ``CC`` environment variable: + +.. code-block:: bash + + set CC=cl + +passing the compiler on the command line: + +.. code-block:: bash + + cmake -S.. -B. -DCMAKE_C_COMPILER=cl.exe -DCMAKE_CXX_COMPILER=cl.exe + +or using the -G option: + +.. code-block:: bash + + cmake -S.. -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 ``ninja``. + +.. code-block:: bash + + MSBuild scriptableapplication.sln "/p:Configuration=Release" + +Note that using the "Ninja" 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 PySide 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 PySide6 build config, otherwise the application will not properly +work. + +In practice this means the only supported configurations are: + +#. release config build of the application + + PySide ``setup.py`` without ``--debug`` flag + ``python.exe`` for the + PySide build process + ``python39.dll`` for the linked in shared + library + release build of Qt. +#. debug config build of the application + + PySide ``setup.py`` *with* ``--debug`` flag + ``python_d.exe`` for the + PySide build process + ``python39_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 (``pyside6.dll``, ``shiboken6.dll``) are hard-linked into the build +folder of the application. diff --git a/examples/scriptableapplication/main.cpp b/examples/scriptableapplication/main.cpp index d7cb4b6db..8fe7ee8a8 100644 --- a/examples/scriptableapplication/main.cpp +++ b/examples/scriptableapplication/main.cpp @@ -1,63 +1,16 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt for Python examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "mainwindow.h" #include <QApplication> -#include <QDesktopWidget> +#include <QScreen> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow mainWindow; - const QRect availableGeometry = a.desktop()->availableGeometry(&mainWindow); + const QRect availableGeometry = mainWindow.screen()->availableGeometry(); mainWindow.resize(availableGeometry.width() / 2, availableGeometry.height() / 2); mainWindow.show(); return a.exec(); diff --git a/examples/scriptableapplication/mainwindow.cpp b/examples/scriptableapplication/mainwindow.cpp index 0811990de..ece7989e7 100644 --- a/examples/scriptableapplication/mainwindow.cpp +++ b/examples/scriptableapplication/mainwindow.cpp @@ -1,57 +1,9 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt for Python examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "mainwindow.h" #include "pythonutils.h" -#include <QtGui.QAction> #include <QtWidgets/QApplication> #include <QtWidgets/QMenu> #include <QtWidgets/QMenuBar> @@ -60,42 +12,51 @@ #include <QtWidgets/QToolBar> #include <QtWidgets/QVBoxLayout> +#include <QtGui/QAction> #include <QtGui/QFontDatabase> #include <QtGui/QIcon> #include <QtCore/QDebug> #include <QtCore/QTextStream> -static const char defaultScript[] = R"( +using namespace Qt::StringLiterals; + +static const auto defaultScript = R"(import AppLib print("Hello, world") mainWindow.testFunction1() -)"; +)"_L1; MainWindow::MainWindow() - : m_scriptEdit(new QPlainTextEdit(QString::fromLatin1(defaultScript).trimmed(), this)) + : m_scriptEdit(new QPlainTextEdit(defaultScript, this)) { setWindowTitle(tr("Scriptable Application")); - QMenu *fileMenu = menuBar()->addMenu(tr("&File")); - const QIcon runIcon = QIcon::fromTheme(QStringLiteral("system-run")); - QAction *runAction = fileMenu->addAction(runIcon, tr("&Run..."), this, &MainWindow::slotRunScript); - runAction->setShortcut(Qt::CTRL + Qt::Key_R); - QAction *diagnosticAction = fileMenu->addAction(tr("&Print Diagnostics"), this, &MainWindow::slotPrintDiagnostics); - diagnosticAction->setShortcut(Qt::CTRL + Qt::Key_D); - fileMenu->addAction(tr("&Invoke testFunction1()"), this, &MainWindow::testFunction1); - const QIcon quitIcon = QIcon::fromTheme(QStringLiteral("application-exit")); - QAction *quitAction = fileMenu->addAction(quitIcon, tr("&Quit"), qApp, &QCoreApplication::quit); - quitAction->setShortcut(Qt::CTRL + Qt::Key_Q); - - QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); - const QIcon clearIcon = QIcon::fromTheme(QStringLiteral("edit-clear")); - QAction *clearAction = editMenu->addAction(clearIcon, tr("&Clear"), m_scriptEdit, &QPlainTextEdit::clear); - - QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); - const QIcon aboutIcon = QIcon::fromTheme(QStringLiteral("help-about")); - QAction *aboutAction = helpMenu->addAction(aboutIcon, tr("&About Qt"), qApp, &QApplication::aboutQt); - - QToolBar *toolBar = new QToolBar; + auto *fileMenu = menuBar()->addMenu(tr("&File")); + const QIcon runIcon = QIcon::fromTheme("system-run"_L1); + auto *runAction = fileMenu->addAction(runIcon, tr("&Run..."), + this, &MainWindow::slotRunScript); + runAction->setShortcut(Qt::CTRL | Qt::Key_R); + auto *diagnosticAction = fileMenu->addAction(tr("&Print Diagnostics"), + this, &MainWindow::slotPrintDiagnostics); + diagnosticAction->setShortcut(Qt::CTRL | Qt::Key_D); + fileMenu->addAction(tr("&Invoke testFunction1()"), + this, &MainWindow::testFunction1); + const QIcon quitIcon = QIcon::fromTheme(QIcon::ThemeIcon::ApplicationExit); + auto *quitAction = fileMenu->addAction(quitIcon, tr("&Quit"), + qApp, &QCoreApplication::quit); + quitAction->setShortcut(Qt::CTRL | Qt::Key_Q); + + auto *editMenu = menuBar()->addMenu(tr("&Edit")); + const QIcon clearIcon = QIcon::fromTheme(QIcon::ThemeIcon::EditClear); + auto *clearAction = editMenu->addAction(clearIcon, tr("&Clear"), + m_scriptEdit, &QPlainTextEdit::clear); + + auto *helpMenu = menuBar()->addMenu(tr("&Help")); + const QIcon aboutIcon = QIcon::fromTheme(QIcon::ThemeIcon::HelpAbout); + auto *aboutAction = helpMenu->addAction(aboutIcon, tr("&About Qt"), + qApp, &QApplication::aboutQt); + + auto *toolBar = new QToolBar; addToolBar(toolBar); toolBar->addAction(quitAction); toolBar->addSeparator(); @@ -108,25 +69,29 @@ MainWindow::MainWindow() m_scriptEdit->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); setCentralWidget(m_scriptEdit); - if (!PythonUtils::bindAppObject("__main__", "mainWindow", PythonUtils::MainWindowType, this)) + if (!PythonUtils::bindAppObject("__main__"_L1, "mainWindow"_L1, + PythonUtils::MainWindowType, this)) { statusBar()->showMessage(tr("Error loading the application module")); + } } void MainWindow::slotRunScript() { - const QStringList script = m_scriptEdit->toPlainText().trimmed().split(QLatin1Char('\n'), Qt::SkipEmptyParts); - if (!script.isEmpty()) - runScript(script); + const QString text = m_scriptEdit->toPlainText().trimmed(); + if (!text.isEmpty()) + runScript(text); } void MainWindow::slotPrintDiagnostics() { - const QStringList script = QStringList() - << "import sys" << "print('Path=', sys.path)" << "print('Executable=', sys.executable)"; + const QString script = R"P(import sys +print('Path=', sys.path) +print('Executable=', sys.executable) +)P"_L1; runScript(script); } -void MainWindow::runScript(const QStringList &script) +void MainWindow::runScript(const QString &script) { if (!::PythonUtils::runScript(script)) statusBar()->showMessage(tr("Error running script")); diff --git a/examples/scriptableapplication/mainwindow.h b/examples/scriptableapplication/mainwindow.h index ce613833c..e72f5ca72 100644 --- a/examples/scriptableapplication/mainwindow.h +++ b/examples/scriptableapplication/mainwindow.h @@ -1,59 +1,12 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt for Python examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QtWidgets/QMainWindow> -class QPlainTextEdit; +QT_FORWARD_DECLARE_CLASS(QPlainTextEdit) class MainWindow : public QMainWindow { @@ -63,12 +16,14 @@ public: void testFunction1(); + static constexpr auto TEST = QLatin1StringView("test"); + private Q_SLOTS: void slotRunScript(); void slotPrintDiagnostics(); private: - void runScript(const QStringList &); + void runScript(const QString &); QPlainTextEdit *m_scriptEdit; }; diff --git a/examples/scriptableapplication/pyside.pri b/examples/scriptableapplication/pyside.pri new file mode 100644 index 000000000..39c8a674d --- /dev/null +++ b/examples/scriptableapplication/pyside.pri @@ -0,0 +1,52 @@ +PYSIDE_CONFIG = $$PWD/../utils/pyside_config.py + +# Use provided python interpreter if given. +isEmpty(python_interpreter) { + python_interpreter = python +} +message(Using python interpreter: $$python_interpreter) + +SHIBOKEN_GENERATOR = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken-generator-path) +isEmpty(SHIBOKEN_GENERATOR): error(Unable to locate the shiboken-generator package location) + +SHIBOKEN_MODULE = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken-module-path) +isEmpty(SHIBOKEN_MODULE): error(Unable to locate the shiboken package location) + +PYSIDE = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside-path) +isEmpty(PYSIDE): error(Unable to locate the PySide package location) + +PYTHON_INCLUDE = $$system($$python_interpreter $$PYSIDE_CONFIG --python-include-path) +isEmpty(PYTHON_INCLUDE): error(Unable to locate the Python include headers directory) + +PYTHON_LFLAGS = $$system($$python_interpreter $$PYSIDE_CONFIG --python-link-flags-qmake) +isEmpty(PYTHON_LFLAGS): error(Unable to locate the Python library for linking) + +SHIBOKEN_INCLUDE = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken-generator-include-path) +isEmpty(SHIBOKEN_INCLUDE): error(Unable to locate the shiboken include headers directory) + +PYSIDE_INCLUDE = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside-include-path) +isEmpty(PYSIDE_INCLUDE): error(Unable to locate PySide include headers directory) + +SHIBOKEN_LFLAGS = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken-module-qmake-lflags) +isEmpty(SHIBOKEN_LFLAGS): error(Unable to locate the shiboken libraries for linking) + +PYSIDE_LFLAGS = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside-qmake-lflags) +isEmpty(PYSIDE_LFLAGS): error(Unable to locate the PySide libraries for linking) + +SHIBOKEN_SHARED_LIBRARIES = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken-module-shared-libraries-qmake) +isEmpty(SHIBOKEN_SHARED_LIBRARIES): error(Unable to locate the used shiboken module shared libraries) + +PYSIDE_SHARED_LIBRARIES = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside-shared-libraries-qmake) +isEmpty(PYSIDE_SHARED_LIBRARIES): error(Unable to locate the used PySide shared libraries) + +INCLUDEPATH += "$$PYTHON_INCLUDE" $$PYSIDE_INCLUDE $$SHIBOKEN_INCLUDE +LIBS += $$PYTHON_LFLAGS $$PYSIDE_LFLAGS $$SHIBOKEN_LFLAGS +!build_pass:message(INCLUDEPATH is $$INCLUDEPATH) +!build_pass:message(LIBS are $$LIBS) + +!build_pass:message(Using $$PYSIDE) + +!win32 { + !build_pass:message(RPATH will include $$PYSIDE and $$SHIBOKEN_MODULE) + QMAKE_RPATHDIR += $$PYSIDE $$SHIBOKEN_MODULE +} diff --git a/examples/scriptableapplication/pyside2.pri b/examples/scriptableapplication/pyside2.pri deleted file mode 100644 index 2da3bc880..000000000 --- a/examples/scriptableapplication/pyside2.pri +++ /dev/null @@ -1,52 +0,0 @@ -PYSIDE_CONFIG = $$PWD/../utils/pyside2_config.py - -# Use provided python interpreter if given. -isEmpty(python_interpreter) { - python_interpreter = python -} -message(Using python interpreter: $$python_interpreter) - -SHIBOKEN2_GENERATOR = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-generator-path) -isEmpty(SHIBOKEN2_GENERATOR): error(Unable to locate the shiboken2-generator package location) - -SHIBOKEN2_MODULE = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-module-path) -isEmpty(SHIBOKEN2_MODULE): error(Unable to locate the shiboken2 package location) - -PYSIDE2 = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside2-path) -isEmpty(PYSIDE2): error(Unable to locate the PySide2 package location) - -PYTHON_INCLUDE = $$system($$python_interpreter $$PYSIDE_CONFIG --python-include-path) -isEmpty(PYTHON_INCLUDE): error(Unable to locate the Python include headers directory) - -PYTHON_LFLAGS = $$system($$python_interpreter $$PYSIDE_CONFIG --python-link-flags-qmake) -isEmpty(PYTHON_LFLAGS): error(Unable to locate the Python library for linking) - -SHIBOKEN2_INCLUDE = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-generator-include-path) -isEmpty(SHIBOKEN2_INCLUDE): error(Unable to locate the shiboken include headers directory) - -PYSIDE2_INCLUDE = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside2-include-path) -isEmpty(PYSIDE2_INCLUDE): error(Unable to locate the PySide2 include headers directory) - -SHIBOKEN2_LFLAGS = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-module-qmake-lflags) -isEmpty(SHIBOKEN2_LFLAGS): error(Unable to locate the shiboken libraries for linking) - -PYSIDE2_LFLAGS = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside2-qmake-lflags) -isEmpty(PYSIDE2_LFLAGS): error(Unable to locate the PySide2 libraries for linking) - -SHIBOKEN2_SHARED_LIBRARIES = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-module-shared-libraries-qmake) -isEmpty(SHIBOKEN2_SHARED_LIBRARIES): error(Unable to locate the used shiboken2 module shared libraries) - -PYSIDE2_SHARED_LIBRARIES = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside2-shared-libraries-qmake) -isEmpty(PYSIDE2_SHARED_LIBRARIES): error(Unable to locate the used PySide2 shared libraries) - -INCLUDEPATH += "$$PYTHON_INCLUDE" $$PYSIDE2_INCLUDE $$SHIBOKEN2_INCLUDE -LIBS += $$PYTHON_LFLAGS $$PYSIDE2_LFLAGS $$SHIBOKEN2_LFLAGS -!build_pass:message(INCLUDEPATH is $$INCLUDEPATH) -!build_pass:message(LIBS are $$LIBS) - -!build_pass:message(Using $$PYSIDE2) - -!win32 { - !build_pass:message(RPATH will include $$PYSIDE2 and $$SHIBOKEN2_MODULE) - QMAKE_RPATHDIR += $$PYSIDE2 $$SHIBOKEN2_MODULE -} diff --git a/examples/scriptableapplication/pythonutils.cpp b/examples/scriptableapplication/pythonutils.cpp index c5e18f256..8104bb167 100644 --- a/examples/scriptableapplication/pythonutils.cpp +++ b/examples/scriptableapplication/pythonutils.cpp @@ -1,52 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt for Python examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #include "pythonutils.h" @@ -64,11 +17,8 @@ /* from AppLib bindings */ -#if PY_MAJOR_VERSION >= 3 - extern "C" PyObject *PyInit_AppLib(); -#else - extern "C" void initAppLib(); -#endif +extern "C" PyObject *PyInit_AppLib(); +static const char moduleName[] = "AppLib"; // This variable stores all Python types exported by this module. extern PyTypeObject **SbkAppLibTypes; @@ -94,14 +44,12 @@ static const char virtualEnvVar[] = "VIRTUAL_ENV"; // packages location. static void initVirtualEnvironment() { - QByteArray virtualEnvPath = qgetenv(virtualEnvVar); // As of Python 3.8, Python is no longer able to run stand-alone in a // virtualenv due to missing libraries. Add the path to the modules instead. if (QOperatingSystemVersion::currentType() == QOperatingSystemVersion::Windows && (PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 8))) { + const QByteArray virtualEnvPath = qgetenv(virtualEnvVar); qputenv("PYTHONPATH", virtualEnvPath + "\\Lib\\site-packages"); - } else { - qputenv("PYTHONHOME", virtualEnvPath); } } @@ -113,15 +61,15 @@ State init() if (qEnvironmentVariableIsSet(virtualEnvVar)) initVirtualEnvironment(); + if (PyImport_AppendInittab(moduleName, PyInit_AppLib) == -1) { + qWarning("Failed to add the module '%s' to the table of built-in modules.", moduleName); + return state; + } + Py_Initialize(); qAddPostRoutine(cleanup); state = PythonInitialized; -#if PY_MAJOR_VERSION >= 3 const bool pythonInitialized = PyInit_AppLib() != nullptr; -#else - const bool pythonInitialized = true; - initAppLib(); -#endif const bool pyErrorOccurred = PyErr_Occurred() != nullptr; if (pythonInitialized && !pyErrorOccurred) { state = AppModuleLoaded; @@ -140,7 +88,7 @@ bool bindAppObject(const QString &moduleName, const QString &name, return false; PyTypeObject *typeObject = SbkAppLibTypes[index]; - PyObject *po = Shiboken::Conversions::pointerToPython(reinterpret_cast<SbkObjectType *>(typeObject), o); + PyObject *po = Shiboken::Conversions::pointerToPython(typeObject, o); if (!po) { qWarning() << __FUNCTION__ << "Failed to create wrapper for" << o; return false; @@ -166,20 +114,14 @@ bool bindAppObject(const QString &moduleName, const QString &name, return true; } -bool runScript(const QStringList &script) +bool runScript(const QString &script) { if (init() == PythonUninitialized) return false; - // Concatenating all the lines - QString content; - QTextStream ss(&content); - for (const QString &line: script) - ss << line << "\n"; - // Executing the whole script as one line bool result = true; - const QByteArray line = content.toUtf8(); + const QByteArray line = script.toUtf8(); if (PyRun_SimpleString(line.constData()) == -1) { if (PyErr_Occurred()) PyErr_Print(); diff --git a/examples/scriptableapplication/pythonutils.h b/examples/scriptableapplication/pythonutils.h index 21aef194e..09e959159 100644 --- a/examples/scriptableapplication/pythonutils.h +++ b/examples/scriptableapplication/pythonutils.h @@ -1,59 +1,12 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt for Python examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #ifndef PYTHONUTILS_H #define PYTHONUTILS_H -class QObject; -class QString; -class QStringList; +#include <QtCore/QStringList> + +QT_FORWARD_DECLARE_CLASS(QObject) namespace PythonUtils { @@ -74,7 +27,7 @@ State init(); bool bindAppObject(const QString &moduleName, const QString &name, int index, QObject *o); -bool runScript(const QStringList &script); +bool runScript(const QString &script); } // namespace PythonUtils diff --git a/examples/scriptableapplication/scriptableapplication.pro b/examples/scriptableapplication/scriptableapplication.pro index 8ebab9476..148a22546 100644 --- a/examples/scriptableapplication/scriptableapplication.pro +++ b/examples/scriptableapplication/scriptableapplication.pro @@ -3,7 +3,7 @@ CONFIG += no_keywords # avoid clash with slots in Python.h CONFIG += console force_debug_info QT += widgets -include(pyside2.pri) +include(pyside.pri) WRAPPED_HEADER = wrappedclasses.h WRAPPER_DIR = $$OUT_PWD/AppLib @@ -17,13 +17,13 @@ qtConfig(framework): QT_INCLUDEPATHS += --framework-include-paths=$$[QT_INSTALL_ SHIBOKEN_OPTIONS = --generator-set=shiboken --enable-parent-ctor-heuristic \ --enable-pyside-extensions --enable-return-value-heuristic --use-isnull-as-nb_nonzero \ - $$QT_INCLUDEPATHS -I$$PWD -T$$PWD -T$$PYSIDE2/typesystems --output-directory=$$OUT_PWD + $$QT_INCLUDEPATHS -I$$PWD -T$$PWD -T$$PYSIDE/typesystems --output-directory=$$OUT_PWD # MSVC does not honor #define protected public... win32:SHIBOKEN_OPTIONS += --avoid-protected-hack # Prepare the shiboken tool -QT_TOOL.shiboken.binary = $$system_path($$SHIBOKEN2_GENERATOR/shiboken2) +QT_TOOL.shiboken.binary = $$system_path($$SHIBOKEN_GENERATOR/shiboken6) qtPrepareTool(SHIBOKEN, shiboken) # Shiboken run that adds the module wrapper to GENERATED_SOURCES @@ -51,7 +51,7 @@ defineReplace(getOutDir) { return($$out_dir) } -# Create hardlinks to the PySide2 shared libraries, so the example can be executed without manually +# Create hardlinks to the PySide shared libraries, so the example can be executed without manually # setting the PATH. win32 { out_dir = $$getOutDir() @@ -61,7 +61,7 @@ win32 { hard_link_libraries.CONFIG = no_link target_predeps explicit_dependencies hard_link_libraries.output = $$out_dir/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT} hard_link_libraries.commands = mklink /H $$shell_path($$out_dir/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}) $$shell_path(${QMAKE_FILE_IN}) - hard_link_libraries.input = PYSIDE2_SHARED_LIBRARIES SHIBOKEN2_SHARED_LIBRARIES + hard_link_libraries.input = PYSIDE_SHARED_LIBRARIES SHIBOKEN6_SHARED_LIBRARIES } QMAKE_EXTRA_COMPILERS += shiboken module_wrapper_dummy_command @@ -69,7 +69,7 @@ win32:QMAKE_EXTRA_COMPILERS += hard_link_libraries INCLUDEPATH += $$WRAPPER_DIR -for(i, PYSIDE2_INCLUDE) { +for(i, PYSIDE_INCLUDE) { INCLUDEPATH += $$i/QtWidgets $$i/QtGui $$i/QtCore } @@ -82,4 +82,4 @@ HEADERS += \ mainwindow.h \ pythonutils.h -OTHER_FILES += $$TYPESYSTEM_FILE $$WRAPPED_HEADER pyside2_config.py README.md +OTHER_FILES += $$TYPESYSTEM_FILE $$WRAPPED_HEADER pyside_config.py README.md diff --git a/examples/scriptableapplication/scriptableapplication.xml b/examples/scriptableapplication/scriptableapplication.xml index 7ef2e9f9e..ef401cb62 100644 --- a/examples/scriptableapplication/scriptableapplication.xml +++ b/examples/scriptableapplication/scriptableapplication.xml @@ -1,54 +1,7 @@ <?xml version="1.0"?> <!-- -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt for Python examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause --> <typesystem package="AppLib"> <load-typesystem name="typesystem_widgets.xml" generate="no"/> diff --git a/examples/scriptableapplication/wrappedclasses.h b/examples/scriptableapplication/wrappedclasses.h index d7661429e..b31ca7f44 100644 --- a/examples/scriptableapplication/wrappedclasses.h +++ b/examples/scriptableapplication/wrappedclasses.h @@ -1,52 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt for Python examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause #ifndef WRAPPEDCLASSES_H #define WRAPPEDCLASSES_H |