Revision control

Copy as Markdown

// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtabstractitemmodel-in-android-studio-projects-example.html
\title Using QtAbstractItemModel in Android Studio Projects
\brief Shows how to handle complex data types and apply conditional
formatting to a table view format using QtAbstractItemModel class and
QtModelIndex class.
\ingroup qtquickexamples
\include running-qtquick-for-android-examples.qdocinc
\section1 Overview
\image qtabstractitemmodel_portrait.png {Android app with TableView
displaying editable cell grid and row/column control buttons}
This example consists of two projects: an Android Studio project
(qtabstractitemmodel_java) and a QML project (qtabstractitemmodel).
You can import the QML project into an Android project.
The example shows how to handle complex data types between Java and QML.
It demonstrates how to use the \l QtAbstractItemModel and \l QtModelIndex
Java API classes. In QML, the data usage is demonstrated with the TableView item.
In Java, data usage is demonstrated with a model of nested ArrayList items
for rows and columns. For more information on how QML works, see \l {Qt Qml}.
\section1 Running the example
To run this example, you need Android Studio and
\l {\QtTAS} on top of a standard Qt for Android installation.
Open qtabstractitemmodel_java in Android Studio and follow the instructions
in \l {\QtTAS} to import the \c qtabstractitemmodel.
\section1 QML project
On the QML project side, the example uses a \l [QML] {Rectangle} as the root
object. The \c dataModel property variable holds the data model created and
delivered from the Java side.
\snippet android/models/qtabstractitemmodel/Main.qml 0
\l [QML]{TableView} displays our data model.
\snippet android/models/qtabstractitemmodel/Main.qml 1
On the \c delegate property, each cell item of the model is defined with a
\l [QML]{Rectangle} containing a \l [QML]{TextEdit}.
The text property of the \c TextEdit is set using the
\l QAbstractItemModel::data()
which returns a value based on the given role and index.
Calling these methods from QML means the execution takes place in the Qt qtMainLoopThread
thread context.
\snippet android/models/qtabstractitemmodel/Main.qml 2
In the case of editing the \l {TextEdit} field, \c onEditingFinished() handler
sets the model's \c edit role value to the edited text. This calls the
\l QAbstractItemModel::setData()
method, where the edited text of the cell is updated to the corresponding
index of the model.
For more information see \l {QAbstractItemModel}.
\section1 Android Studio project
The Android Studio project (qtabstractitemmodel_java) contains
one Activity class \c MainActivity and \c MyDataModel class.
\section2 Data Model
The data model, \c MyDataModel, extends \l QtAbstractItemModel class.
The \c QtAbstractItemModel is a wrapper for \l {QAbstractItemModel}.
As the methods of \c MyDataModel class are called from both, QML and Android sides, the
execution occurs in both thread contexts, Qt qtMainLoopThread, and Android main thread
contexts. You must ensure synchronization when accessing member variables in methods of
the \c MyDataModel class.
First, the example initializes the model with a simple row and column mock data set. Note
that this constructor method is called in the Android main thread context.
\snippet android/models/qtabstractitemmodel_java/app/src/main/java/com/example/qtabstractitemmodel_java/MyDataModel.java 1
The example overrides the \l QtAbstractItemModel methods for different purposes. The
columnCount() and rowCount() methods return the count of each in a model. The execution of
each rowCount() occurs in both thread contexts, Qt qtMainLoopThread and Android main thread
contexts.
\snippet android/models/qtabstractitemmodel_java/app/src/main/java/com/example/qtabstractitemmodel_java/MyDataModel.java 2
Method data() provides model data based on the role and index from Java to QML. The
roleNames() method returns a hash matching numerical role values to their names as strings;
in QML, we use these role names to fetch corresponding data from the model. The index()
method returns the new model index. Method parent() should return a parent of the index.
Still, as this example focuses on data without parent indices, we override the method and
return an empty QtModelIndex(). As the methods are called from QML, the execution occurs in
the Qt qtMainLoopThread thread context.
\snippet android/models/qtabstractitemmodel_java/app/src/main/java/com/example/qtabstractitemmodel_java/MyDataModel.java 3
The example overrides the \l QAbstractItemModel::setData()
method, which is called when model's data at \c index is set from the QML
side of the application.
\snippet android/models/qtabstractitemmodel_java/app/src/main/java/com/example/qtabstractitemmodel_java/MyDataModel.java 4
The example implements methods on the model side for \c MainActivity UI interaction to add
and remove rows and columns. Calls begin, end, insert, and remove rows to update model
indexes, like beginInsertRow().
Because the example uses the \l QtAbstractItemModel, it must call beginInsertRows() and
endInsertRows() every time it inserts new rows into the model. The same applies to removal.
As the methods are called from the Android side, the execution takes place in the Android
main thread context.
\snippet android/models/qtabstractitemmodel_java/app/src/main/java/com/example/qtabstractitemmodel_java/MyDataModel.java 5
The example implements methods on the model side for \c MainActivity UI interaction to add
and remove columns. Calls begin, end, insert, and remove columns to update model indexes,
like beginRemoveColumn(). The same context awareness applies as with the add and remove row
methods.
\snippet android/models/qtabstractitemmodel_java/app/src/main/java/com/example/qtabstractitemmodel_java/MyDataModel.java 6
\section2 Main Activity
\c MainActivity implements the \l QtQmlStatusChangeListener interface to get status updates
when the QML is loaded. It is also the main Android activity.
The example creates and initializes the data model. See also
\l {QtQuickView}
\snippet android/models/qtabstractitemmodel_java/app/src/main/java/com/example/qtabstractitemmodel_java/MainActivity.java 1
The example sets the UI button and its listeners to allow the users to interact with the
model via the UI.
\snippet android/models/qtabstractitemmodel_java/app/src/main/java/com/example/qtabstractitemmodel_java/MyDataModel.java 2
The example starts loading the QML content. Loading happens in the background until the
\c ready status is updated.
\snippet android/models/qtabstractitemmodel_java/app/src/main/java/com/example/qtabstractitemmodel_java/MyDataModel.java 3
The example sets the data model when the QML content is loaded, and the status is ready.
\snippet android/models/qtabstractitemmodel_java/app/src/main/java/com/example/qtabstractitemmodel_java/MyDataModel.java 4
*/