diff options
Diffstat (limited to 'sources/pyside2/libpyside/pyside.cpp')
-rw-r--r-- | sources/pyside2/libpyside/pyside.cpp | 113 |
1 files changed, 72 insertions, 41 deletions
diff --git a/sources/pyside2/libpyside/pyside.cpp b/sources/pyside2/libpyside/pyside.cpp index 2419b2e16..5d0859adc 100644 --- a/sources/pyside2/libpyside/pyside.cpp +++ b/sources/pyside2/libpyside/pyside.cpp @@ -50,7 +50,6 @@ #include "pysidemetafunction_p.h" #include "pysidemetafunction.h" #include "dynamicqmetaobject.h" -#include "destroylistener.h" #include <autodecref.h> #include <basewrapper.h> @@ -59,7 +58,6 @@ #include <sbkconverter.h> #include <sbkstring.h> #include <sbkstaticstrings.h> -#include <qapp_macro.h> #include <QtCore/QByteArray> #include <QtCore/QCoreApplication> @@ -94,6 +92,7 @@ void init(PyObject *module) MetaFunction::init(module); // Init signal manager, so it will register some meta types used by QVariant. SignalManager::instance(); + initQApp(); } static bool _setProperty(PyObject *qObj, PyObject *name, PyObject *value, bool *accept) @@ -121,38 +120,36 @@ static bool _setProperty(PyObject *qObj, PyObject *name, PyObject *value, bool * return true; } -bool fillQtProperties(PyObject *qObj, const QMetaObject *metaObj, PyObject *kwds, const char **blackList, unsigned int blackListSize) +bool fillQtProperties(PyObject *qObj, const QMetaObject *metaObj, PyObject *kwds) { PyObject *key, *value; Py_ssize_t pos = 0; while (PyDict_Next(kwds, &pos, &key, &value)) { - if (!blackListSize || !std::binary_search(blackList, blackList + blackListSize, std::string(Shiboken::String::toCString(key)))) { - QByteArray propName(Shiboken::String::toCString(key)); - bool accept = false; - if (metaObj->indexOfProperty(propName) != -1) { - if (!_setProperty(qObj, key, value, &accept)) - return false; - } else { - propName.append("()"); - if (metaObj->indexOfSignal(propName) != -1) { - accept = true; - propName.prepend('2'); - if (!PySide::Signal::connect(qObj, propName, value)) - return false; - } - } - if (!accept) { - // PYSIDE-1019: Allow any existing attribute in the constructor. - if (!_setProperty(qObj, key, value, &accept)) + QByteArray propName(Shiboken::String::toCString(key)); + bool accept = false; + if (metaObj->indexOfProperty(propName) != -1) { + if (!_setProperty(qObj, key, value, &accept)) + return false; + } else { + propName.append("()"); + if (metaObj->indexOfSignal(propName) != -1) { + accept = true; + propName.prepend('2'); + if (!PySide::Signal::connect(qObj, propName, value)) return false; } - if (!accept) { - PyErr_Format(PyExc_AttributeError, "'%s' is not a Qt property or a signal", - propName.constData()); + } + if (!accept) { + // PYSIDE-1019: Allow any existing attribute in the constructor. + if (!_setProperty(qObj, key, value, &accept)) return false; - } + } + if (!accept) { + PyErr_Format(PyExc_AttributeError, "'%s' is not a Qt property or a signal", + propName.constData()); + return false; } } return true; @@ -165,12 +162,10 @@ void registerCleanupFunction(CleanupFunction func) void runCleanupFunctions() { - //PySide::DestroyListener::instance()->destroy(); while (!cleanupFunctionList.isEmpty()) { CleanupFunction f = cleanupFunctionList.pop(); f(); } - PySide::DestroyListener::destroy(); } static void destructionVisitor(SbkObject *pyObj, void *data) @@ -214,7 +209,7 @@ void destroyQCoreApplication() delete app; Py_END_ALLOW_THREADS // PYSIDE-571: make sure to create a singleton deleted qApp. - MakeSingletonQAppWrapper(NULL); + Py_DECREF(MakeQAppWrapper(nullptr)); } std::size_t getSizeOfQObject(SbkObjectType *type) @@ -225,8 +220,7 @@ std::size_t getSizeOfQObject(SbkObjectType *type) void initDynamicMetaObject(SbkObjectType *type, const QMetaObject *base, std::size_t cppObjSize) { //create DynamicMetaObject based on python type - auto userData = - new TypeUserData(reinterpret_cast<PyTypeObject *>(type), base, cppObjSize); + auto userData = new TypeUserData(reinterpret_cast<PyTypeObject *>(type), base, cppObjSize); userData->mo.update(); Shiboken::ObjectType::setTypeUserData(type, userData, Shiboken::callCppDestructor<TypeUserData>); @@ -270,11 +264,6 @@ const QMetaObject *retrieveMetaObject(PyObject *pyObj) return retrieveMetaObject(pyTypeObj); } -void initDynamicMetaObject(SbkObjectType *type, const QMetaObject *base) -{ - initDynamicMetaObject(type, base, 0); -} - void initQObjectSubType(SbkObjectType *type, PyObject *args, PyObject * /* kwds */) { PyTypeObject *qObjType = Shiboken::Conversions::getPythonTypeObject("QObject*"); @@ -299,6 +288,26 @@ void initQObjectSubType(SbkObjectType *type, PyObject *args, PyObject * /* kwds initDynamicMetaObject(type, userData->mo.update(), userData->cppObjSize); } +void initQApp() +{ + /* + * qApp will not be initialized when embedding is active. + * That means that qApp exists already when PySide is initialized. + * We could solve that by creating a qApp variable, but in embedded + * mode, we also have the effect that the first assignment to qApp + * is persistent! Therefore, we can never be sure to have created + * qApp late enough to get the right type for the instance. + * + * I would appreciate very much if someone could explain or even fix + * this issue. It exists only when a pre-existing application exists. + */ + if (!qApp) + Py_DECREF(MakeQAppWrapper(nullptr)); + + // PYSIDE-1470: Register a function to destroy an application from shiboken. + setDestroyQApplication(destroyQCoreApplication); +} + PyObject *getMetaDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *name) { PyObject *attr = PyObject_GenericGetAttr(self, name); @@ -310,7 +319,6 @@ PyObject *getMetaDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *nam Py_DECREF(attr); if (!value) return 0; - Py_INCREF(value); attr = value; } @@ -401,6 +409,24 @@ static void invalidatePtr(any_t *object) static const char invalidatePropertyName[] = "_PySideInvalidatePtr"; +// PYSIDE-1214, when creating new wrappers for classes inheriting QObject but +// not exposed to Python, try to find the best-matching (most-derived) Qt +// class by walking up the meta objects. +static const char *typeName(QObject *cppSelf) +{ + const char *typeName = typeid(*cppSelf).name(); + if (!Shiboken::Conversions::getConverter(typeName)) { + for (auto metaObject = cppSelf->metaObject(); metaObject; metaObject = metaObject->superClass()) { + const char *name = metaObject->className(); + if (Shiboken::Conversions::getConverter(name)) { + typeName = name; + break; + } + } + } + return typeName; +} + PyObject *getWrapperForQObject(QObject *cppSelf, SbkObjectType *sbk_type) { PyObject *pyOut = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper(cppSelf)); @@ -423,8 +449,7 @@ PyObject *getWrapperForQObject(QObject *cppSelf, SbkObjectType *sbk_type) } } - const char *typeName = typeid(*cppSelf).name(); - pyOut = Shiboken::Object::newObject(sbk_type, cppSelf, false, false, typeName); + pyOut = Shiboken::Object::newObject(sbk_type, cppSelf, false, false, typeName(cppSelf)); return pyOut; } @@ -561,16 +586,22 @@ bool registerInternalQtConf() #ifdef PYSIDE_QT_CONF_PREFIX setupPrefix = QStringLiteral(PYSIDE_QT_CONF_PREFIX); #endif - QString prefixPath = pysideDir.absoluteFilePath(setupPrefix); + const QString prefixPathStr = pysideDir.absoluteFilePath(setupPrefix); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + const QByteArray prefixPath = prefixPathStr.toLocal8Bit(); +#else + // PYSIDE-972, QSettings used by QtCore uses Latin1 + const QByteArray prefixPath = prefixPathStr.toLatin1(); +#endif // rccData needs to be static, otherwise when it goes out of scope, the Qt resource system // will point to invalid memory. - static QByteArray rccData = QByteArray("[Paths]\nPrefix = ") + prefixPath.toLocal8Bit() + static QByteArray rccData = QByteArrayLiteral("[Paths]\nPrefix = ") + prefixPath #ifdef Q_OS_WIN // LibraryExecutables needs to point to Prefix instead of ./bin because we don't // currently conform to the Qt default directory layout on Windows. This is necessary // for QtWebEngineCore to find the location of QtWebEngineProcess.exe. - + QByteArray("\nLibraryExecutables = ") + prefixPath.toLocal8Bit() + + QByteArray("\nLibraryExecutables = ") + prefixPath #endif ; rccData.append('\n'); |