From 3aac13eacf33e3669b84d4afe53b25804f431fbc Mon Sep 17 00:00:00 2001 From: Uwe Date: Wed, 9 Nov 2022 13:23:47 +0100 Subject: [PATCH] Revert "Gui: fix possible crash when running the garbage collector after creating a shiboken wrapper" This reverts commit a06533392b272694c08fc951f7e04b2ff8526e8c. --- src/Gui/PythonWrapper.cpp | 100 -------------------------------------- 1 file changed, 100 deletions(-) diff --git a/src/Gui/PythonWrapper.cpp b/src/Gui/PythonWrapper.cpp index 0e94a76b6a..199f23ace4 100644 --- a/src/Gui/PythonWrapper.cpp +++ b/src/Gui/PythonWrapper.cpp @@ -217,106 +217,6 @@ void registerTypes() // -------------------------------------------------------- namespace Gui { -template -PyTypeObject *getPyTypeObjectForTypeName(); - -/*! - * \brief The WrapperManager class - * This is a helper class that records the Python wrappers of a QObject and invalidates - * them when the QObject is about to be destroyed. - * This is to make sure that if the Python wrapper doesn't own the QObject it won't be notified - * if the QObject is destroyed. - * \code - * ui = Gui.UiLoader() - * lineedit = ui.createWidget("QLineEdit") - * lineedit.deleteLater() - * # Make sure this won't crash - * lineedit.show() - * \endcode - */ -class WrapperManager : public QObject -{ - std::unordered_map> wrappers; - -public: - static WrapperManager& instance() - { - static WrapperManager singleton; - return singleton; - } - /*! - * \brief addQObject - * \param obj - * \param pyobj - * Add the QObject and its Python wrapper to the list. - */ - void addQObject(QObject* obj, PyObject* pyobj) - { - if (wrappers.find(obj) == wrappers.end()) { - QObject::connect(obj, &QObject::destroyed, this, &WrapperManager::destroyed); - } - - auto& pylist = wrappers[obj]; - if (std::find_if(pylist.cbegin(), pylist.cend(), [pyobj](const Py::Object& py) { return py.ptr() == pyobj; }) == pylist.end()) { - pylist.emplace_back(pyobj); - } - } - -private: - /*! - * \brief destroyed - * \param obj - * The listed QObject is about to be destroyed. Invalidate its Python wrappers now. - */ - void destroyed(QObject* obj = nullptr) - { - if (obj) { -#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) - auto key = wrappers.find(obj); - if (key != wrappers.end()) { - Base::PyGILStateLocker lock; - for (const auto& it : key->second) { - auto value = it.ptr(); - Shiboken::Object::setValidCpp(reinterpret_cast(value), false); - } - - wrappers.erase(key); - } -#endif - } - } - void clear() - { - Base::PyGILStateLocker lock; - wrappers.clear(); - } - void wrapQApplication() - { - // We have to explicitly hold a reference to the wrapper of the QApplication - // as otherwise it can happen that when running the gc the program crashes - // The code snippet below caused a crash on older versions: - // mw = Gui.getMainWindow() - // mw.style() - // import gc - // gc.collect() - PyTypeObject * type = getPyTypeObjectForTypeName(); - if (type) { - auto sbk_type = reinterpret_cast(type); - std::string typeName = "QApplication"; - PyObject* pyobj = Shiboken::Object::newObject(sbk_type, qApp, false, false, typeName.c_str()); - addQObject(qApp, pyobj); - } - } - - WrapperManager() - { - connect(QApplication::instance(), &QCoreApplication::aboutToQuit, - this, &WrapperManager::clear); - wrapQApplication(); - } - ~WrapperManager() = default; -}; - template Py::Object qt_wrapInstance(qttype object, const char* className, const char* shiboken, const char* pyside,