diff options
| author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-11-15 09:37:51 +0100 |
|---|---|---|
| committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-11-16 09:33:16 +0100 |
| commit | 671f9ed73ee174fe2ba96d7a1c2b267455ef367e (patch) | |
| tree | a0d4bbb196b06decbd274ba412fd241bcf18a97f /sources/pyside6/PySide6 | |
| parent | 74fa311186c9355b43af7c4e6812d14e4fde332c (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
Pick-to: 6.2
Change-Id: I075d583404bd60dc52b84c23a3d09e50d32a5a3a
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
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 15f44c276..30d21d86f 100644 --- a/sources/pyside6/PySide6/QtQml/typesystem_qml.xml +++ b/sources/pyside6/PySide6/QtQml/typesystem_qml.xml @@ -113,6 +113,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 73b44faf2..d32265d2e 100644 --- a/sources/pyside6/PySide6/glue/qtqml.cpp +++ b/sources/pyside6/PySide6/glue/qtqml.cpp @@ -91,3 +91,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 |
