diff options
Diffstat (limited to 'sources/pyside6/libpyside/signalmanager.cpp')
-rw-r--r-- | sources/pyside6/libpyside/signalmanager.cpp | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/sources/pyside6/libpyside/signalmanager.cpp b/sources/pyside6/libpyside/signalmanager.cpp index e5f069c86..305d2f5c3 100644 --- a/sources/pyside6/libpyside/signalmanager.cpp +++ b/sources/pyside6/libpyside/signalmanager.cpp @@ -24,8 +24,10 @@ #include <QtCore/qcoreevent.h> #include <QtCore/qdebug.h> #include <QtCore/qhash.h> +#include <QtCore/qmetatype.h> #include <QtCore/qscopedpointer.h> +#include <climits> #include <memory> #include <utility> @@ -37,6 +39,8 @@ using namespace Qt::StringLiterals; static PyObject *metaObjectAttr = nullptr; +static int pyObjectWrapperMetaTypeId = QMetaType::UnknownType; + static void destroyMetaObject(PyObject *obj) { void *ptr = PyCapsule_GetPointer(obj, nullptr); @@ -168,6 +172,10 @@ PyObjectWrapper::operator PyObject *() const return m_me; } +int PyObjectWrapper::metaTypeId() +{ + return pyObjectWrapperMetaTypeId; +} int PyObjectWrapper::toInt() const { @@ -233,7 +241,29 @@ QDataStream &operator>>(QDataStream &in, PyObjectWrapper &myObj) return in; } -}; +PYSIDE_API QDebug operator<<(QDebug debug, const PyObjectWrapper &myObj) +{ + QDebugStateSaver saver(debug); + debug.noquote(); + debug.nospace(); + // Do not repeat the type name as it is typically called from the QVariant debug + // operator, which outputs the type. + debug << '<'; + if (PyObject *ob = myObj) { + const auto refs = Py_REFCNT(ob); + debug << Py_TYPE(ob)->tp_name << " at " << ob; + if (refs == UINT_MAX) // _Py_IMMORTAL_REFCNT + debug << ", immortal"; + else + debug << ", refs=" << refs; + } else { + debug << '0'; + } + debug << '>'; + return debug; +} + +} // namespace PySide using namespace PySide; @@ -250,19 +280,11 @@ struct SignalManagerPrivate SignalManager::QmlMetaCallErrorHandler SignalManagerPrivate::m_qmlMetaCallErrorHandler = nullptr; -static void PyObject_PythonToCpp_PyObject_PTR(PyObject *pyIn, void *cppOut) -{ - *reinterpret_cast<PyObject **>(cppOut) = pyIn; -} -static PythonToCppFunc is_PyObject_PythonToCpp_PyObject_PTR_Convertible(PyObject * /* pyIn */) -{ - return PyObject_PythonToCpp_PyObject_PTR; -} -static PyObject *PyObject_PTR_CppToPython_PyObject(const void *cppIn) +static PyObject *CopyCppToPythonPyObject(const void *cppIn) { - auto *pyOut = reinterpret_cast<PyObject *>(const_cast<void *>(cppIn)); - if (pyOut) - Py_INCREF(pyOut); + const auto *wrapper = reinterpret_cast<const PyObjectWrapper *>(cppIn); + PyObject *pyOut = *wrapper; + Py_XINCREF(pyOut); return pyOut; } @@ -272,13 +294,16 @@ void SignalManager::init() using namespace Shiboken; // Register PyObject type to use in queued signal and slot connections - qRegisterMetaType<PyObjectWrapper>("PyObject"); + pyObjectWrapperMetaTypeId = qRegisterMetaType<PyObjectWrapper>("PyObject"); // Register QVariant(enum) conversion to QVariant(int) QMetaType::registerConverter<PyObjectWrapper, int>(&PyObjectWrapper::toInt); - SbkConverter *converter = Shiboken::Conversions::createConverter(&PyBaseObject_Type, nullptr); - Shiboken::Conversions::setCppPointerToPythonFunction(converter, PyObject_PTR_CppToPython_PyObject); - Shiboken::Conversions::setPythonToCppPointerFunctions(converter, PyObject_PythonToCpp_PyObject_PTR, is_PyObject_PythonToCpp_PyObject_PTR_Convertible); + // Register a shiboken converter for PyObjectWrapper->Python (value conversion). + // Python->PyObjectWrapper is not registered since the converters do not work for + // non-SbkObject types (falling back to plain pointer pass through). + // This conversion needs to be done manually via QVariant. + SbkConverter *converter = Shiboken::Conversions::createConverter(&PyBaseObject_Type, + CopyCppToPythonPyObject); Shiboken::Conversions::registerConverterName(converter, "PyObject"); Shiboken::Conversions::registerConverterName(converter, "object"); Shiboken::Conversions::registerConverterName(converter, "PyObjectWrapper"); |