From ec93b2aef12d39fdf5363e9d00c8a4393da019a3 Mon Sep 17 00:00:00 2001 From: Ladislav Michl Date: Tue, 23 Jan 2024 12:45:04 +0100 Subject: [PATCH] Gui: PythonWrapper: unify getPyTypeObjectForTypeName --- src/Gui/PythonWrapper.cpp | 169 ++++++++++++++------------------------ 1 file changed, 63 insertions(+), 106 deletions(-) diff --git a/src/Gui/PythonWrapper.cpp b/src/Gui/PythonWrapper.cpp index 0123e339bd..2fc77b08c5 100644 --- a/src/Gui/PythonWrapper.cpp +++ b/src/Gui/PythonWrapper.cpp @@ -276,8 +276,32 @@ void registerTypes() // -------------------------------------------------------- namespace Gui { + +#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) template -PyTypeObject *getPyTypeObjectForTypeName(); +#if defined (HAVE_SHIBOKEN2) +SbkObjectType* +#else +PyTypeObject* +#endif +getPyTypeObjectForTypeName() +{ +#if defined (HAVE_SHIBOKEN_TYPE_FOR_TYPENAME) +# if defined (HAVE_SHIBOKEN2) + auto sbkType = Shiboken::ObjectType::typeForTypeName(typeid(qttype).name()); + if (sbkType) + return reinterpret_cast&(sbkType->type); +# else + return Shiboken::ObjectType::typeForTypeName(typeid(qttype).name()); +# endif +#else +# if defined (HAVE_SHIBOKEN2) + return reinterpret_cast(Shiboken::SbkType()); +# else + return Shiboken::SbkType(); +# endif +#endif +} /*! * \brief The WrapperManager class @@ -324,13 +348,11 @@ public: auto destroyedFun = [pyobj](){ Base::PyGILStateLocker lock; -#if defined (HAVE_SHIBOKEN) auto sbk_ptr = reinterpret_cast (pyobj); if (sbk_ptr != nullptr) Shiboken::Object::setValidCpp(sbk_ptr, false); else Base::Console().DeveloperError("WrapperManager", "A QObject has just been destroyed after its Pythonic wrapper.\n"); -#endif Py_DECREF (pyobj); }; @@ -348,19 +370,11 @@ private: // mw.style() // import gc // gc.collect() -#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) - PyTypeObject * type = getPyTypeObjectForTypeName(); + auto type = getPyTypeObjectForTypeName(); if (type) { -#if defined (HAVE_SHIBOKEN2) - auto sbk_type = reinterpret_cast(type); -#else - auto sbk_type = type; -#endif - std::string typeName = "QApplication"; - PyObject* pyobj = Shiboken::Object::newObject(sbk_type, qApp, false, false, typeName.c_str()); + PyObject* pyobj = Shiboken::Object::newObject(type, qApp, false, false, "QApplication"); addQObject(qApp, pyobj); } -#endif } WrapperManager() @@ -370,6 +384,8 @@ private: ~WrapperManager() override = default; }; +#endif + static std::string formatModuleError(const std::string& name) { std::string error = "Cannot load " + name + " module"; @@ -423,6 +439,18 @@ Py::Object qt_wrapInstance(qttype object, return func.apply(arguments); } +void* qt_getCppPointer(const Py::Object& pyobject, const std::string& unwrap) +{ + // https://github.com/PySide/Shiboken/blob/master/shibokenmodule/typesystem_shiboken.xml + Py::Module mainmod(importShiboken(), true); + Py::Callable func = mainmod.getDict().getItem(unwrap); + + Py::Tuple arguments(1); + arguments[0] = pyobject; //PySide pointer + Py::Tuple result(func.apply(arguments)); + return PyLong_AsVoidPtr(result[0].ptr()); +} + const char* qt_identifyType(QObject* ptr, const std::string& moduleName) { Py::Module qtmod(importPySide(moduleName)); @@ -437,50 +465,19 @@ const char* qt_identifyType(QObject* ptr, const std::string& moduleName) return nullptr; } -void* qt_getCppPointer(const Py::Object& pyobject, const std::string& unwrap) -{ - // https://github.com/PySide/Shiboken/blob/master/shibokenmodule/typesystem_shiboken.xml - Py::Module mainmod(importShiboken(), true); - Py::Callable func = mainmod.getDict().getItem(unwrap); - - Py::Tuple arguments(1); - arguments[0] = pyobject; //PySide pointer - Py::Tuple result(func.apply(arguments)); - return PyLong_AsVoidPtr(result[0].ptr()); -} - - -template -PyTypeObject *getPyTypeObjectForTypeName() -{ -#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) -#if defined (HAVE_SHIBOKEN_TYPE_FOR_TYPENAME) -#if defined (HAVE_SHIBOKEN2) - SbkObjectType* sbkType = Shiboken::ObjectType::typeForTypeName(typeid(qttype).name()); - if (sbkType) - return &(sbkType->type); -#else - return Shiboken::ObjectType::typeForTypeName(typeid(qttype).name()); -#endif -#else - return Shiboken::SbkType(); -#endif -#endif - return nullptr; -} - template qttype* qt_getCppType(PyObject* pyobj) { #if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) - PyTypeObject * type = getPyTypeObjectForTypeName(); + auto type = getPyTypeObjectForTypeName(); if (type) { if (Shiboken::Object::checkType(pyobj)) { - auto sbkobject = reinterpret_cast(pyobj); - void* cppobject = Shiboken::Object::cppPointer(sbkobject, type); - return static_cast(cppobject); + auto skbobj = reinterpret_cast(pyobj); + auto pytypeobj = reinterpret_cast(type); + return static_cast(Shiboken::Object::cppPointer(skbobj, pytypeobj)); } } + return nullptr; #else void* ptr = qt_getCppPointer(Py::asObject(pyobj), "getCppPointer"); if (ptr) @@ -570,22 +567,17 @@ QGraphicsObject* PythonWrapper::toQGraphicsObject(const Py::Object& pyobject) Py::Object PythonWrapper::fromQImage(const QImage& img) { #if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) -#if defined (HAVE_SHIBOKEN2) - PyObject* pyobj = Shiboken::Conversions::copyToPython(reinterpret_cast(getPyTypeObjectForTypeName()), - const_cast(&img)); -#else PyObject* pyobj = Shiboken::Conversions::copyToPython(getPyTypeObjectForTypeName(), const_cast(&img)); -#endif if (pyobj) { return Py::asObject(pyobj); } + + throw Py::RuntimeError("Failed to wrap image"); #else // Access shiboken/PySide via Python - // return qt_wrapInstance(&img, "QImage", "QtGui", "wrapInstance"); #endif - throw Py::RuntimeError("Failed to wrap icon"); } QImage *PythonWrapper::toQImage(PyObject *pyobj) @@ -597,21 +589,16 @@ Py::Object PythonWrapper::fromQIcon(const QIcon* icon) { #if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) const char* typeName = typeid(*const_cast(icon)).name(); -#if defined (HAVE_SHIBOKEN2) - PyObject* pyobj = Shiboken::Object::newObject(reinterpret_cast(getPyTypeObjectForTypeName()), - const_cast(icon), true, false, typeName); -#else PyObject* pyobj = Shiboken::Object::newObject(getPyTypeObjectForTypeName(), const_cast(icon), true, false, typeName); -#endif if (pyobj) return Py::asObject(pyobj); + + throw Py::RuntimeError("Failed to wrap icon"); #else // Access shiboken/PySide via Python - // return qt_wrapInstance(icon, "QIcon", "QtGui", "wrapInstance"); #endif - throw Py::RuntimeError("Failed to wrap icon"); } QIcon *PythonWrapper::toQIcon(PyObject *pyobj) @@ -623,19 +610,14 @@ Py::Object PythonWrapper::fromQDir(const QDir& dir) { #if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) const char* typeName = typeid(dir).name(); -#if defined (HAVE_SHIBOKEN2) - PyObject* pyobj = Shiboken::Object::newObject(reinterpret_cast(getPyTypeObjectForTypeName()), - const_cast(&dir), false, false, typeName); -#else PyObject* pyobj = Shiboken::Object::newObject(getPyTypeObjectForTypeName(), const_cast(&dir), false, false, typeName); -#endif if (pyobj) return Py::asObject(pyobj); #else Q_UNUSED(dir) #endif - throw Py::RuntimeError("Failed to wrap icon"); + throw Py::RuntimeError("Failed to wrap directory"); } QDir* PythonWrapper::toQDir(PyObject* pyobj) @@ -649,25 +631,23 @@ Py::Object PythonWrapper::fromQPrinter(QPrinter* printer) return Py::None(); #if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) // Access shiboken/PySide via C++ - // - PyTypeObject * type = getPyTypeObjectForTypeName(); + auto type = getPyTypeObjectForTypeName(); if (!type) { + // XXX: Why is QPrinter special? +#if defined (HAVE_SHIBOKEN2) + type = reinterpret_cast(Shiboken::Conversions::getPythonTypeObject("QPrinter")); +#else type = Shiboken::Conversions::getPythonTypeObject("QPrinter"); +#endif } if (type) { -#if defined (HAVE_SHIBOKEN2) - auto sbk_type = reinterpret_cast(type); -#else - auto sbk_type = type; -#endif - PyObject* pyobj = Shiboken::Object::newObject(sbk_type, printer, false, false, "QPrinter"); + PyObject* pyobj = Shiboken::Object::newObject(type, printer, false, false, "QPrinter"); return Py::asObject(pyobj); } - throw Py::RuntimeError("Failed to wrap object"); + throw Py::RuntimeError("Failed to wrap printer"); #else // Access shiboken/PySide via Python - // return qt_wrapInstance(printer, "QPrinter", "QtCore", "wrapInstance"); #endif } @@ -678,27 +658,20 @@ Py::Object PythonWrapper::fromQObject(QObject* object, const char* className) return Py::None(); #if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) // Access shiboken/PySide via C++ - // - PyTypeObject * type = getPyTypeObjectForTypeName(); + auto type = getPyTypeObjectForTypeName(); if (type) { -#if defined (HAVE_SHIBOKEN2) - auto sbk_type = reinterpret_cast(type); -#else - auto sbk_type = type; -#endif std::string typeName; if (className) typeName = className; else typeName = object->metaObject()->className(); - PyObject* pyobj = Shiboken::Object::newObject(sbk_type, object, false, false, typeName.c_str()); + PyObject* pyobj = Shiboken::Object::newObject(type, object, false, false, typeName.c_str()); WrapperManager::instance().addQObject(object, pyobj); return Py::asObject(pyobj); } throw Py::RuntimeError("Failed to wrap object"); #else // Access shiboken/PySide via Python - // return qt_wrapInstance(object, className, "QtCore", "wrapInstance"); #endif } @@ -707,28 +680,20 @@ Py::Object PythonWrapper::fromQWidget(QWidget* widget, const char* className) { #if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) // Access shiboken/PySide via C++ - // - PyTypeObject * type = getPyTypeObjectForTypeName(); + auto type = getPyTypeObjectForTypeName(); if (type) { -#if defined (HAVE_SHIBOKEN2) - auto sbk_type = reinterpret_cast(type); -#else - auto sbk_type = type; -#endif std::string typeName; if (className) typeName = className; else typeName = widget->metaObject()->className(); - PyObject* pyobj = Shiboken::Object::newObject(sbk_type, widget, false, false, typeName.c_str()); + PyObject* pyobj = Shiboken::Object::newObject(type, widget, false, false, typeName.c_str()); WrapperManager::instance().addQObject(widget, pyobj); return Py::asObject(pyobj); } throw Py::RuntimeError("Failed to wrap widget"); - #else // Access shiboken/PySide via Python - // return qt_wrapInstance(widget, className, "QtWidgets", "wrapInstance"); #endif } @@ -792,11 +757,7 @@ void PythonWrapper::createChildrenNameAttributes(PyObject* root, QObject* object bool hasAttr = PyObject_HasAttrString(root, name.constData()); if (!hasAttr) { #if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) -#if defined (HAVE_SHIBOKEN2) - Shiboken::AutoDecRef pyChild(Shiboken::Conversions::pointerToPython(reinterpret_cast(getPyTypeObjectForTypeName()), child)); -#else Shiboken::AutoDecRef pyChild(Shiboken::Conversions::pointerToPython(getPyTypeObjectForTypeName(), child)); -#endif PyObject_SetAttrString(root, name.constData(), pyChild); #else const char* className = qt_identifyType(child, "QtWidgets"); @@ -821,11 +782,7 @@ void PythonWrapper::setParent(PyObject* pyWdg, QObject* parent) { #if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) if (parent) { -#if defined (HAVE_SHIBOKEN2) - Shiboken::AutoDecRef pyParent(Shiboken::Conversions::pointerToPython(reinterpret_cast(getPyTypeObjectForTypeName()), parent)); -#else Shiboken::AutoDecRef pyParent(Shiboken::Conversions::pointerToPython(getPyTypeObjectForTypeName(), parent)); -#endif Shiboken::Object::setParent(pyParent, pyWdg); } #else