aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside2/libpyside/pyside.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside2/libpyside/pyside.cpp')
-rw-r--r--sources/pyside2/libpyside/pyside.cpp113
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');