diff options
Diffstat (limited to 'sources/pyside6')
3 files changed, 60 insertions, 157 deletions
diff --git a/sources/pyside6/PySide6/QtQuick/pysidequickregistertype.cpp b/sources/pyside6/PySide6/QtQuick/pysidequickregistertype.cpp index edca30620..2f2e5a6a2 100644 --- a/sources/pyside6/PySide6/QtQuick/pysidequickregistertype.cpp +++ b/sources/pyside6/PySide6/QtQuick/pysidequickregistertype.cpp @@ -47,83 +47,31 @@ #include <QtQuick/QQuickPaintedItem> #include <QtQuick/QQuickFramebufferObject> -#include <QtQml/private/qqmlmetatype_p.h> - -#include <QtCore/QMutex> - -static void createQuickItem(void *memory, void *type) -{ - QMutexLocker locker(&PySide::nextQObjectMemoryAddrMutex()); - PySide::setNextQObjectMemoryAddr(memory); - Shiboken::GilState state; - PyObject *obj = PyObject_CallObject(reinterpret_cast<PyObject *>(type), 0); - if (!obj || PyErr_Occurred()) - PyErr_Print(); - PySide::setNextQObjectMemoryAddr(nullptr); -} - -bool pyTypeObjectInheritsFromClass(PyTypeObject *pyObjType, QByteArray className) +bool pyTypeObjectInheritsFromClass(PyTypeObject *pyObjType, const char *classPtrName) { - className.append('*'); - PyTypeObject *classPyType = Shiboken::Conversions::getPythonTypeObject(className.constData()); + PyTypeObject *classPyType = Shiboken::Conversions::getPythonTypeObject(classPtrName); bool isDerived = PySequence_Contains(pyObjType->tp_mro, reinterpret_cast<PyObject *>(classPyType)); return isDerived; } -template <typename T> -struct QPysideQmlMetaTypeInterface : public QQmlMetaTypeInterface -{ - const QMetaObject *metaObject; - - static const QMetaObject *metaObjectFun(const QMetaTypeInterface *mti) - { - return static_cast<const QPysideQmlMetaTypeInterface *>(mti)->metaObject; - } - - QPysideQmlMetaTypeInterface(const QByteArray &name, const QMetaObject *metaObjectIn = nullptr) - : QQmlMetaTypeInterface(name, static_cast<T*>(nullptr)), metaObject(metaObjectIn) { - metaObjectFn = metaObjectFun; - } -}; - template <class WrappedClass> -void registerTypeIfInheritsFromClass( - const QByteArray &className, - PyTypeObject *typeToRegister, - const QByteArray &typePointerName, - const QByteArray &typeListName, - const QMetaObject *typeMetaObject, - QQmlPrivate::RegisterType *type, - bool ®istered) +bool registerTypeIfInheritsFromClass(const char *classPtrName, + PyTypeObject *typeToRegister, + QQmlPrivate::RegisterType *type) { - bool shouldRegister = !registered && pyTypeObjectInheritsFromClass(typeToRegister, className); - if (shouldRegister) { - - QMetaType ptrType(new QPysideQmlMetaTypeInterface<WrappedClass *>(typePointerName, typeMetaObject)); - - QMetaType lstType(new QQmlListMetaTypeInterface(typeListName, static_cast<QQmlListProperty<WrappedClass>*>(nullptr), ptrType.iface())); - - type->typeId = std::move(ptrType); - type->listId = std::move(lstType); - type->attachedPropertiesFunction = QQmlPrivate::attachedPropertiesFunc<WrappedClass>(); - type->attachedPropertiesMetaObject = - QQmlPrivate::attachedPropertiesMetaObject<WrappedClass>(); - type->parserStatusCast = - QQmlPrivate::StaticCastSelector<WrappedClass, QQmlParserStatus>::cast(); - type->valueSourceCast = - QQmlPrivate::StaticCastSelector<WrappedClass, QQmlPropertyValueSource>::cast(); - type->valueInterceptorCast = - QQmlPrivate::StaticCastSelector<WrappedClass, QQmlPropertyValueInterceptor>::cast(); - // Pass the size of the generated wrapper class (larger than the plain - // Qt class due to virtual method cache) since that is what is instantiated. - type->objectSize = int(PySide::getSizeOfQObject(typeToRegister)); - registered = true; - } + if (!pyTypeObjectInheritsFromClass(typeToRegister, classPtrName)) + return false; + type->parserStatusCast = + QQmlPrivate::StaticCastSelector<WrappedClass, QQmlParserStatus>::cast(); + type->valueSourceCast = + QQmlPrivate::StaticCastSelector<WrappedClass, QQmlPropertyValueSource>::cast(); + type->valueInterceptorCast = + QQmlPrivate::StaticCastSelector<WrappedClass, QQmlPropertyValueInterceptor>::cast(); + return true; } -bool quickRegisterType(PyObject *pyObj, const char *uri, int versionMajor, int versionMinor, - const char *qmlName, bool creatable, const char *noCreationReason, QQmlPrivate::RegisterType *type) +bool quickRegisterType(PyObject *pyObj, QQmlPrivate::RegisterType *type) { using namespace Shiboken; @@ -137,50 +85,12 @@ bool quickRegisterType(PyObject *pyObj, const char *uri, int versionMajor, int v if (!isQuickItem) return false; - // Used inside macros to register the type. - const QMetaObject *metaObject = PySide::retrieveMetaObject(pyObj); - Q_ASSERT(metaObject); - - - // Incref the type object, don't worry about decref'ing it because - // there's no way to unregister a QML type. - Py_INCREF(pyObj); - - // Used in macro registration. - QByteArray pointerName(qmlName); - pointerName.append('*'); - QByteArray listName(qmlName); - listName.prepend("QQmlListProperty<"); - listName.append('>'); - - bool registered = false; - // Pass the size of the generated wrapper class since that is what is instantiated. - registerTypeIfInheritsFromClass<QQuickPaintedItem>( - "QQuickPaintedItem", pyObjType, pointerName, listName, - metaObject, type, registered); - registerTypeIfInheritsFromClass<QQuickFramebufferObject>( - "QQuickFramebufferObject", pyObjType, pointerName, listName, - metaObject, type, registered); - registerTypeIfInheritsFromClass<QQuickItem>( - "QQuickItem", pyObjType, pointerName, listName, - metaObject, type, registered); - if (!registered) - return false; - - type->structVersion = 0; - type->create = creatable ? createQuickItem : nullptr; - type->noCreationReason = noCreationReason; - type->userdata = pyObj; - type->uri = uri; - type->version = QTypeRevision::fromVersion(versionMajor, versionMinor); - type->elementName = qmlName; - type->metaObject = metaObject; - - type->extensionObjectCreate = 0; - type->extensionMetaObject = 0; - type->customParser = 0; - - return true; + return registerTypeIfInheritsFromClass<QQuickPaintedItem>("QQuickPaintedItem*", + pyObjType, type) + || registerTypeIfInheritsFromClass<QQuickFramebufferObject>("QQuickFramebufferObject*", + pyObjType, type) + || registerTypeIfInheritsFromClass<QQuickItem>("QQuickItem*", + pyObjType, type); } void PySide::initQuickSupport(PyObject *module) diff --git a/sources/pyside6/libpysideqml/pysideqmlregistertype.cpp b/sources/pyside6/libpysideqml/pysideqmlregistertype.cpp index 05a7bbffb..94b4897e1 100644 --- a/sources/pyside6/libpysideqml/pysideqmlregistertype.cpp +++ b/sources/pyside6/libpysideqml/pysideqmlregistertype.cpp @@ -132,35 +132,30 @@ int qmlRegisterType(PyObject *pyObj, const char *uri, int versionMajor, QQmlPrivate::RegisterType type; // Allow registering Qt Quick items. - bool registered = false; - if (quickRegisterItemFunction) { - registered = - quickRegisterItemFunction(pyObj, uri, versionMajor, versionMinor, - qmlName, creatable, noCreationReason, &type); - } + const bool isQuickType = quickRegisterItemFunction && quickRegisterItemFunction(pyObj, &type); // Register as simple QObject rather than Qt Quick item. - if (!registered) { - using QObjectQmlList = QQmlListProperty<QObject>; - // Incref the type object, don't worry about decref'ing it because - // there's no way to unregister a QML type. - Py_INCREF(pyObj); - - type.structVersion = 0; - - const QByteArray typeName(pyObjType->tp_name); - QByteArray ptrType = typeName + '*'; - QByteArray listType = QByteArrayLiteral("QQmlListProperty<") + typeName + '>'; - - type.typeId = QMetaType(new QQmlMetaTypeInterface(ptrType, static_cast<QObject **>(nullptr))); - type.listId = QMetaType(new QQmlListMetaTypeInterface(listType, - static_cast<QObjectQmlList*>(nullptr), - type.typeId.iface())); - const auto typeInfo = qmlTypeInfo(pyObj); - auto info = qmlAttachedInfo(pyObjType, typeInfo); - type.attachedPropertiesFunction = info.factory; - type.attachedPropertiesMetaObject = info.metaObject; + using QObjectQmlList = QQmlListProperty<QObject>; + // Incref the type object, don't worry about decref'ing it because + // there's no way to unregister a QML type. + Py_INCREF(pyObj); + + type.structVersion = 0; + + const QByteArray typeName(pyObjType->tp_name); + QByteArray ptrType = typeName + '*'; + QByteArray listType = QByteArrayLiteral("QQmlListProperty<") + typeName + '>'; + + type.typeId = QMetaType(new QQmlMetaTypeInterface(ptrType, static_cast<QObject **>(nullptr))); + type.listId = QMetaType(new QQmlListMetaTypeInterface(listType, + static_cast<QObjectQmlList*>(nullptr), + type.typeId.iface())); + const auto typeInfo = qmlTypeInfo(pyObj); + auto info = qmlAttachedInfo(pyObjType, typeInfo); + type.attachedPropertiesFunction = info.factory; + type.attachedPropertiesMetaObject = info.metaObject; + if (!isQuickType) { // values filled by the Quick registration type.parserStatusCast = QQmlPrivate::StaticCastSelector<QObject, QQmlParserStatus>::cast(); // QPyQmlPropertyValueSource inherits QObject, QmlPropertyValueSource, so, @@ -172,22 +167,22 @@ int qmlRegisterType(PyObject *pyObj, const char *uri, int versionMajor, : QQmlPrivate::StaticCastSelector<QObject, QQmlPropertyValueSource>::cast(); type.valueInterceptorCast = QQmlPrivate::StaticCastSelector<QObject, QQmlPropertyValueInterceptor>::cast(); - - int objectSize = static_cast<int>(PySide::getSizeOfQObject( - reinterpret_cast<PyTypeObject *>(pyObj))); - type.objectSize = objectSize; - type.create = creatable ? createInto : nullptr; - type.noCreationReason = QString::fromUtf8(noCreationReason); - type.userdata = pyObj; - type.uri = uri; - type.version = QTypeRevision::fromVersion(versionMajor, versionMinor); - type.elementName = qmlName; - - info = qmlExtendedInfo(pyObj, typeInfo); - type.extensionObjectCreate = info.factory; - type.extensionMetaObject = info.metaObject; - type.customParser = 0; } + + int objectSize = static_cast<int>(PySide::getSizeOfQObject( + reinterpret_cast<PyTypeObject *>(pyObj))); + type.objectSize = objectSize; + type.create = creatable ? createInto : nullptr; + type.noCreationReason = QString::fromUtf8(noCreationReason); + type.userdata = pyObj; + type.uri = uri; + type.version = QTypeRevision::fromVersion(versionMajor, versionMinor); + type.elementName = qmlName; + + info = qmlExtendedInfo(pyObj, typeInfo); + type.extensionObjectCreate = info.factory; + type.extensionMetaObject = info.metaObject; + type.customParser = 0; type.metaObject = metaObject; // Snapshot may have changed. int qmlTypeId = QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); diff --git a/sources/pyside6/libpysideqml/pysideqmlregistertype.h b/sources/pyside6/libpysideqml/pysideqmlregistertype.h index d77a67bdb..e3da4ac31 100644 --- a/sources/pyside6/libpysideqml/pysideqmlregistertype.h +++ b/sources/pyside6/libpysideqml/pysideqmlregistertype.h @@ -113,12 +113,10 @@ PYSIDEQML_API PyObject *qmlAnonymousMacro(PyObject *pyObj); PYSIDEQML_API PyObject *qmlSingletonMacro(PyObject *pyObj); -// Used by QtQuick module to notify QtQml that custom QtQuick items can be registered. +// Used by QtQuick module to fill the QQmlPrivate::RegisterType::parserStatusCast, +// valueSourceCast and valueInterceptorCast fields with the correct values. using QuickRegisterItemFunction = - bool (*)(PyObject *pyObj, const char *uri, int versionMajor, - int versionMinor, const char *qmlName, - bool creatable, const char *noCreationReason, - QQmlPrivate::RegisterType *); + bool (*)(PyObject *pyObj, QQmlPrivate::RegisterType *); PYSIDEQML_API QuickRegisterItemFunction getQuickRegisterItemFunction(); PYSIDEQML_API void setQuickRegisterItemFunction(QuickRegisterItemFunction function); |
