aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2021-11-08 15:48:33 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2021-11-10 19:58:33 +0100
commit4f57d4eb32df52838129547be60b1a75d3f3356c (patch)
tree19f625c23ebd5ecdbe6cd9f30e71832f0df15d4a
parent5b9320df2284b96dba4d5eec1857a797797187e6 (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.cpp39
-rw-r--r--sources/pyside6/PySide6/QtQml/pysideqmlregistertype.h5
-rw-r--r--sources/pyside6/PySide6/QtQml/typesystem_qml.xml4
-rw-r--r--sources/pyside6/PySide6/glue/qtqml.cpp4
-rw-r--r--sources/pyside6/doc/extras/QtQml.QmlAnonymous.rst22
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):
+ # ...