diff options
author | Joni Poikelin <joni.poikelin@qt.io> | 2019-12-27 11:12:23 +0200 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2020-01-24 05:15:40 +0000 |
commit | 6dce8c470ca9711fc874b32519cefdcca40f149f (patch) | |
tree | 9d8174b320f00511bdf8d31e466c0fe786a01aba | |
parent | 04e855d5e2639be8acd91f4a581f1500a2908282 (diff) |
Add support to match against QObject properties in DelegateChooser
Views could use an array of QObject instances as a model, as an alterative to a
QAIM subclass; but DelegateChooser only supported querying the value based on the
model role name. Now a QObject property name can also be used as roleValue.
[ChangeLog][QtQuick][Item Views] DelegateChooser now supports using a property name
as roleValue when an array of QObject instances is used as the model for a view.
Fixes: QTBUG-81580
Change-Id: I3e5b57ce0456520667e342741efbe46417f0843c
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | src/imports/labsmodels/qqmldelegatecomponent.cpp | 12 | ||||
-rw-r--r-- | tests/auto/qmltest/listview/data/MultiDelegate3.qml | 97 | ||||
-rw-r--r-- | tests/auto/qmltest/listview/tst_listview.qml | 17 |
3 files changed, 123 insertions, 3 deletions
diff --git a/src/imports/labsmodels/qqmldelegatecomponent.cpp b/src/imports/labsmodels/qqmldelegatecomponent.cpp index 4698287fe3..aaf3fea5da 100644 --- a/src/imports/labsmodels/qqmldelegatecomponent.cpp +++ b/src/imports/labsmodels/qqmldelegatecomponent.cpp @@ -218,7 +218,7 @@ bool QQmlDelegateChoice::match(int row, int column, const QVariant &value) const /*! \qmlproperty string QtQml.Models::DelegateChooser::role - This property holds the role used to determine the delegate for a given model item. + This property holds the role or the property name used to determine the delegate for a given model item. \sa DelegateChoice */ @@ -289,9 +289,15 @@ QQmlComponent *QQmlDelegateChooser::delegate(QQmlAdaptorModel *adaptorModel, int v = value(adaptorModel, row, column, m_role); if (!v.isValid()) { // check if the row only has modelData, for example if the row is a QVariantMap v = value(adaptorModel, row, column, QStringLiteral("modelData")); - if (v.isValid()) - v = v.toMap().value(m_role); + + if (v.isValid()) { + if (v.canConvert(QMetaType::QVariantMap)) + v = v.toMap().value(m_role); + else if (v.canConvert(QMetaType::QObjectStar)) + v = v.value<QObject*>()->property(m_role.toUtf8()); + } } + // loop through choices, finding first one that fits for (int i = 0; i < m_choices.count(); ++i) { const QQmlDelegateChoice *choice = m_choices.at(i); diff --git a/tests/auto/qmltest/listview/data/MultiDelegate3.qml b/tests/auto/qmltest/listview/data/MultiDelegate3.qml new file mode 100644 index 0000000000..75116e0f9b --- /dev/null +++ b/tests/auto/qmltest/listview/data/MultiDelegate3.qml @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 +import QtQml.Models 2.12 +import Qt.labs.qmlmodels 1.0 + +ListView { + width: 400 + height: 400 + + property var item1: QtObject { + property string dataType: "rect" + property color color: "red" + } + property var item2: QtObject { + property string dataType: "text" + property string text: "Hello world" + } + model: [ item1, item2 ] + + delegate: DelegateChooser { + role: "dataType" + DelegateChoice { + roleValue: "rect" + delegate: Rectangle { + width: parent.width + height: 50 + color: modelData.color + } + } + DelegateChoice { + roleValue: "text" + delegate: Text { + width: parent.width + height: 50 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + text: modelData.text + } + } + + DelegateChoice { + delegate: Item { + width: parent.width + height: 50 + } + } + } +} diff --git a/tests/auto/qmltest/listview/tst_listview.qml b/tests/auto/qmltest/listview/tst_listview.qml index 5e9bb22e8e..bea6b45c3a 100644 --- a/tests/auto/qmltest/listview/tst_listview.qml +++ b/tests/auto/qmltest/listview/tst_listview.qml @@ -213,6 +213,10 @@ Item { id: multiDelegate2 } + MultiDelegate3 { + id: multiDelegate3 + } + TestCase { name: "ListView" when: windowShown @@ -414,5 +418,18 @@ Item { var delegate = multiDelegate2.itemAt(10, row.y) compare(delegate.choiceType, row.type) } + + function test_multipleDelegates3_data() { + return [ + { y: 25, type: "Rectangle", property: "color", value: "#ff0000" }, + { y: 75, type: "Text", property: "text", value: "Hello world" } + ] + } + + function test_multipleDelegates3(row) { + var delegate = multiDelegate3.itemAt(10, row.y) + verify(delegate.toString().includes(row.type)) + compare(delegate[row.property], row.value) + } } } |