aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2020-11-23 14:08:37 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2020-12-03 21:12:42 +0100
commit6eb35df60e061b9ce4e88f97a174216e2b1c617f (patch)
tree9619b6de7eca4b6e727fdd04de87e9dee1fe1e0b
parent77579924957af07dc9bfb2a7309caf606bcffab0 (diff)
QML engine: Deprecate DefaultMethod
Assigning objects to signal handlers can be convenient, as seen in the examples which use it together with ListView.onRemove. However, that convenience makes it hard to reason about what actually happens. Moreover, the only user of that functionality are the Animation classes, and the usage of DefaultMethod is not documented anywhere. [ChangeLog][QtQml] Assigning an object to a signal handler is deprecated. Instead, create the object, give it an id, and call the desired slot from the signal handler. For instance, instead of of ListView.onRemove: SequentialAnimation {...} use SequentialAnimation {id: removeAnimation; ...} ListView.onRemove: removeAnimation.start() A warning will be printed whenever an assignment of an object to a signal handler occurs. The warning can be controlled via the qt.qml.defaultmethod logging category. Change-Id: I001ddf4d7933871977f84a5e012d020fb043cc64 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--examples/quick/views/listview/dynamiclist.qml8
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp8
-rw-r--r--src/quick/doc/snippets/qml/listview/listview.qml4
-rw-r--r--tests/auto/quick/qquicklistview/data/listviewtest.qml4
-rw-r--r--tests/testapplications/listview/onRemove.qml4
5 files changed, 22 insertions, 6 deletions
diff --git a/examples/quick/views/listview/dynamiclist.qml b/examples/quick/views/listview/dynamiclist.qml
index f37aab98e2..973d3ce389 100644
--- a/examples/quick/views/listview/dynamiclist.qml
+++ b/examples/quick/views/listview/dynamiclist.qml
@@ -200,18 +200,22 @@ Rectangle {
// Animate adding and removing of items:
//! [1]
- ListView.onAdd: SequentialAnimation {
+ SequentialAnimation {
+ id: addAnimation
PropertyAction { target: delegateItem; property: "height"; value: 0 }
NumberAnimation { target: delegateItem; property: "height"; to: 80; duration: 250; easing.type: Easing.InOutQuad }
}
+ ListView.onAdd: addAnimation.start()
- ListView.onRemove: SequentialAnimation {
+ SequentialAnimation {
+ id: removeAnimation
PropertyAction { target: delegateItem; property: "ListView.delayRemove"; value: true }
NumberAnimation { target: delegateItem; property: "height"; to: 0; duration: 250; easing.type: Easing.InOutQuad }
// Make sure delayRemove is set back to false so that the item can be destroyed
PropertyAction { target: delegateItem; property: "ListView.delayRemove"; value: false }
}
+ ListView.onRemove: removeAnimation.start()
}
//! [1]
}
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 8bf16fec96..76d1bd20bd 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -66,6 +66,9 @@
#include <qtqml_tracepoints_p.h>
#include <QScopedValueRollback>
+#include <QLoggingCategory>
+
+Q_LOGGING_CATEGORY(lcQmlDefaultMethod, "qt.qml.defaultmethod")
QT_USE_NAMESPACE
@@ -1036,7 +1039,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
return false;
}
- // Assigning object to signal property?
+ // Assigning object to signal property? ### Qt 7: Remove that functionality
if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject) {
if (!bindingProperty->isFunction()) {
recordError(binding->valueLocation, tr("Cannot assign an object to signal property %1").arg(bindingProperty->name(_qobject)));
@@ -1047,6 +1050,9 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
recordError(binding->valueLocation, tr("Cannot assign object type %1 with no default method").arg(QString::fromLatin1(createdSubObject->metaObject()->className())));
return false;
}
+ qCWarning(lcQmlDefaultMethod) << "Assigning an object to a signal handler is deprecated."
+ "Instead, create the object, give it an id, and call the desired slot from the signal handler."
+ ;
QMetaMethod signalMethod = _qobject->metaObject()->method(bindingProperty->coreIndex());
if (!QMetaObject::checkConnectArgs(signalMethod, method)) {
diff --git a/src/quick/doc/snippets/qml/listview/listview.qml b/src/quick/doc/snippets/qml/listview/listview.qml
index 759344b574..b7b4b508c3 100644
--- a/src/quick/doc/snippets/qml/listview/listview.qml
+++ b/src/quick/doc/snippets/qml/listview/listview.qml
@@ -94,11 +94,13 @@ Rectangle {
Component {
id: delegate
Item {
- ListView.onRemove: SequentialAnimation {
+ SequentialAnimation {
+ id: removeAnimation
PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: true }
NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: Easing.InOutQuad }
PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: false }
}
+ ListView.onRemove: removeAnimation.start()
}
}
//![delayRemove]
diff --git a/tests/auto/quick/qquicklistview/data/listviewtest.qml b/tests/auto/quick/qquicklistview/data/listviewtest.qml
index b27c8e45e0..2bcba82035 100644
--- a/tests/auto/quick/qquicklistview/data/listviewtest.qml
+++ b/tests/auto/quick/qquicklistview/data/listviewtest.qml
@@ -95,12 +95,14 @@ Rectangle {
text: wrapper.y
}
color: ListView.isCurrentItem ? "lightsteelblue" : "white"
- ListView.onRemove: SequentialAnimation {
+ SequentialAnimation {
+ id: removeAnimation
PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: true }
NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: "InOutQuad" }
PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: false }
}
+ ListView.onRemove: removeAnimation.start()
}
},
Component {
diff --git a/tests/testapplications/listview/onRemove.qml b/tests/testapplications/listview/onRemove.qml
index c5fffb0e55..e8abbbed0e 100644
--- a/tests/testapplications/listview/onRemove.qml
+++ b/tests/testapplications/listview/onRemove.qml
@@ -87,13 +87,15 @@ Item {
lifeSpan: 2000
}
- ListView.onRemove: SequentialAnimation {
+ SequentialAnimation {
+ id: removeAnimation
PropertyAction { target: item; property: "ListView.delayRemove"; value: true }
PropertyAction { target: item; property: "opacity"; value: 0 }
ScriptAction { script: item.boom() }
PauseAnimation { duration: 1000 }
PropertyAction { target: item; property: "ListView.delayRemove"; value: false }
}
+ ListView.onRemove: removeAnimation.start()
}
}