Skip to content

Commit dfdba3b

Browse files
committed
QQuickStates: Handle more types as result of when
When calling QQmlBinding::evaluate(), we get a generic QVariant back, and no conversions from the evaluation result to bool are done at that point. Consequently, we would need to mirror the engines conversion from arbitrary values to bool. Doing that manually is rather fragile, so we instead use the QMetaType based overload, which already takes care of the conversion. That requires making the overload public. As qmlsc is already using that overload from within evaluate, it was not affected by the bug. Fixes: QTBUG-108024 Pick-to: 6.2 6.4 6.5 Change-Id: I3d5ee8f886ea6ada44fc8182300f3472cb1efc3c Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
1 parent 7d5cc73 commit dfdba3b

File tree

4 files changed

+39
-10
lines changed

4 files changed

+39
-10
lines changed

src/qml/qml/qqmlbinding_p.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ class Q_QML_PRIVATE_EXPORT QQmlBinding : public QQmlJavaScriptExpression,
7979
};
8080

8181
QVariant evaluate();
82+
bool evaluate(void *result, QMetaType type)
83+
{
84+
return QQmlJavaScriptExpression::evaluate(&result, &type, 0);
85+
}
8286

8387
void expressionChanged() override;
8488

@@ -116,10 +120,6 @@ class Q_QML_PRIVATE_EXPORT QQmlBinding : public QQmlJavaScriptExpression,
116120
QQmlPropertyData::WriteFlags flags);
117121

118122
QV4::ReturnedValue evaluate(bool *isUndefined);
119-
bool evaluate(void *result, QMetaType type)
120-
{
121-
return QQmlJavaScriptExpression::evaluate(&result, &type, 0);
122-
}
123123

124124
private:
125125
static QQmlBinding *newBinding(const QQmlPropertyData *property);

src/quick/util/qquickstategroup.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -353,11 +353,10 @@ bool QQuickStateGroupPrivate::updateAutoState()
353353
if (abstractBinding && abstractBinding->kind() == QQmlAbstractBinding::QmlBinding) {
354354
QQmlBinding *binding = static_cast<QQmlBinding *>(abstractBinding);
355355
if (binding->hasValidContext()) {
356-
QVariant evalResult = binding->evaluate();
357-
if (evalResult.metaType() == QMetaType::fromType<QJSValue>())
358-
whenValue = evalResult.value<QJSValue>().toBool();
359-
else
360-
whenValue = evalResult.toBool();
356+
const auto boolType = QMetaType::fromType<bool>();
357+
const bool isUndefined = !binding->evaluate(&whenValue, boolType);
358+
if (isUndefined)
359+
whenValue = false;
361360
}
362361
}
363362

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import QtQuick 2.15
2+
3+
Item {
4+
id: root
5+
property var prop: null
6+
property bool works: false
7+
states: [
8+
State {
9+
name: "mystate"
10+
when: root.prop
11+
PropertyChanges {
12+
target: root
13+
works: "works"
14+
}
15+
}
16+
]
17+
Component.onCompleted: root.prop = Qt.createQmlObject(
18+
"import QtQml 2.15\nQtObject {}",
19+
root, "dynamicSnippet")
20+
}

tests/auto/quick/qquickstates/tst_qquickstates.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ private slots:
175175
void revertListMemoryLeak();
176176
void duplicateStateName();
177177
void trivialWhen();
178+
void jsValueWhen_data();
178179
void jsValueWhen();
179180
void noStateOsciallation();
180181
void parentChangeCorrectReversal();
@@ -1695,11 +1696,20 @@ void tst_qquickstates::trivialWhen()
16951696
QVERIFY(root);
16961697
}
16971698

1699+
1700+
void tst_qquickstates::jsValueWhen_data()
1701+
{
1702+
QTest::addColumn<QByteArray>("fileName");
1703+
QTest::addRow("jsObject") << QByteArray("jsValueWhen.qml");
1704+
QTest::addRow("qmlObject") << QByteArray("jsValueWhen2.qml");
1705+
}
1706+
16981707
void tst_qquickstates::jsValueWhen()
16991708
{
1709+
QFETCH(QByteArray, fileName);
17001710
QQmlEngine engine;
17011711

1702-
QQmlComponent c(&engine, testFileUrl("jsValueWhen.qml"));
1712+
QQmlComponent c(&engine, testFileUrl(fileName.constData()));
17031713
QScopedPointer<QObject> root(c.create());
17041714
QVERIFY(root);
17051715
QVERIFY(root->property("works").toBool());

0 commit comments

Comments
 (0)