diff --git a/CMakeLists.txt b/CMakeLists.txt index 90c2f634d..361371f5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -369,7 +369,11 @@ if(FREECAD_LIBPACK_USE) # -------------------------------- Shiboken/PySide ------------------------ - find_package(PySideTools REQUIRED) # Pyside utilities (pyside-uic & pyside-rcc) + if(BUILD_QT5) + find_package(PySide2Tools REQUIRED) # PySide2 utilities (pyside2-uic & pyside2-rcc) + else() + find_package(PySideTools REQUIRED) # Pyside utilities (pyside-uic & pyside-rcc) + endif() # -------------------------------- Salome SMESH -------------------------- @@ -828,6 +832,32 @@ endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # -------------------------------- Shiboken/PySide ------------------------ + if(BUILD_QT5) + # set(PYTHON_SUFFIX -python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}) + SET(PYTHON_SUFFIX -python2.7) # for shiboken + SET(PYTHON_BASENAME -python2.7) # for PySide + + if(DEFINED MACPORTS_PREFIX) + find_package(Shiboken REQUIRED HINTS "${PYTHON_LIBRARY_DIR}/cmake") + find_package(PySide REQUIRED HINTS "${PYTHON_LIBRARY_DIR}/cmake") + endif(DEFINED MACPORTS_PREFIX) + + find_package(Shiboken2)# REQUIRED + if(NOT SHIBOKEN_INCLUDE_DIR) + MESSAGE(FATAL_ERROR "====================\n" + "shiboken2 not found.\n" + "====================\n") + endif(NOT SHIBOKEN_INCLUDE_DIR) + + find_package(PySide2)# REQUIRED + if(NOT PYSIDE_INCLUDE_DIR) + MESSAGE(FATAL_ERROR "==================\n" + "PySide2 not found.\n" + "==================\n") + endif(NOT PYSIDE_INCLUDE_DIR) + + find_package(PySideTools REQUIRED) # PySide2 utilities (pyside-uic & pyside-rcc) + else() # set(PYTHON_SUFFIX -python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}) SET(PYTHON_SUFFIX -python2.7) # for shiboken SET(PYTHON_BASENAME -python2.7) # for PySide @@ -852,6 +882,7 @@ endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") endif(NOT PYSIDE_INCLUDE_DIR) find_package(PySideTools REQUIRED) # PySide utilities (pyside-uic & pyside-rcc) + endif() # ------------------------------ Matplotlib ------------------------------ diff --git a/src/Gui/ApplicationPy.cpp b/src/Gui/ApplicationPy.cpp index 14b90174c..e5a284da6 100644 --- a/src/Gui/ApplicationPy.cpp +++ b/src/Gui/ApplicationPy.cpp @@ -579,6 +579,7 @@ PyObject* Application::sGetMainWindow(PyObject * /*self*/, PyObject *args,PyObje PythonWrapper wrap; wrap.loadCoreModule(); wrap.loadGuiModule(); + wrap.loadWidgetsModule(); try { return Py::new_reference_to(wrap.fromQWidget(Gui::getMainWindow(), "QMainWindow")); } diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index d946c3ac5..56cf2a44a 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -116,6 +116,7 @@ ENDIF(OCULUS_FOUND) if(SHIBOKEN_INCLUDE_DIR) if (BUILD_QT5) + add_definitions(-DHAVE_SHIBOKEN2) else() add_definitions(-DHAVE_SHIBOKEN) endif() @@ -128,10 +129,6 @@ if(SHIBOKEN_INCLUDE_DIR) endif(SHIBOKEN_INCLUDE_DIR) if(PYSIDE_INCLUDE_DIR) - if (BUILD_QT5) - else() - add_definitions(-DHAVE_PYSIDE) - endif() include_directories( ${PYSIDE_INCLUDE_DIR} ${PYSIDE_INCLUDE_DIR}/QtCore @@ -140,6 +137,14 @@ if(PYSIDE_INCLUDE_DIR) list(APPEND FreeCADGui_LIBS ${PYSIDE_LIBRARY} ) + if (BUILD_QT5) + include_directories( + ${PYSIDE_INCLUDE_DIR}/QtWidgets + ) + add_definitions(-DHAVE_PYSIDE2) + else() + add_definitions(-DHAVE_PYSIDE) + endif() endif(PYSIDE_INCLUDE_DIR) generate_from_xml(DocumentPy) diff --git a/src/Gui/ViewProviderPyImp.cpp b/src/Gui/ViewProviderPyImp.cpp index 5c2522465..a241f7e35 100644 --- a/src/Gui/ViewProviderPyImp.cpp +++ b/src/Gui/ViewProviderPyImp.cpp @@ -356,6 +356,7 @@ Py::Object ViewProviderPy::getIcon(void) const #else PythonWrapper wrap; wrap.loadGuiModule(); + wrap.loadWidgetsModule(); QIcon icon = getViewProviderPtr()->getIcon(); return wrap.fromQIcon(new QIcon(icon)); #endif diff --git a/src/Gui/ViewProviderPythonFeature.cpp b/src/Gui/ViewProviderPythonFeature.cpp index eede9551b..2c1229a2a 100644 --- a/src/Gui/ViewProviderPythonFeature.cpp +++ b/src/Gui/ViewProviderPythonFeature.cpp @@ -527,6 +527,7 @@ void ViewProviderPythonFeatureImp::setupContextMenu(QMenu* menu) if (vp.hasAttr("__object__")) { PythonWrapper wrap; wrap.loadGuiModule(); + wrap.loadWidgetsModule(); Py::Callable method(vp.getAttr(std::string("setupContextMenu"))); Py::Tuple args(1); args.setItem(0, wrap.fromQWidget(menu, "QMenu")); @@ -535,6 +536,7 @@ void ViewProviderPythonFeatureImp::setupContextMenu(QMenu* menu) else { PythonWrapper wrap; wrap.loadGuiModule(); + wrap.loadWidgetsModule(); Py::Callable method(vp.getAttr(std::string("setupContextMenu"))); Py::Tuple args(2); args.setItem(0, Py::Object(object->getPyObject(), true)); diff --git a/src/Gui/WidgetFactory.cpp b/src/Gui/WidgetFactory.cpp index af089fc56..da1c51141 100644 --- a/src/Gui/WidgetFactory.cpp +++ b/src/Gui/WidgetFactory.cpp @@ -61,6 +61,26 @@ PyTypeObject** SbkPySide_QtGuiTypes=NULL; # endif #endif +#ifdef HAVE_SHIBOKEN2 +# define HAVE_SHIBOKEN +# undef _POSIX_C_SOURCE +# undef _XOPEN_SOURCE +# include +# include +# include +# include +# include +# ifdef HAVE_PYSIDE2 +# define HAVE_PYSIDE +# include +# include +# include +PyTypeObject** SbkPySide2_QtCoreTypes=NULL; +PyTypeObject** SbkPySide2_QtGuiTypes=NULL; +PyTypeObject** SbkPySide2_QtWidgetsTypes=NULL; +# endif +#endif + #ifdef __GNUC__ # pragma GCC diagnostic pop #endif @@ -255,7 +275,15 @@ Py::Object PythonWrapper::fromQWidget(QWidget* widget, const char* className) bool PythonWrapper::loadCoreModule() { -#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) +#if defined (HAVE_SHIBOKEN2) && (HAVE_PYSIDE2) + // QtCore + if (!SbkPySide2_QtCoreTypes) { + Shiboken::AutoDecRef requiredModule(Shiboken::Module::import("PySide2.QtCore")); + if (requiredModule.isNull()) + return false; + SbkPySide2_QtCoreTypes = Shiboken::Module::getTypes(requiredModule); + } +#elif defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) // QtCore if (!SbkPySide_QtCoreTypes) { Shiboken::AutoDecRef requiredModule(Shiboken::Module::import("PySide.QtCore")); @@ -269,7 +297,15 @@ bool PythonWrapper::loadCoreModule() bool PythonWrapper::loadGuiModule() { -#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) +#if defined (HAVE_SHIBOKEN2) && defined(HAVE_PYSIDE2) + // QtGui + if (!SbkPySide2_QtGuiTypes) { + Shiboken::AutoDecRef requiredModule(Shiboken::Module::import("PySide2.QtGui")); + if (requiredModule.isNull()) + return false; + SbkPySide2_QtGuiTypes = Shiboken::Module::getTypes(requiredModule); + } +#elif defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) // QtGui if (!SbkPySide_QtGuiTypes) { Shiboken::AutoDecRef requiredModule(Shiboken::Module::import("PySide.QtGui")); @@ -281,6 +317,20 @@ bool PythonWrapper::loadGuiModule() return true; } +bool PythonWrapper::loadWidgetsModule() +{ +#if defined (HAVE_SHIBOKEN2) && defined(HAVE_PYSIDE2) + // QtWidgets + if (!SbkPySide2_QtWidgetsTypes) { + Shiboken::AutoDecRef requiredModule(Shiboken::Module::import("PySide2.QtWidgets")); + if (requiredModule.isNull()) + return false; + SbkPySide2_QtWidgetsTypes = Shiboken::Module::getTypes(requiredModule); + } +#endif + return true; +} + void PythonWrapper::createChildrenNameAttributes(PyObject* root, QObject* object) { #if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) @@ -290,7 +340,11 @@ void PythonWrapper::createChildrenNameAttributes(PyObject* root, QObject* object if (!name.isEmpty() && !name.startsWith("_") && !name.startsWith("qt_")) { bool hasAttr = PyObject_HasAttrString(root, name.constData()); if (!hasAttr) { +#if defined (HAVE_SHIBOKEN2) && defined(HAVE_PYSIDE2) + Shiboken::AutoDecRef pyChild(Shiboken::Conversions::pointerToPython((SbkObjectType*)SbkPySide2_QtCoreTypes[SBK_QOBJECT_IDX], child)); +#else Shiboken::AutoDecRef pyChild(Shiboken::Conversions::pointerToPython((SbkObjectType*)SbkPySide_QtCoreTypes[SBK_QOBJECT_IDX], child)); +#endif PyObject_SetAttrString(root, name.constData(), pyChild); } createChildrenNameAttributes(root, child); @@ -307,7 +361,11 @@ void PythonWrapper::setParent(PyObject* pyWdg, QObject* parent) { #if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) if (parent) { +#if defined (HAVE_SHIBOKEN2) && defined(HAVE_PYSIDE2) + Shiboken::AutoDecRef pyParent(Shiboken::Conversions::pointerToPython((SbkObjectType*)SbkPySide2_QtGuiTypes[SBK_QWIDGET_IDX], parent)); +#else Shiboken::AutoDecRef pyParent(Shiboken::Conversions::pointerToPython((SbkObjectType*)SbkPySide_QtGuiTypes[SBK_QWIDGET_IDX], parent)); +#endif Shiboken::Object::setParent(pyParent, pyWdg); } #else @@ -675,6 +733,7 @@ Py::Object UiLoaderPy::load(const Py::Tuple& args) QWidget* widget = loader.load(device, parent); if (widget) { wrap.loadGuiModule(); + wrap.loadWidgetsModule(); Py::Object pyWdg = wrap.fromQWidget(widget); wrap.createChildrenNameAttributes(*pyWdg, widget); @@ -731,6 +790,7 @@ Py::Object UiLoaderPy::createWidget(const Py::Tuple& args) throw Py::RuntimeError(err); } wrap.loadGuiModule(); + wrap.loadWidgetsModule(); return wrap.fromQWidget(widget); } diff --git a/src/Gui/WidgetFactory.h b/src/Gui/WidgetFactory.h index 74fc4e339..185efe9e9 100644 --- a/src/Gui/WidgetFactory.h +++ b/src/Gui/WidgetFactory.h @@ -45,6 +45,7 @@ public: PythonWrapper(); bool loadCoreModule(); bool loadGuiModule(); + bool loadWidgetsModule(); bool toCString(const Py::Object&, std::string&); QObject* toQObject(const Py::Object&);