diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-11-15 09:37:51 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-11-16 09:58:24 +0000 |
commit | 13d5bffca41178f969f06a0ce892edc8695ad41a (patch) | |
tree | 502ed337e85b751b79fe6fdf2994e162734c87b2 /sources/pyside6/PySide6 | |
parent | b97d977a5def85f262ac6f82c9f246e81816f4e1 (diff) |
Add a QmlSingleton decorator
Add a simple decorator function that stores the type in a list
for the QmlElement decorator to use singleton registration.
Task-number: PYSIDE-1709
Change-Id: I075d583404bd60dc52b84c23a3d09e50d32a5a3a
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
(cherry picked from commit 671f9ed73ee174fe2ba96d7a1c2b267455ef367e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'sources/pyside6/PySide6')
4 files changed, 44 insertions, 9 deletions
diff --git a/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.cpp b/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.cpp index 1dd0507f7..b3d2b31fe 100644 --- a/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.cpp +++ b/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.cpp @@ -370,7 +370,8 @@ static int getGlobalInt(const char *name) enum class RegisterMode { Normal, Anonymous, - Uncreatable + Uncreatable, + Singleton }; static PyObject *qmlElementMacroHelper(PyObject *pyObj, @@ -411,21 +412,36 @@ static PyObject *qmlElementMacroHelper(PyObject *pyObj, if (minorVersion == -1) minorVersion = 0; - if (PySide::qmlRegisterType(pyObj, importName.c_str(), majorVersion, minorVersion, - mode != RegisterMode::Anonymous ? typeName : nullptr, - noCreationReason, - mode == RegisterMode::Normal) == -1) { - PyErr_Format(PyExc_TypeError, "Failed to register type %s.", typeName); + const char *uri = importName.c_str(); + const int result = mode == RegisterMode::Singleton + ? PySide::qmlRegisterSingletonType(pyObj, uri, majorVersion, minorVersion, + typeName, nullptr, + PySide::isQObjectDerived(pyObjType, false), + false) + : PySide::qmlRegisterType(pyObj, uri, majorVersion, minorVersion, + mode != RegisterMode::Anonymous ? typeName : nullptr, + noCreationReason, + mode == RegisterMode::Normal); + + if (result == -1) { + PyErr_Format(PyExc_TypeError, "%s: Failed to register type %s.", + decoratorName, typeName); } return pyObj; } +// FIXME: Store this in PySide::TypeUserData once it is moved to libpyside? +static QList<PyObject *> decoratedSingletons; + PyObject *PySide::qmlElementMacro(PyObject *pyObj) { - auto *noCreationReason = PySide::qmlNoCreationReason(pyObj); - const auto mode = noCreationReason != nullptr - ? RegisterMode::Uncreatable : RegisterMode::Normal; + const char *noCreationReason = nullptr; + RegisterMode mode = RegisterMode::Normal; + if (decoratedSingletons.contains(pyObj)) + mode = RegisterMode::Singleton; + else if ((noCreationReason = PySide::qmlNoCreationReason(pyObj))) + mode = RegisterMode::Uncreatable; return qmlElementMacroHelper(pyObj, "QmlElement", mode, noCreationReason); } @@ -434,3 +450,10 @@ PyObject *PySide::qmlAnonymousMacro(PyObject *pyObj) return qmlElementMacroHelper(pyObj, "QmlAnonymous", RegisterMode::Anonymous); } + +PyObject *PySide::qmlSingletonMacro(PyObject *pyObj) +{ + decoratedSingletons.append(pyObj); + Py_INCREF(pyObj); + return pyObj; +} diff --git a/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.h b/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.h index e8105eb94..643033237 100644 --- a/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.h +++ b/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.h @@ -100,6 +100,10 @@ PyObject *qmlElementMacro(PyObject *pyObj); /// \param pyObj Python type to be registered PyObject *qmlAnonymousMacro(PyObject *pyObj); +/// PySide implementation of the QML_SINGLETON macro +/// \param pyObj Python type to be registered +PyObject *qmlSingletonMacro(PyObject *pyObj); + } // namespace PySide #endif // PYSIDEQMLREGISTERTYPE_H diff --git a/sources/pyside6/PySide6/QtQml/typesystem_qml.xml b/sources/pyside6/PySide6/QtQml/typesystem_qml.xml index 02fcb222f..d1664f1ed 100644 --- a/sources/pyside6/PySide6/QtQml/typesystem_qml.xml +++ b/sources/pyside6/PySide6/QtQml/typesystem_qml.xml @@ -111,6 +111,10 @@ <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlanonymous"/> </add-function> + <add-function signature="QmlSingleton(PyObject*)" return-type="PyObject*"> + <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlsingleton"/> + </add-function> + <function signature="qjsEngine(const QObject*)"> <modify-function> <modify-argument index="return" pyi-type="Optional[PySide6.QtQml.QJSEngine]"/> diff --git a/sources/pyside6/PySide6/glue/qtqml.cpp b/sources/pyside6/PySide6/glue/qtqml.cpp index 2d4a69a0e..27834e2a7 100644 --- a/sources/pyside6/PySide6/glue/qtqml.cpp +++ b/sources/pyside6/PySide6/glue/qtqml.cpp @@ -90,3 +90,7 @@ return %CONVERTTOPYTHON[%RETURN_TYPE](retval); // @snippet qmlanonymous %PYARG_0 = PySide::qmlAnonymousMacro(%ARGUMENT_NAMES); // @snippet qmlanonymous + +// @snippet qmlsingleton +%PYARG_0 = PySide::qmlSingletonMacro(%ARGUMENT_NAMES); +// @snippet qmlsingleton |