aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/libpyside/pyside.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/libpyside/pyside.cpp')
-rw-r--r--sources/pyside6/libpyside/pyside.cpp44
1 files changed, 43 insertions, 1 deletions
diff --git a/sources/pyside6/libpyside/pyside.cpp b/sources/pyside6/libpyside/pyside.cpp
index 1a4050bf8..9e12e3cd7 100644
--- a/sources/pyside6/libpyside/pyside.cpp
+++ b/sources/pyside6/libpyside/pyside.cpp
@@ -43,6 +43,7 @@
#include <QtCore/QMutex>
#include <QtCore/QStack>
#include <QtCore/QThread>
+#include <QtCore/private/qobject_p.h>
#include <algorithm>
#include <cstring>
@@ -63,6 +64,20 @@ QT_END_NAMESPACE
Q_LOGGING_CATEGORY(lcPySide, "qt.pyside.libpyside", QtCriticalMsg)
+static QObjectData *qt_object_private(const QObject *o)
+{
+ class FriendlyQObject : public QObject {
+ public:
+ using QObject::d_ptr;
+ };
+ return static_cast<const FriendlyQObject *>(o)->d_ptr.data();
+}
+
+static bool hasDynamicMetaObject(const QObject *o)
+{
+ return qt_object_private(o)->metaObject != nullptr;
+}
+
namespace PySide
{
@@ -675,6 +690,32 @@ static void invalidatePtr(any_t *object)
static const char invalidatePropertyName[] = "_PySideInvalidatePtr";
+// PYSIDE-2749: Skip over internal QML classes and classes
+// with dynamic meta objects when looking for the best matching
+// type to avoid unnessarily triggering the lazy load mechanism
+// for classes that do not have a binding from things like eventFilter().
+static inline bool isInternalObject(const char *name)
+{
+ return std::strstr(name, "QMLTYPE") != nullptr || std::strstr(name, "QQmlPrivate") != nullptr;
+}
+
+static const QMetaObject *metaObjectCandidate(const QObject *o)
+{
+ auto *metaObject = o->metaObject();
+ // Skip QML helper types and Python objects
+ if (hasDynamicMetaObject(o)) {
+ if (auto *super = metaObject->superClass())
+ metaObject = super;
+ }
+ for (auto *candidate = metaObject; candidate != nullptr; candidate = candidate->superClass()) {
+ if (!isInternalObject(candidate->className())) {
+ metaObject = candidate;
+ break;
+ }
+ }
+ return metaObject;
+}
+
// 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.
@@ -682,7 +723,8 @@ static const char *typeName(const QObject *cppSelf)
{
const char *typeName = typeid(*cppSelf).name();
if (!Shiboken::Conversions::getConverter(typeName)) {
- for (auto metaObject = cppSelf->metaObject(); metaObject; metaObject = metaObject->superClass()) {
+ auto *metaObject = metaObjectCandidate(cppSelf);
+ for (; metaObject != nullptr; metaObject = metaObject->superClass()) {
const char *name = metaObject->className();
if (Shiboken::Conversions::getConverter(name)) {
typeName = name;