diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-11-08 15:48:33 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-11-10 19:58:33 +0100 |
commit | 4f57d4eb32df52838129547be60b1a75d3f3356c (patch) | |
tree | 19f625c23ebd5ecdbe6cd9f30e71832f0df15d4a | |
parent | 5b9320df2284b96dba4d5eec1857a797797187e6 (diff) |
PySide6: Add a QmlAnonymous decorator
Split out a helper from the qmlElementMacro() to register (also
preparing for uncreatable types) and add the decorator.
Pick-to: 6.2
Change-Id: I0f3ebf6f31c141083440abcc9f1acd227ce046d7
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
-rw-r--r-- | sources/pyside6/PySide6/QtQml/pysideqmlregistertype.cpp | 39 | ||||
-rw-r--r-- | sources/pyside6/PySide6/QtQml/pysideqmlregistertype.h | 5 | ||||
-rw-r--r-- | sources/pyside6/PySide6/QtQml/typesystem_qml.xml | 4 | ||||
-rw-r--r-- | sources/pyside6/PySide6/glue/qtqml.cpp | 4 | ||||
-rw-r--r-- | sources/pyside6/doc/extras/QtQml.QmlAnonymous.rst | 22 |
5 files changed, 68 insertions, 6 deletions
diff --git a/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.cpp b/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.cpp index 76ea97979..b9f66f98b 100644 --- a/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.cpp +++ b/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.cpp @@ -364,7 +364,16 @@ static int getGlobalInt(const char *name) return value; } -PyObject *PySide::qmlElementMacro(PyObject *pyObj) +enum class RegisterMode { + Normal, + Anonymous, + Uncreatable +}; + +static PyObject *qmlElementMacroHelper(PyObject *pyObj, + const char *decoratorName, + RegisterMode mode = RegisterMode::Normal, + const char *noCreationReason = nullptr) { if (!PyType_Check(pyObj)) { PyErr_Format(PyExc_TypeError, "This decorator can only be used on classes."); @@ -372,8 +381,10 @@ PyObject *PySide::qmlElementMacro(PyObject *pyObj) } PyTypeObject *pyObjType = reinterpret_cast<PyTypeObject *>(pyObj); + const char *typeName = pyObjType->tp_name; if (!PySequence_Contains(pyObjType->tp_mro, reinterpret_cast<PyObject *>(qObjectType()))) { - PyErr_Format(PyExc_TypeError, "This decorator can only be used with classes inherited from QObject, got %s.", pyObjType->tp_name); + PyErr_Format(PyExc_TypeError, "This decorator can only be used with classes inherited from QObject, got %s.", + typeName); return nullptr; } @@ -382,12 +393,14 @@ PyObject *PySide::qmlElementMacro(PyObject *pyObj) int minorVersion = getGlobalInt("QML_IMPORT_MINOR_VERSION"); if (importName.empty()) { - PyErr_Format(PyExc_TypeError, "You need specify QML_IMPORT_NAME in order to use QmlElement."); + PyErr_Format(PyExc_TypeError, "You need specify QML_IMPORT_NAME in order to use %s.", + decoratorName); return nullptr; } if (majorVersion == -1) { - PyErr_Format(PyExc_TypeError, "You need specify QML_IMPORT_MAJOR_VERSION in order to use QmlElement."); + PyErr_Format(PyExc_TypeError, "You need specify QML_IMPORT_MAJOR_VERSION in order to use %s.", + decoratorName); return nullptr; } @@ -395,9 +408,23 @@ PyObject *PySide::qmlElementMacro(PyObject *pyObj) if (minorVersion == -1) minorVersion = 0; - if (qmlRegisterType(pyObj, importName.c_str(), majorVersion, minorVersion, pyObjType->tp_name) == -1) { - PyErr_Format(PyExc_TypeError, "Failed to register type %s.", pyObjType->tp_name); + 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); } return pyObj; } + +PyObject *PySide::qmlElementMacro(PyObject *pyObj) +{ + return qmlElementMacroHelper(pyObj, "QmlElement"); +} + +PyObject *PySide::qmlAnonymousMacro(PyObject *pyObj) +{ + return qmlElementMacroHelper(pyObj, "QmlAnonymous", + RegisterMode::Anonymous); +} diff --git a/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.h b/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.h index 5c2c15c3d..e8105eb94 100644 --- a/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.h +++ b/sources/pyside6/PySide6/QtQml/pysideqmlregistertype.h @@ -95,6 +95,11 @@ int qmlRegisterSingletonInstance(PyObject *pyObj, const char *uri, int versionMa * \param pyObj Python type to be registered */ PyObject *qmlElementMacro(PyObject *pyObj); + +/// PySide implementation of the QML_ANONYMOUS macro +/// \param pyObj Python type to be registered +PyObject *qmlAnonymousMacro(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 eb05cdff8..58b04d367 100644 --- a/sources/pyside6/PySide6/QtQml/typesystem_qml.xml +++ b/sources/pyside6/PySide6/QtQml/typesystem_qml.xml @@ -106,6 +106,10 @@ <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlelement"/> </add-function> + <add-function signature="QmlAnonymous(PyObject*)" return-type="PyObject*"> + <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlanonymous"/> + </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 4a8d72ca4..f4a54a55a 100644 --- a/sources/pyside6/PySide6/glue/qtqml.cpp +++ b/sources/pyside6/PySide6/glue/qtqml.cpp @@ -85,3 +85,7 @@ return %CONVERTTOPYTHON[%RETURN_TYPE](retval); // @snippet qmlelement %PYARG_0 = PySide::qmlElementMacro(%ARGUMENT_NAMES); // @snippet qmlelement + +// @snippet qmlanonymous +%PYARG_0 = PySide::qmlAnonymousMacro(%ARGUMENT_NAMES); +// @snippet qmlanonymous diff --git a/sources/pyside6/doc/extras/QtQml.QmlAnonymous.rst b/sources/pyside6/doc/extras/QtQml.QmlAnonymous.rst new file mode 100644 index 000000000..a805b0763 --- /dev/null +++ b/sources/pyside6/doc/extras/QtQml.QmlAnonymous.rst @@ -0,0 +1,22 @@ +.. currentmodule:: PySide6.QtQml +.. _QmlAnonymous: + +QmlAnonymous +************ + +.. py:decorator:: QmlAnonymous + + Declares the enclosing type to be available, but anonymous in QML. The type + cannot be created or used to declare properties in QML, but when passed from + C++, it is recognized. In QML, you can use properties of this type if they + are declared in C++. + + .. code-block:: python + + QML_IMPORT_NAME = "com.library.name" + QML_IMPORT_MAJOR_VERSION = 1 + QML_IMPORT_MINOR_VERSION = 0 # Optional + + @QmlAnonymous + class ClassForQml(QObject): + # ... |