Add itemAtIndex to quick views

This patch adds itemAtIndex method to ItemView-derived views and
to PathView.

[ChangeLog][QtQuick][QQuickItemView] Added itemAtIndex() to
GridView, ListView and PathView to fetch a visible delegate by index.

Change-Id: Id8475d06c1481036984fe5109bb52cf2729b1c21
Fixes: QTBUG-72961
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Paolo Angelelli 2019-01-11 15:33:58 +01:00
parent 77e275a6f8
commit 6536076b1f
10 changed files with 107 additions and 0 deletions

View File

@ -2636,6 +2636,19 @@ bool QQuickGridViewPrivate::needsRefillForAddedOrRemovedIndex(int modelIndex) co
\b Note: methods should only be called after the Component has completed.
*/
/*!
\qmlmethod Item QtQuick::GridView::itemAtIndex(int index)
Returns the item for \a index. If there is no item for that index, for example
because it has not been created yet, or because it has been panned out of
the visible area and removed from the cache, null is returned.
\b Note: this method should only be called after the Component has completed.
The returned value should also not be stored since it can turn to null
as soon as control goes out of the calling scope, if the view releases that item.
\since 5.13
*/
/*!
\qmlmethod QtQuick::GridView::forceLayout()

View File

@ -472,6 +472,10 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
#if QT_CONFIG(quick_tableview)
qmlRegisterType<QQuickTableView>(uri, 2, 12, "TableView");
#endif
qmlRegisterUncreatableType<QQuickItemView, 13>(uri, 2, 13, itemViewName, itemViewMessage);
qmlRegisterType<QQuickPathView, 13>(uri, 2, 13, "PathView");
qmlRegisterType<QQuickGridView, 13>(uri, 2, 13, "GridView");
}
static void initResources()

View File

@ -951,6 +951,13 @@ QQuickItem *QQuickItemView::itemAt(qreal x, qreal y) const
return item ? item->item : nullptr;
}
QQuickItem *QQuickItemView::itemAtIndex(int index) const
{
Q_D(const QQuickItemView);
const FxViewItem *item = d->visibleItem(index);
return item ? item->item : nullptr;
}
void QQuickItemView::forceLayout()
{
Q_D(QQuickItemView);

View File

@ -228,6 +228,7 @@ public:
Q_INVOKABLE void positionViewAtIndex(int index, int mode);
Q_INVOKABLE int indexAt(qreal x, qreal y) const;
Q_INVOKABLE QQuickItem *itemAt(qreal x, qreal y) const;
Q_REVISION(13) Q_INVOKABLE QQuickItem *itemAtIndex(int index) const;
Q_INVOKABLE void positionViewAtBeginning();
Q_INVOKABLE void positionViewAtEnd();
Q_REVISION(1) Q_INVOKABLE void forceLayout();

View File

@ -3512,6 +3512,20 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex
\b Note: methods should only be called after the Component has completed.
*/
/*!
\qmlmethod Item QtQuick::ListView::itemAtIndex(int index)
Returns the item for \a index. If there is no item for that index, for example
because it has not been created yet, or because it has been panned out of
the visible area and removed from the cache, null is returned.
\b Note: this method should only be called after the Component has completed.
The returned value should also not be stored since it can turn to null
as soon as control goes out of the calling scope, if the view releases that item.
\since 5.13
*/
/*!
\qmlmethod QtQuick::ListView::forceLayout()

View File

@ -1550,6 +1550,33 @@ QQuickItem *QQuickPathView::itemAt(qreal x, qreal y) const
return nullptr;
}
/*!
\qmlmethod Item QtQuick::QQuickPathView::itemAtIndex(int index)
Returns the item for \a index. If there is no item for that index, for example
because it has not been created yet, or because it has been panned out of
the visible area and removed from the cache, null is returned.
\b Note: this method should only be called after the Component has completed.
The returned value should also not be stored since it can turn to null
as soon as control goes out of the calling scope, if the view releases that item.
\since 5.13
*/
QQuickItem *QQuickPathView::itemAtIndex(int index) const
{
Q_D(const QQuickPathView);
if (!d->isValid())
return nullptr;
for (QQuickItem *item : d->items) {
if (index == d->model->indexOf(item, nullptr))
return item;
}
return nullptr;
}
QPointF QQuickPathViewPrivate::pointNear(const QPointF &point, qreal *nearPercent) const
{
const auto pathLength = path->path().length();

View File

@ -180,6 +180,7 @@ public:
Q_INVOKABLE void positionViewAtIndex(int index, int mode);
Q_INVOKABLE int indexAt(qreal x, qreal y) const;
Q_INVOKABLE QQuickItem *itemAt(qreal x, qreal y) const;
Q_REVISION(13) Q_INVOKABLE QQuickItem *itemAtIndex(int index) const;
static QQuickPathViewAttached *qmlAttachedProperties(QObject *);

View File

@ -0,0 +1,15 @@
import QtQuick 2.0
ListView {
width: 400
height: 400
focus: true
model: 3
delegate: Text {
width: parent.width
height: 10
property int idx: index
text: index
}
}

View File

@ -16,6 +16,7 @@ include (../../shared/util.pri)
include (../shared/util.pri)
TESTDATA = data/*
DISTFILES += data/*
QT += core-private gui-private qml-private quick-private testlib qmltest

View File

@ -166,6 +166,7 @@ private slots:
void QTBUG_16037();
void indexAt_itemAt_data();
void indexAt_itemAt();
void itemAtIndex();
void incrementalModel();
void onAdd();
void onAdd_data();
@ -4782,6 +4783,29 @@ void tst_QQuickListView::indexAt_itemAt()
delete testObject;
}
void tst_QQuickListView::itemAtIndex()
{
QScopedPointer<QQuickView> window(createView());
window->setSource(testFileUrl("listview-itematindex.qml"));
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window.data()));
QQuickListView *listview = qobject_cast<QQuickListView*>(window->rootObject());
QVERIFY(listview != nullptr);
QCOMPARE(listview->itemAtIndex(-1), nullptr);
QCOMPARE(listview->itemAtIndex(3), nullptr);
QQuickItem *item = listview->itemAtIndex(0);
QVERIFY(item);
QCOMPARE(item->property("idx"), 0);
item = listview->itemAtIndex(1);
QVERIFY(item);
QCOMPARE(item->property("idx"), 1);
item = listview->itemAtIndex(2);
QVERIFY(item);
QCOMPARE(item->property("idx"), 2);
}
void tst_QQuickListView::incrementalModel()
{
QScopedPointer<QQuickView> window(createView());