1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include <QtTest/QtTest>
43 #include <QtTest/QSignalSpy>
44 #include <private/qlistmodelinterface_p.h>
45 #include <QtDeclarative/qdeclarativeengine.h>
46 #include <QtQuick/qquickview.h>
47 #include <QtDeclarative/qdeclarativecontext.h>
48 #include <QtDeclarative/qdeclarativeexpression.h>
49 #include <QtDeclarative/qdeclarativeincubator.h>
50 #include <private/qquickrepeater_p.h>
51 #include <QtQuick/private/qquicktext_p.h>
53 #include "../../shared/util.h"
55 class tst_QQuickRepeater : public QDeclarativeDataTest
65 void dataModel_adding();
66 void dataModel_removing();
67 void dataModel_changes();
76 QQuickView *createView();
78 T *findItem(QObject *parent, const QString &objectName, int index);
80 T *findItem(QObject *parent, const QString &id);
83 class TestObject : public QObject
87 Q_PROPERTY(bool error READ error WRITE setError)
88 Q_PROPERTY(bool useModel READ useModel NOTIFY useModelChanged)
91 TestObject() : QObject(), mError(true), mUseModel(false) {}
93 bool error() const { return mError; }
94 void setError(bool err) { mError = err; }
96 bool useModel() const { return mUseModel; }
97 void setUseModel(bool use) { mUseModel = use; emit useModelChanged(); }
100 void useModelChanged();
107 class TestModel : public QAbstractListModel
110 enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
112 TestModel(QObject *parent=0) : QAbstractListModel(parent) {
113 QHash<int, QByteArray> roles;
114 roles[Name] = "name";
115 roles[Number] = "number";
119 int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
120 QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
123 rv = list.at(index.row()).first;
124 else if (role == Number)
125 rv = list.at(index.row()).second;
130 int count() const { return rowCount(); }
131 QString name(int index) const { return list.at(index).first; }
132 QString number(int index) const { return list.at(index).second; }
134 void addItem(const QString &name, const QString &number) {
135 emit beginInsertRows(QModelIndex(), list.count(), list.count());
136 list.append(QPair<QString,QString>(name, number));
137 emit endInsertRows();
140 void insertItem(int index, const QString &name, const QString &number) {
141 emit beginInsertRows(QModelIndex(), index, index);
142 list.insert(index, QPair<QString,QString>(name, number));
143 emit endInsertRows();
146 void removeItem(int index) {
147 emit beginRemoveRows(QModelIndex(), index, index);
148 list.removeAt(index);
149 emit endRemoveRows();
152 void moveItem(int from, int to) {
153 emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
158 void modifyItem(int idx, const QString &name, const QString &number) {
159 list[idx] = QPair<QString,QString>(name, number);
160 emit dataChanged(index(idx,0), index(idx,0));
164 QList<QPair<QString,QString> > list;
168 tst_QQuickRepeater::tst_QQuickRepeater()
172 void tst_QQuickRepeater::numberModel()
174 QQuickView *canvas = createView();
176 QDeclarativeContext *ctxt = canvas->rootContext();
177 ctxt->setContextProperty("testData", 5);
178 TestObject *testObject = new TestObject;
179 ctxt->setContextProperty("testObject", testObject);
181 canvas->setSource(testFileUrl("intmodel.qml"));
182 qApp->processEvents();
184 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
185 QVERIFY(repeater != 0);
186 QCOMPARE(repeater->parentItem()->childItems().count(), 5+1);
188 QVERIFY(!repeater->itemAt(-1));
189 for (int i=0; i<repeater->count(); i++)
190 QCOMPARE(repeater->itemAt(i), repeater->parentItem()->childItems().at(i));
191 QVERIFY(!repeater->itemAt(repeater->count()));
193 QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
194 QVERIFY(testObject->error() == false);
200 class MyObject : public QObject
203 Q_PROPERTY(int idx READ idx CONSTANT)
205 MyObject(int i) : QObject(), m_idx(i) {}
207 int idx() const { return m_idx; }
212 void tst_QQuickRepeater::objectList()
214 QQuickView *canvas = createView();
216 for (int i=0; i<100; i++)
217 data << new MyObject(i);
219 QDeclarativeContext *ctxt = canvas->rootContext();
220 ctxt->setContextProperty("testData", QVariant::fromValue(data));
222 canvas->setSource(testFileUrl("objlist.qml"));
223 qApp->processEvents();
225 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
226 QVERIFY(repeater != 0);
227 QCOMPARE(repeater->property("errors").toInt(), 0);//If this fails either they are out of order or can't find the object's data
228 QCOMPARE(repeater->property("instantiated").toInt(), 100);
230 QVERIFY(!repeater->itemAt(-1));
231 for (int i=0; i<data.count(); i++)
232 QCOMPARE(repeater->itemAt(i), repeater->parentItem()->childItems().at(i));
233 QVERIFY(!repeater->itemAt(data.count()));
235 QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*)));
236 QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*)));
237 ctxt->setContextProperty("testData", QVariant::fromValue(data));
238 QCOMPARE(addedSpy.count(), data.count());
239 QCOMPARE(removedSpy.count(), data.count());
246 The Repeater element creates children at its own position in its parent's
247 stacking order. In this test we insert a repeater between two other Text
248 elements to test this.
250 void tst_QQuickRepeater::stringList()
252 QQuickView *canvas = createView();
260 QDeclarativeContext *ctxt = canvas->rootContext();
261 ctxt->setContextProperty("testData", data);
263 canvas->setSource(testFileUrl("repeater1.qml"));
264 qApp->processEvents();
266 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
267 QVERIFY(repeater != 0);
269 QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
270 QVERIFY(container != 0);
272 QCOMPARE(container->childItems().count(), data.count() + 3);
274 bool saw_repeater = false;
275 for (int i = 0; i < container->childItems().count(); ++i) {
278 QQuickText *name = qobject_cast<QQuickText*>(container->childItems().at(i));
280 QCOMPARE(name->text(), QLatin1String("Zero"));
281 } else if (i == container->childItems().count() - 2) {
282 // The repeater itself
283 QQuickRepeater *rep = qobject_cast<QQuickRepeater*>(container->childItems().at(i));
284 QCOMPARE(rep, repeater);
287 } else if (i == container->childItems().count() - 1) {
288 QQuickText *name = qobject_cast<QQuickText*>(container->childItems().at(i));
290 QCOMPARE(name->text(), QLatin1String("Last"));
292 QQuickText *name = qobject_cast<QQuickText*>(container->childItems().at(i));
294 QCOMPARE(name->text(), data.at(i-1));
297 QVERIFY(saw_repeater);
302 void tst_QQuickRepeater::dataModel_adding()
304 QQuickView *canvas = createView();
305 QDeclarativeContext *ctxt = canvas->rootContext();
306 TestObject *testObject = new TestObject;
307 ctxt->setContextProperty("testObject", testObject);
310 ctxt->setContextProperty("testData", &testModel);
311 canvas->setSource(testFileUrl("repeater2.qml"));
312 qApp->processEvents();
314 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
315 QVERIFY(repeater != 0);
316 QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
317 QVERIFY(container != 0);
319 QVERIFY(!repeater->itemAt(0));
321 QSignalSpy countSpy(repeater, SIGNAL(countChanged()));
322 QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*)));
324 // add to empty model
325 testModel.addItem("two", "2");
326 QCOMPARE(repeater->itemAt(0), container->childItems().at(0));
327 QCOMPARE(countSpy.count(), 1); countSpy.clear();
328 QCOMPARE(addedSpy.count(), 1);
329 QCOMPARE(addedSpy.at(0).at(0).toInt(), 0);
330 QCOMPARE(addedSpy.at(0).at(1).value<QQuickItem*>(), container->childItems().at(0));
334 testModel.insertItem(0, "one", "1");
335 QCOMPARE(repeater->itemAt(0), container->childItems().at(0));
336 QCOMPARE(countSpy.count(), 1); countSpy.clear();
337 QCOMPARE(addedSpy.count(), 1);
338 QCOMPARE(addedSpy.at(0).at(0).toInt(), 0);
339 QCOMPARE(addedSpy.at(0).at(1).value<QQuickItem*>(), container->childItems().at(0));
343 testModel.insertItem(2, "four", "4");
344 QCOMPARE(repeater->itemAt(2), container->childItems().at(2));
345 QCOMPARE(countSpy.count(), 1); countSpy.clear();
346 QCOMPARE(addedSpy.count(), 1);
347 QCOMPARE(addedSpy.at(0).at(0).toInt(), 2);
348 QCOMPARE(addedSpy.at(0).at(1).value<QQuickItem*>(), container->childItems().at(2));
352 testModel.insertItem(2, "three", "3");
353 QCOMPARE(repeater->itemAt(2), container->childItems().at(2));
354 QCOMPARE(countSpy.count(), 1); countSpy.clear();
355 QCOMPARE(addedSpy.count(), 1);
356 QCOMPARE(addedSpy.at(0).at(0).toInt(), 2);
357 QCOMPARE(addedSpy.at(0).at(1).value<QQuickItem*>(), container->childItems().at(2));
366 void tst_QQuickRepeater::dataModel_removing()
368 QQuickView *canvas = createView();
369 QDeclarativeContext *ctxt = canvas->rootContext();
370 TestObject *testObject = new TestObject;
371 ctxt->setContextProperty("testObject", testObject);
374 testModel.addItem("one", "1");
375 testModel.addItem("two", "2");
376 testModel.addItem("three", "3");
377 testModel.addItem("four", "4");
378 testModel.addItem("five", "5");
380 ctxt->setContextProperty("testData", &testModel);
381 canvas->setSource(testFileUrl("repeater2.qml"));
382 qApp->processEvents();
384 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
385 QVERIFY(repeater != 0);
386 QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
387 QVERIFY(container != 0);
388 QCOMPARE(container->childItems().count(), repeater->count()+1);
390 QSignalSpy countSpy(repeater, SIGNAL(countChanged()));
391 QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*)));
394 QQuickItem *item = repeater->itemAt(0);
395 QCOMPARE(item, container->childItems().at(0));
397 testModel.removeItem(0);
398 QVERIFY(repeater->itemAt(0) != item);
399 QCOMPARE(countSpy.count(), 1); countSpy.clear();
400 QCOMPARE(removedSpy.count(), 1);
401 QCOMPARE(removedSpy.at(0).at(0).toInt(), 0);
402 QCOMPARE(removedSpy.at(0).at(1).value<QQuickItem*>(), item);
406 int lastIndex = testModel.count()-1;
407 item = repeater->itemAt(lastIndex);
408 QCOMPARE(item, container->childItems().at(lastIndex));
410 testModel.removeItem(lastIndex);
411 QVERIFY(repeater->itemAt(lastIndex) != item);
412 QCOMPARE(countSpy.count(), 1); countSpy.clear();
413 QCOMPARE(removedSpy.count(), 1);
414 QCOMPARE(removedSpy.at(0).at(0).toInt(), lastIndex);
415 QCOMPARE(removedSpy.at(0).at(1).value<QQuickItem*>(), item);
418 // remove from middle
419 item = repeater->itemAt(1);
420 QCOMPARE(item, container->childItems().at(1));
422 testModel.removeItem(1);
423 QVERIFY(repeater->itemAt(lastIndex) != item);
424 QCOMPARE(countSpy.count(), 1); countSpy.clear();
425 QCOMPARE(removedSpy.count(), 1);
426 QCOMPARE(removedSpy.at(0).at(0).toInt(), 1);
427 QCOMPARE(removedSpy.at(0).at(1).value<QQuickItem*>(), item);
434 void tst_QQuickRepeater::dataModel_changes()
436 QQuickView *canvas = createView();
437 QDeclarativeContext *ctxt = canvas->rootContext();
438 TestObject *testObject = new TestObject;
439 ctxt->setContextProperty("testObject", testObject);
442 testModel.addItem("one", "1");
443 testModel.addItem("two", "2");
444 testModel.addItem("three", "3");
446 ctxt->setContextProperty("testData", &testModel);
447 canvas->setSource(testFileUrl("repeater2.qml"));
448 qApp->processEvents();
450 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
451 QVERIFY(repeater != 0);
452 QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
453 QVERIFY(container != 0);
454 QCOMPARE(container->childItems().count(), repeater->count()+1);
456 // Check that model changes are propagated
457 QQuickText *text = findItem<QQuickText>(canvas->rootObject(), "myName", 1);
459 QCOMPARE(text->text(), QString("two"));
461 testModel.modifyItem(1, "Item two", "_2");
462 text = findItem<QQuickText>(canvas->rootObject(), "myName", 1);
464 QCOMPARE(text->text(), QString("Item two"));
466 text = findItem<QQuickText>(canvas->rootObject(), "myNumber", 1);
468 QCOMPARE(text->text(), QString("_2"));
474 void tst_QQuickRepeater::itemModel()
476 QQuickView *canvas = createView();
477 QDeclarativeContext *ctxt = canvas->rootContext();
478 TestObject *testObject = new TestObject;
479 ctxt->setContextProperty("testObject", testObject);
481 canvas->setSource(testFileUrl("itemlist.qml"));
482 qApp->processEvents();
484 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
485 QVERIFY(repeater != 0);
487 QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
488 QVERIFY(container != 0);
490 QCOMPARE(container->childItems().count(), 1);
492 testObject->setUseModel(true);
493 QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
494 QVERIFY(testObject->error() == false);
496 QCOMPARE(container->childItems().count(), 4);
497 QVERIFY(qobject_cast<QObject*>(container->childItems().at(0))->objectName() == "item1");
498 QVERIFY(qobject_cast<QObject*>(container->childItems().at(1))->objectName() == "item2");
499 QVERIFY(qobject_cast<QObject*>(container->childItems().at(2))->objectName() == "item3");
500 QVERIFY(container->childItems().at(3) == repeater);
502 QMetaObject::invokeMethod(canvas->rootObject(), "switchModel");
503 QCOMPARE(container->childItems().count(), 3);
504 QVERIFY(qobject_cast<QObject*>(container->childItems().at(0))->objectName() == "item4");
505 QVERIFY(qobject_cast<QObject*>(container->childItems().at(1))->objectName() == "item5");
506 QVERIFY(container->childItems().at(2) == repeater);
508 testObject->setUseModel(false);
509 QCOMPARE(container->childItems().count(), 1);
515 void tst_QQuickRepeater::resetModel()
517 QQuickView *canvas = createView();
520 for (int i=0; i<10; i++)
521 dataA << QString::number(i);
523 QDeclarativeContext *ctxt = canvas->rootContext();
524 ctxt->setContextProperty("testData", dataA);
525 canvas->setSource(testFileUrl("repeater1.qml"));
526 qApp->processEvents();
527 QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
528 QVERIFY(repeater != 0);
529 QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
530 QVERIFY(container != 0);
532 QCOMPARE(repeater->count(), dataA.count());
533 for (int i=0; i<repeater->count(); i++)
534 QCOMPARE(repeater->itemAt(i), container->childItems().at(i+1)); // +1 to skip first Text object
536 QSignalSpy modelChangedSpy(repeater, SIGNAL(modelChanged()));
537 QSignalSpy countSpy(repeater, SIGNAL(countChanged()));
538 QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*)));
539 QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*)));
542 for (int i=0; i<20; i++)
543 dataB << QString::number(i);
545 // reset context property
546 ctxt->setContextProperty("testData", dataB);
547 QCOMPARE(repeater->count(), dataB.count());
549 QCOMPARE(modelChangedSpy.count(), 1);
550 QCOMPARE(countSpy.count(), 1);
551 QCOMPARE(removedSpy.count(), dataA.count());
552 QCOMPARE(addedSpy.count(), dataB.count());
553 for (int i=0; i<dataB.count(); i++) {
554 QCOMPARE(addedSpy.at(i).at(0).toInt(), i);
555 QCOMPARE(addedSpy.at(i).at(1).value<QQuickItem*>(), repeater->itemAt(i));
557 modelChangedSpy.clear();
562 // reset via setModel()
563 repeater->setModel(dataA);
564 QCOMPARE(repeater->count(), dataA.count());
566 QCOMPARE(modelChangedSpy.count(), 1);
567 QCOMPARE(countSpy.count(), 1);
568 QCOMPARE(removedSpy.count(), dataB.count());
569 QCOMPARE(addedSpy.count(), dataA.count());
570 for (int i=0; i<dataA.count(); i++) {
571 QCOMPARE(addedSpy.at(i).at(0).toInt(), i);
572 QCOMPARE(addedSpy.at(i).at(1).value<QQuickItem*>(), repeater->itemAt(i));
575 modelChangedSpy.clear();
584 void tst_QQuickRepeater::modelChanged()
586 QDeclarativeEngine engine;
587 QDeclarativeComponent component(&engine, testFileUrl("modelChanged.qml"));
589 QQuickItem *rootObject = qobject_cast<QQuickItem*>(component.create());
591 QQuickRepeater *repeater = findItem<QQuickRepeater>(rootObject, "repeater");
594 repeater->setModel(4);
595 QCOMPARE(repeater->count(), 4);
596 QCOMPARE(repeater->property("itemsCount").toInt(), 4);
597 QCOMPARE(repeater->property("itemsFound").toList().count(), 4);
599 repeater->setModel(10);
600 QCOMPARE(repeater->count(), 10);
601 QCOMPARE(repeater->property("itemsCount").toInt(), 10);
602 QCOMPARE(repeater->property("itemsFound").toList().count(), 10);
607 void tst_QQuickRepeater::properties()
609 QDeclarativeEngine engine;
610 QDeclarativeComponent component(&engine, testFileUrl("properties.qml"));
612 QQuickItem *rootObject = qobject_cast<QQuickItem*>(component.create());
615 QQuickRepeater *repeater = findItem<QQuickRepeater>(rootObject, "repeater");
618 QSignalSpy modelSpy(repeater, SIGNAL(modelChanged()));
619 repeater->setModel(3);
620 QCOMPARE(modelSpy.count(),1);
621 repeater->setModel(3);
622 QCOMPARE(modelSpy.count(),1);
624 QSignalSpy delegateSpy(repeater, SIGNAL(delegateChanged()));
626 QDeclarativeComponent rectComponent(&engine);
627 rectComponent.setData("import QtQuick 2.0; Rectangle {}", QUrl::fromLocalFile(""));
629 repeater->setDelegate(&rectComponent);
630 QCOMPARE(delegateSpy.count(),1);
631 repeater->setDelegate(&rectComponent);
632 QCOMPARE(delegateSpy.count(),1);
637 void tst_QQuickRepeater::asynchronous()
639 QQuickView *canvas = createView();
641 QDeclarativeIncubationController controller;
642 canvas->engine()->setIncubationController(&controller);
644 canvas->setSource(testFileUrl("asyncloader.qml"));
646 QQuickItem *rootObject = qobject_cast<QQuickItem*>(canvas->rootObject());
649 QQuickItem *container = findItem<QQuickItem>(rootObject, "container");
653 controller.incubateWhile(&b);
654 container = findItem<QQuickItem>(rootObject, "container");
657 QQuickRepeater *repeater = 0;
660 controller.incubateWhile(&b);
661 repeater = findItem<QQuickRepeater>(rootObject, "repeater");
664 // items will be created one at a time
665 for (int i = 0; i < 10; ++i) {
666 QString name("delegate");
667 name += QString::number(i);
668 QVERIFY(findItem<QQuickItem>(container, name) == 0);
669 QQuickItem *item = 0;
672 controller.incubateWhile(&b);
673 item = findItem<QQuickItem>(container, name);
679 controller.incubateWhile(&b);
682 // verify positioning
683 for (int i = 0; i < 10; ++i) {
684 QString name("delegate");
685 name += QString::number(i);
686 QQuickItem *item = findItem<QQuickItem>(container, name);
687 QTRY_COMPARE(item->y(), i * 50.0);
693 void tst_QQuickRepeater::initParent()
695 QDeclarativeEngine engine;
696 QDeclarativeComponent component(&engine, testFileUrl("initparent.qml"));
698 QQuickItem *rootObject = qobject_cast<QQuickItem*>(component.create());
701 QCOMPARE(qvariant_cast<QQuickItem*>(rootObject->property("parentItem")), rootObject);
704 QQuickView *tst_QQuickRepeater::createView()
706 QQuickView *canvas = new QQuickView(0);
707 canvas->setGeometry(0,0,240,320);
713 T *tst_QQuickRepeater::findItem(QObject *parent, const QString &objectName, int index)
715 const QMetaObject &mo = T::staticMetaObject;
716 //qDebug() << parent->children().count() << "children";
717 for (int i = 0; i < parent->children().count(); ++i) {
718 QQuickItem *item = qobject_cast<QQuickItem*>(parent->children().at(i));
721 //qDebug() << "try" << item;
722 if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
724 QDeclarativeExpression e(qmlContext(item), item, "index");
725 if (e.evaluate().toInt() == index)
726 return static_cast<T*>(item);
728 return static_cast<T*>(item);
731 item = findItem<T>(item, objectName, index);
733 return static_cast<T*>(item);
740 T *tst_QQuickRepeater::findItem(QObject *parent, const QString &objectName)
742 const QMetaObject &mo = T::staticMetaObject;
743 if (mo.cast(parent) && (objectName.isEmpty() || parent->objectName() == objectName))
744 return static_cast<T*>(parent);
745 for (int i = 0; i < parent->children().count(); ++i) {
746 QQuickItem *child = qobject_cast<QQuickItem*>(parent->children().at(i));
749 QQuickItem *item = findItem<T>(child, objectName);
751 return static_cast<T*>(item);
757 QTEST_MAIN(tst_QQuickRepeater)
759 #include "tst_qquickrepeater.moc"