diff --git a/CMakeLists.txt b/CMakeLists.txt index 2349303a..0d1deb31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,39 @@ cmake_minimum_required(VERSION 2.8) project(PythonQt) #----------------------------------------------------------------------------- +#---------------------------------------------------------------------------- +# Qt version + +# Sanity checks +if(DEFINED Qt5_DIR AND DEFINED QT_QMAKE_EXECUTABLE) + message(FATAL_ERROR + "${PROJECT_NAME} shoult NOT be configured setting both Qt5_DIR and QT_QMAKE_EXECUTABLE options. +To build with Qt4, specify QT_QMAKE_EXECUTABLE. To build with Qt5, specify Qt5_DIR.") +endif() + +# Set PythonQt_QT_VERSION +if(DEFINED Qt5_DIR) + message(STATUS "${PROJECT_NAME}: Setting PythonQt_QT_VERSION to 5 because Qt5_DIR is defined.") + set(PythonQt_QT_VERSION 5) +elseif(DEFINED QT_QMAKE_EXECUTABLE) + message(STATUS "${PROJECT_NAME}: Setting PythonQt_QT_VERSION to 4 because QT_QMAKE_EXECUTABLE is defined.") + set(PythonQt_QT_VERSION 4) +else() + set(PythonQt_QT_VERSION 4 CACHE STRING "Pick a version of Qt to use: 4 or 5") + # Set the possible values of Qt version for cmake-gui + set_property(CACHE PythonQt_QT_VERSION PROPERTY STRINGS "4" "5") +endif() + +# Requirements +set(minimum_required_qt5_version "5.3.0") +set(minimum_required_qt4_version "4.6.2") +set(minimum_required_qt_version ${minimum_required_qt${PythonQt_QT_VERSION}_version}) + +# Qt components +set(qt5libs Core Widgets Network OpenGL Sql Svg UiTools WebKitWidgets Xml XmlPatterns) +set(qt4libs core gui network opengl sql svg uitools webkit xml xmlpatterns) +set(qtlibs ${qt${PythonQt_QT_VERSION}libs}) + #----------------------------------------------------------------------------- # Python libraries @@ -40,17 +73,41 @@ if(NOT DEFINED PythonQt_INSTALL_INCLUDE_DIR) set(PythonQt_INSTALL_INCLUDE_DIR include/PythonQt) endif() +# Since the Qt bindings sources used for both Qt4 and Qt5 are +# grouped using Qt4 naming convention, qt_wrapped_libs variables are the +# same for the two Qt versions. +set(qt4_wrapped_libs ${qt4libs}) +set(qt5_wrapped_libs ${qt4libs}) +set(qt_wrapped_libs ${qt${PythonQt_QT_VERSION}_wrapped_libs}) + +set(qt5_wrapped_lib_depends_gui Multimedia) + +set(qtlib_to_wraplib_Widgets gui) +set(qtlib_to_wraplib_WebKitWidgets webkit) + +# Define PythonQt_Wrap_Qt* options option(PythonQt_Wrap_QtAll "Make all Qt components available in python" OFF) +foreach(qtlib ${qt_wrapped_libs}) + OPTION(PythonQt_Wrap_Qt${qtlib} "Make all of Qt${qtlib} available in python" OFF) +endforeach() -set(qtlibs core gui network opengl sql svg uitools webkit xml xmlpatterns) +# Set qtlib_to_wraplib_* variables foreach(qtlib ${qtlibs}) - OPTION(PythonQt_Wrap_Qt${qtlib} "Make all of Qt${qtlib} available in python" OFF) + string(TOLOWER ${qtlib} qtlib_lowercase) + if(DEFINED qtlib_to_wraplib_${qtlib}) + set(qtlib_lowercase ${qtlib_to_wraplib_${qtlib}}) + endif() + set(qtlib_to_wraplib_${qtlib} ${qtlib_lowercase}) endforeach() # Force option if it applies if(PythonQt_Wrap_QtAll) - list(REMOVE_ITEM qtlibs xmlpatterns) # xmlpatterns wrapper does *NOT* build at all :( - foreach(qtlib ${qtlibs}) + set(_qt_wrapped_libs ${qt_wrapped_libs}) + + # XXX xmlpatterns wrapper does *NOT* build at all :( + list(REMOVE_ITEM _qt_wrapped_libs xmlpatterns) + + foreach(qtlib ${_qt_wrapped_libs}) if(NOT ${PythonQt_Wrap_Qt${qtlib}}) set(PythonQt_Wrap_Qt${qtlib} ON CACHE BOOL "Make all of Qt${qtlib} available in python" FORCE) message(STATUS "Enabling [PythonQt_Wrap_Qt${qtlib}] because of [PythonQt_Wrap_QtAll] evaluates to True") @@ -68,40 +125,86 @@ endif() #----------------------------------------------------------------------------- # Setup Qt -set(minimum_required_qt_version "4.6.2") +if(PythonQt_QT_VERSION VERSION_GREATER "4") + + # Required components + set(qt_required_components Core Widgets) + foreach(qtlib ${qtlibs}) + set(qt_wrapped_lib ${qtlib_to_wraplib_${qtlib}}) + if(${PythonQt_Wrap_Qt${qt_wrapped_lib}}) + list(APPEND qt_required_components ${qtlib} ${qt${PythonQt_QT_VERSION}_wrapped_lib_depends_${qt_wrapped_lib}}) + endif() + endforeach() + if(BUILD_TESTING) + list(APPEND qt_required_components Test) + endif() + list(REMOVE_DUPLICATES qt_required_components) -find_package(Qt4) + message(STATUS "${PROJECT_NAME}: Required Qt components [${qt_required_components}]") + find_package(Qt5 ${minimum_required_qt_version} COMPONENTS ${qt_required_components} REQUIRED) -if(QT4_FOUND) + set(QT_LIBRARIES ) + foreach(qtlib ${qt_required_components}) + include_directories(${Qt5${qtlib}_INCLUDE_DIRS}) + add_definitions(${Qt5${qtlib}_DEFINITIONS}) + list(APPEND QT_LIBRARIES ${Qt5${qtlib}_LIBRARIES}) + endforeach() - set(found_qt_version ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}) + set(QT_VERSION_MAJOR ${Qt5Core_VERSION_MAJOR}) + set(QT_VERSION_MINOR ${Qt5Core_VERSION_MINOR}) - if(${found_qt_version} VERSION_LESS ${minimum_required_qt_version}) - message(FATAL_ERROR "error: PythonQt requires Qt >= ${minimum_required_qt_version} -- you cannot use Qt ${found_qt_version}.") - endif() + macro(pythonqt_wrap_cpp) + qt5_wrap_cpp(${ARGV}) + endmacro() - # Enable required qt module - foreach(qtlib network opengl sql svg uitools webkit xml xmlpatterns) - string(TOUPPER ${qtlib} qtlib_uppercase) - if (NOT ${QT_QT${qtlib_uppercase}_FOUND}) - message(FATAL_ERROR "QT_QT${qtlib_uppercase} *not* FOUND - Try to disable PythonQt_Wrap_Qt${qtlib}") +else() + + find_package(Qt4) + + if(QT4_FOUND) + + set(found_qt_version ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}) + + if(${found_qt_version} VERSION_LESS ${minimum_required_qt_version}) + message(FATAL_ERROR "error: PythonQt requires Qt >= ${minimum_required_qt_version} -- you cannot use Qt ${found_qt_version}.") endif() - set(QT_USE_QT${qtlib_uppercase} ${PythonQt_Wrap_Qt${qtlib}}) - endforeach() - set(QT_USE_QTTEST ${BUILD_TESTING}) + # Enable required qt module + foreach(qtlib ${qt_wrapped_libs}) + string(TOUPPER ${qtlib} qtlib_uppercase) + if (NOT ${QT_QT${qtlib_uppercase}_FOUND}) + message(FATAL_ERROR "QT_QT${qtlib_uppercase} *not* FOUND - Try to disable PythonQt_Wrap_Qt${qtlib}") + endif() + set(QT_USE_QT${qtlib_uppercase} ${PythonQt_Wrap_Qt${qtlib}}) + endforeach() + + # Enable QtTest in Qt4 is the option BUILD_TESTING was activated + set(QT_USE_QTTEST ${BUILD_TESTING}) + + include(${QT_USE_FILE}) + else() + message(FATAL_ERROR "error: Qt4 was not found on your system. You probably need to set the QT_QMAKE_EXECUTABLE variable") + endif() + + macro(pythonqt_wrap_cpp) + qt4_wrap_cpp(${ARGV}) + endmacro() - include(${QT_USE_FILE}) -else() - message(FATAL_ERROR "error: Qt4 was not found on your system. You probably need to set the QT_QMAKE_EXECUTABLE variable") endif() #----------------------------------------------------------------------------- # The variable "generated_cpp_suffix" allows to conditionnally compile the generated wrappers # associated with the Qt version being used. + +set(generated_cpp_suffix_46 _47) +set(generated_cpp_suffix_52 _50) +set(generated_cpp_suffix_51 _50) + set(generated_cpp_suffix "_${QT_VERSION_MAJOR}${QT_VERSION_MINOR}") -if("${generated_cpp_suffix}" STREQUAL "_46") - set(generated_cpp_suffix "_47") # Also use 4.7 wrappers for 4.6.x version +if(DEFINED generated_cpp_suffix_${QT_VERSION_MAJOR}${QT_VERSION_MINOR}) + set(generated_cpp_suffix "${generated_cpp_suffix_${QT_VERSION_MAJOR}${QT_VERSION_MINOR}}") +elseif(${QT_VERSION_MAJOR}.${QT_VERSION_MINOR} VERSION_GREATER "5.4") + set(generated_cpp_suffix "_54") endif() #----------------------------------------------------------------------------- @@ -181,7 +284,7 @@ set(moc_sources #----------------------------------------------------------------------------- # Add extra sources -foreach(qtlib core gui network opengl sql svg uitools webkit xml xmlpatterns) +foreach(qtlib ${qt_wrapped_libs}) if (${PythonQt_Wrap_Qt${qtlib}}) @@ -189,7 +292,7 @@ foreach(qtlib core gui network opengl sql svg uitools webkit xml xmlpatterns) set(file_prefix generated_cpp${generated_cpp_suffix}/com_trolltech_qt_${qtlib}/com_trolltech_qt_${qtlib}) - foreach(index RANGE 0 11) + foreach(index RANGE 0 12) # Source files if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file_prefix}${index}.cpp) @@ -208,19 +311,9 @@ foreach(qtlib core gui network opengl sql svg uitools webkit xml xmlpatterns) endif() endforeach() -#----------------------------------------------------------------------------- -# UI files -set(ui_sources ) - -#----------------------------------------------------------------------------- -# Resources -set(qrc_sources ) - #----------------------------------------------------------------------------- # Do wrapping -qt4_wrap_cpp(gen_moc_sources ${moc_sources}) -qt4_wrap_ui(gen_ui_sources ${ui_sources}) -qt4_add_resources(gen_qrc_sources ${qrc_sources}) +pythonqt_wrap_cpp(gen_moc_sources ${moc_sources}) #----------------------------------------------------------------------------- # Build the library @@ -232,8 +325,6 @@ include_directories( add_library(PythonQt SHARED ${sources} ${gen_moc_sources} - ${gen_ui_sources} - ${gen_qrc_sources} ) set_target_properties(PythonQt PROPERTIES DEFINE_SYMBOL PYTHONQT_EXPORTS) @@ -270,12 +361,14 @@ if(BUILD_TESTING) tests/PythonQtTestMain.cpp ) + set_property(SOURCE tests/PythonQtTestMain.cpp PROPERTY COMPILE_DEFINITIONS "main=tests_PythonQtTestMain") + list(APPEND test_sources tests/PythonQtTests.cpp tests/PythonQtTests.h ) - QT4_WRAP_CPP(test_sources + pythonqt_wrap_cpp(test_sources tests/PythonQtTests.h ) @@ -286,12 +379,12 @@ if(BUILD_TESTING) tests/PythonQtTestCleanup.cpp tests/PythonQtTestCleanup.h ) - QT4_WRAP_CPP(test_sources + pythonqt_wrap_cpp(test_sources tests/PythonQtTestCleanup.h ) - endif() - set_property(SOURCE tests/PythonQtTestMain.cpp PROPERTY COMPILE_DEFINITIONS "main=tests_PythonQtTestMain") + set_property(SOURCE tests/PythonQtTestMain.cpp APPEND PROPERTY COMPILE_DEFINITIONS "PythonQt_Wrap_Qtcore") + endif() add_executable(PythonQtCppTests ${test_sources}) target_link_libraries(PythonQtCppTests PythonQt) diff --git a/generated_cpp_50/PythonQt_QtBindings.cpp b/generated_cpp_50/PythonQt_QtBindings.cpp new file mode 100644 index 00000000..7ae1630a --- /dev/null +++ b/generated_cpp_50/PythonQt_QtBindings.cpp @@ -0,0 +1,58 @@ + +#include "PythonQt_QtBindings.h" + +#include "PythonQt.h" + +void PythonQt_init_QtGui(PyObject*); +void PythonQt_init_QtSvg(PyObject*); +void PythonQt_init_QtSql(PyObject*); +void PythonQt_init_QtNetwork(PyObject*); +void PythonQt_init_QtCore(PyObject*); +void PythonQt_init_QtWebKit(PyObject*); +void PythonQt_init_QtOpenGL(PyObject*); +void PythonQt_init_QtXml(PyObject*); +void PythonQt_init_QtXmlPatterns(PyObject*); +void PythonQt_init_QtUiTools(PyObject*); + +PYTHONQT_EXPORT void PythonQt_init_QtBindings() + { + #ifdef PYTHONQT_WRAP_Qtcore + PythonQt_init_QtCore(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtgui + PythonQt_init_QtGui(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtnetwork + PythonQt_init_QtNetwork(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtopengl + PythonQt_init_QtOpenGL(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtsql + PythonQt_init_QtSql(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtsvg + PythonQt_init_QtSvg(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtuitools + PythonQt_init_QtUiTools(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtwebkit + PythonQt_init_QtWebKit(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtxml + PythonQt_init_QtXml(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtxmlpatterns + PythonQt_init_QtXmlPatterns(0); + #endif + }; diff --git a/generated_cpp_50/PythonQt_QtBindings.h b/generated_cpp_50/PythonQt_QtBindings.h new file mode 100644 index 00000000..03e96aed --- /dev/null +++ b/generated_cpp_50/PythonQt_QtBindings.h @@ -0,0 +1,10 @@ +#ifndef _PYTHONQT_QTBINDINGS_H +#define _PYTHONQT_QTBINDINGS_H + +#include "PythonQtSystem.h" + +/// Initialize Qt bindings enabled at configuration time +PYTHONQT_EXPORT void PythonQt_init_QtBindings(); + +#endif + diff --git a/generated_cpp_53/PythonQt_QtBindings.cpp b/generated_cpp_53/PythonQt_QtBindings.cpp new file mode 100644 index 00000000..7ae1630a --- /dev/null +++ b/generated_cpp_53/PythonQt_QtBindings.cpp @@ -0,0 +1,58 @@ + +#include "PythonQt_QtBindings.h" + +#include "PythonQt.h" + +void PythonQt_init_QtGui(PyObject*); +void PythonQt_init_QtSvg(PyObject*); +void PythonQt_init_QtSql(PyObject*); +void PythonQt_init_QtNetwork(PyObject*); +void PythonQt_init_QtCore(PyObject*); +void PythonQt_init_QtWebKit(PyObject*); +void PythonQt_init_QtOpenGL(PyObject*); +void PythonQt_init_QtXml(PyObject*); +void PythonQt_init_QtXmlPatterns(PyObject*); +void PythonQt_init_QtUiTools(PyObject*); + +PYTHONQT_EXPORT void PythonQt_init_QtBindings() + { + #ifdef PYTHONQT_WRAP_Qtcore + PythonQt_init_QtCore(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtgui + PythonQt_init_QtGui(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtnetwork + PythonQt_init_QtNetwork(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtopengl + PythonQt_init_QtOpenGL(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtsql + PythonQt_init_QtSql(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtsvg + PythonQt_init_QtSvg(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtuitools + PythonQt_init_QtUiTools(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtwebkit + PythonQt_init_QtWebKit(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtxml + PythonQt_init_QtXml(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtxmlpatterns + PythonQt_init_QtXmlPatterns(0); + #endif + }; diff --git a/generated_cpp_53/PythonQt_QtBindings.h b/generated_cpp_53/PythonQt_QtBindings.h new file mode 100644 index 00000000..03e96aed --- /dev/null +++ b/generated_cpp_53/PythonQt_QtBindings.h @@ -0,0 +1,10 @@ +#ifndef _PYTHONQT_QTBINDINGS_H +#define _PYTHONQT_QTBINDINGS_H + +#include "PythonQtSystem.h" + +/// Initialize Qt bindings enabled at configuration time +PYTHONQT_EXPORT void PythonQt_init_QtBindings(); + +#endif + diff --git a/generated_cpp_54/PythonQt_QtBindings.cpp b/generated_cpp_54/PythonQt_QtBindings.cpp new file mode 100644 index 00000000..7ae1630a --- /dev/null +++ b/generated_cpp_54/PythonQt_QtBindings.cpp @@ -0,0 +1,58 @@ + +#include "PythonQt_QtBindings.h" + +#include "PythonQt.h" + +void PythonQt_init_QtGui(PyObject*); +void PythonQt_init_QtSvg(PyObject*); +void PythonQt_init_QtSql(PyObject*); +void PythonQt_init_QtNetwork(PyObject*); +void PythonQt_init_QtCore(PyObject*); +void PythonQt_init_QtWebKit(PyObject*); +void PythonQt_init_QtOpenGL(PyObject*); +void PythonQt_init_QtXml(PyObject*); +void PythonQt_init_QtXmlPatterns(PyObject*); +void PythonQt_init_QtUiTools(PyObject*); + +PYTHONQT_EXPORT void PythonQt_init_QtBindings() + { + #ifdef PYTHONQT_WRAP_Qtcore + PythonQt_init_QtCore(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtgui + PythonQt_init_QtGui(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtnetwork + PythonQt_init_QtNetwork(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtopengl + PythonQt_init_QtOpenGL(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtsql + PythonQt_init_QtSql(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtsvg + PythonQt_init_QtSvg(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtuitools + PythonQt_init_QtUiTools(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtwebkit + PythonQt_init_QtWebKit(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtxml + PythonQt_init_QtXml(0); + #endif + + #ifdef PYTHONQT_WRAP_Qtxmlpatterns + PythonQt_init_QtXmlPatterns(0); + #endif + }; diff --git a/generated_cpp_54/PythonQt_QtBindings.h b/generated_cpp_54/PythonQt_QtBindings.h new file mode 100644 index 00000000..03e96aed --- /dev/null +++ b/generated_cpp_54/PythonQt_QtBindings.h @@ -0,0 +1,10 @@ +#ifndef _PYTHONQT_QTBINDINGS_H +#define _PYTHONQT_QTBINDINGS_H + +#include "PythonQtSystem.h" + +/// Initialize Qt bindings enabled at configuration time +PYTHONQT_EXPORT void PythonQt_init_QtBindings(); + +#endif + diff --git a/tests/PythonQtTestMain.cpp b/tests/PythonQtTestMain.cpp index ac3a37d8..8b498ab4 100644 --- a/tests/PythonQtTestMain.cpp +++ b/tests/PythonQtTestMain.cpp @@ -65,6 +65,7 @@ int main(int argc, char *argv[]) Py_Finalize(); } +#ifdef PythonQt_Wrap_Qtcore PythonQtTestCleanup cleanup; failCount += QTest::qExec(&cleanup, argc, argv); @@ -73,6 +74,8 @@ int main(int argc, char *argv[]) } else { std::cout << "All tests passed successfully." << std::endl; } +#endif + return failCount; }