Improve warning for QtQml.Binding
Print a warning if there is no property with the given name of the specified target object, or the property is read-only. Change-Id: I5dc2e8330fb1ce53be396b7bf5baf13c1702d2f4 Task-number: QTBUG-39243 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
This commit is contained in:
parent
fe7d35e3cb
commit
61ce37de40
|
@ -36,6 +36,7 @@
|
|||
#include <private/qqmlnullablevalue_p.h>
|
||||
#include <private/qqmlproperty_p.h>
|
||||
#include <private/qqmlbinding_p.h>
|
||||
#include <private/qqmlmetatype_p.h>
|
||||
|
||||
#include <qqmlengine.h>
|
||||
#include <qqmlcontext.h>
|
||||
|
@ -49,6 +50,29 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace {
|
||||
|
||||
void validateProperty(QObject *target, const QString &propertyName, QObject *binding)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
const QMetaObject *mo = target->metaObject();
|
||||
const int index = mo->indexOfProperty(propertyName.toUtf8());
|
||||
if (index == -1) {
|
||||
qmlInfo(binding) << "Property '" << propertyName << "' does not exist on " << QQmlMetaType::prettyTypeName(target) << ".";
|
||||
return;
|
||||
}
|
||||
|
||||
const QMetaProperty mp = mo->property(index);
|
||||
if (!mp.isWritable()) {
|
||||
qmlInfo(binding) << "Property '" << propertyName << "' on " << QQmlMetaType::prettyTypeName(target) << " is read-only.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class QQmlBindPrivate : public QObjectPrivate
|
||||
{
|
||||
public:
|
||||
|
@ -186,8 +210,10 @@ void QQmlBind::setObject(QObject *obj)
|
|||
d->when = true;
|
||||
}
|
||||
d->obj = obj;
|
||||
if (d->componentComplete)
|
||||
if (d->componentComplete) {
|
||||
validateProperty(d->obj, d->propName, this);
|
||||
d->prop = QQmlProperty(d->obj, d->propName);
|
||||
}
|
||||
eval();
|
||||
}
|
||||
|
||||
|
@ -213,8 +239,10 @@ void QQmlBind::setProperty(const QString &p)
|
|||
d->when = true;
|
||||
}
|
||||
d->propName = p;
|
||||
if (d->componentComplete)
|
||||
if (d->componentComplete) {
|
||||
validateProperty(d->obj, d->propName, this);
|
||||
d->prop = QQmlProperty(d->obj, d->propName);
|
||||
}
|
||||
eval();
|
||||
}
|
||||
|
||||
|
@ -253,8 +281,10 @@ void QQmlBind::componentComplete()
|
|||
{
|
||||
Q_D(QQmlBind);
|
||||
d->componentComplete = true;
|
||||
if (!d->prop.isValid())
|
||||
if (!d->prop.isValid()) {
|
||||
validateProperty(d->obj, d->propName, this);
|
||||
d->prop = QQmlProperty(d->obj, d->propName);
|
||||
}
|
||||
eval();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
readonly property string name: "John"
|
||||
|
||||
Binding {
|
||||
target: root
|
||||
property: "name"
|
||||
value: "Doe"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
Binding {
|
||||
target: root
|
||||
property: "unknown"
|
||||
value: 42
|
||||
}
|
||||
}
|
|
@ -50,6 +50,8 @@ private slots:
|
|||
void restoreBindingWithLoop();
|
||||
void restoreBindingWithoutCrash();
|
||||
void deletedObject();
|
||||
void warningOnUnknownProperty();
|
||||
void warningOnReadOnlyProperty();
|
||||
|
||||
private:
|
||||
QQmlEngine engine;
|
||||
|
@ -224,6 +226,38 @@ void tst_qqmlbinding::deletedObject()
|
|||
delete rect;
|
||||
}
|
||||
|
||||
void tst_qqmlbinding::warningOnUnknownProperty()
|
||||
{
|
||||
QQmlTestMessageHandler messageHandler;
|
||||
|
||||
QQmlEngine engine;
|
||||
QQmlComponent c(&engine, testFileUrl("unknownProperty.qml"));
|
||||
QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
|
||||
QVERIFY(item);
|
||||
delete item;
|
||||
|
||||
QCOMPARE(messageHandler.messages().count(), 1);
|
||||
|
||||
const QString expectedMessage = c.url().toString() + QLatin1String(":6:5: QML Binding: Property 'unknown' does not exist on Item.");
|
||||
QCOMPARE(messageHandler.messages().first(), expectedMessage);
|
||||
}
|
||||
|
||||
void tst_qqmlbinding::warningOnReadOnlyProperty()
|
||||
{
|
||||
QQmlTestMessageHandler messageHandler;
|
||||
|
||||
QQmlEngine engine;
|
||||
QQmlComponent c(&engine, testFileUrl("readonlyProperty.qml"));
|
||||
QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
|
||||
QVERIFY(item);
|
||||
delete item;
|
||||
|
||||
QCOMPARE(messageHandler.messages().count(), 1);
|
||||
|
||||
const QString expectedMessage = c.url().toString() + QLatin1String(":8:5: QML Binding: Property 'name' on Item is read-only.");
|
||||
QCOMPARE(messageHandler.messages().first(), expectedMessage);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qqmlbinding)
|
||||
|
||||
#include "tst_qqmlbinding.moc"
|
||||
|
|
Loading…
Reference in New Issue