Auf dieser Seite

Bereitstellung von QtAbstractListModel für QML

Qt Quick Die Beispiele für die Android-API sind Android Studio-Projekte

Die Beispiele für die „ Qt Quick “ für die Android-API werden als Android Studio-Projekte bereitgestellt. Die Projektordner befinden sich in Ihrem Qt-Installationsverzeichnis.

Beispielsweise befinden sie sich unter dem Standard-Installationspfad für Windows hier:

C:\Qt\Examples\Qt-<patch-release-number>\platforms\android\<example-name>

Diese Projekte sind bereits für die Verwendung einer mit dieser Qt-Version kompatiblen Version des Qt-Gradle-Plugins konfiguriert.

Übersicht

Android-App mit einer ListView, die UUIDs und Zeilendaten anzeigt, sowie den Schaltflächen „Zeile hinzufügen“ und „Zeile entfernen“

Dieses Beispiel besteht aus zwei separaten Projekten: einem QML-Projekt und einem Kotlin-basierten Android-Projekt, das den QML-Inhalt hostet und anzeigt. Es zeigt, wie man mit QtAbstractListModel Daten von der Android-Seite an die QML-Ansicht überträgt, die die Daten mithilfe eines „ ListView “ anzeigt.

Ausführen des Beispiels

Um dieses Beispiel auszuführen, benötigen Sie Android Studio und eine Installation von Qt für Android.

Das Qt-Gradle-Plugin wird verwendet, um das QML-Projekt während des Build-Prozesses des Android-Projekts zu erstellen. Zu diesem Zweck enthält das Beispiel einige Plugin-Konfigurationen in der Datei „build.gradle.kts“ auf App-Ebene, die möglicherweise angepasst werden müssen, falls das Plugin beispielsweise das Qt-Kit-Verzeichnis nicht finden kann.

QtBuild {
    // Relative for Qt (Installer or MaintenanceTool) installations.
    qtPath = file("../../../../../../../6.12.0")
    projectPath = file("../../qtabstractlistmodel")
}

Weitere Informationen zur Konfiguration des Plugins finden Sie in der Dokumentation zum Qt-Gradle-Plugin.

QML-Projekt

Das QML-Projekt ist recht einfach: Es definiert ein Datenmodell als Eigenschaft des Root-Objekts sowie einige UI-Elemente zur Anzeige der Daten aus diesem Modell.

Rectangle {
    id: mainRectangle

    property AbstractItemModel dataModel

Zur Anzeige der Daten aus dem Modell wird ein ` ListView ` erstellt. Die Eigenschaft ` model ` wird dann auf das zuvor deklarierte Datenmodell gesetzt.

    ListView {
        id: listView

        model: mainRectangle.dataModel

Um das Datenmodell anzuzeigen, benötigt der „ ListView “ einen Delegaten, der für jedes Element im Datenmodell instanziiert wird. In diesem Fall handelt es sich bei dem Delegaten um einen „ Rectangle “, der zwei „ Text “-Elemente in einem „ Column “ enthält und die Daten aus jedem Element des Datenmodells anzeigt.

        delegate: Rectangle {
            required property var model

            width: listView.width
            height: textColumn.height + (2 * textColumn.spacing)
            color: "#2CDE85"
            radius: 25

            Column {
                id: textColumn

                height: idText.height + rowText.height + spacing
                spacing: 15

                anchors {
                    verticalCenter: parent.verticalCenter
                    left: parent.left
                    right: parent.right
                    leftMargin: 20
                    rightMargin: 20
                }

                Text {
                    id: idText

                    color: "#00414A"
                    text: model.id
                    font.pixelSize: 36
                    font.bold: true
                }

                Text {
                    id: rowText

                    color: "#00414A"
                    text: model.row
                    font.pixelSize: 36
                    font.bold: true
                }
            }
        }

Kotlin-Projekt

Die Android-Seite besteht aus einer einzigen Activity und der Definition für das zuvor in der QML-Ansicht verwendete Datenmodell.

Datenmodell

Das Datenmodell „ MyListModel “ ist eine Unterklasse von „QtAbstractListModel“, wobei „ ArrayList<String> “ als internes Speichersystem für die Daten dient. Im Initialisierungsblock von „ MyListModel “ werden einige Zufallsdaten für die Liste generiert.

class MyListModel : QtAbstractListModel() {
    private val m_dataList = ArrayList<String>()

    init {
        synchronized(this) {
            for (row in 0..4) {
                m_dataList.add(UUID.randomUUID().toString())
            }
        }
    }

Jedem Element im Modell ist eine Reihe von Datenelementen zugeordnet, von denen jedes eine eigene Rolle hat. Benutzerdefinierte Implementierungen von `QtAbstractItemModel` müssen für jedes Datenelement eine eigene Rolle definieren. Jede Rolle ist mit einem `Int` -Wert verknüpft, der beim Abrufen der Daten verwendet wird, sowie mit einem `String` -Wert, der den Namen des Datenelements angibt, wenn es aus QML heraus verwendet wird.

    @Synchronized
    override fun roleNames(): HashMap<Int, String> {
        val m_roles = HashMap<Int, String>()
        m_roles[DataRole.UUID.value()] = "id"
        m_roles[DataRole.Row.value()] = "row"
        return m_roles
    }

Während die Werte von „ Int “ in der Methode „ "roleNames()" “ fest codiert sein können, wird in diesem Beispiel eine benutzerdefinierte Enum-Klasse „ DataRole “ in „ MyListModel “ angegeben, die beim Verweisen auf diese Werte verwendet wird. In diesem Beispiel definieren wir zwei Rollen: „UUID“ und „Row“.

    private enum class DataRole(val m_value: Int) {
        UUID(0),
        Row(1);

        fun value(): Int {
            return m_value
        }

        companion object {
            fun valueOf(value: Int): DataRole? {
                val values = entries.toTypedArray()
                if (0 <= value && value < values.size) return values[value]
                return null
            }
        }
    }

Um Daten aus dem Datenmodell zurückzugeben, muss die Klasse die Methode ` "QtAbstractListModel::data()" ` überschreiben. Diese Methode nimmt zwei Parameter entgegen: `QtModelIndex` und ` Int`, die sich jeweils auf den Index und die Rolle des Datenelements beziehen.

In ` "MyDataModel::data()"` gibt die Rolle ` UUID ` die Daten vom angegebenen Index in den internen Daten zurück, während die Rolle ` Row ` die Zeile des angeforderten Elements zurückgibt.

Hinweis: Diese Methode ist, zusammen mit einigen anderen, mit einem @Synchronized-Tag versehen. Dies liegt daran, dass Aufrufe dieser Methoden vom Qt-Thread stammen und möglicherweise gleichzeitig mit Anfragen aus dem Android-Thread über die Methoden ` "addRow()" ` und ` "removeRow()" ` auf die zugrunde liegenden Daten zugreifen.

    @Synchronized
    override fun data(qtModelIndex: QtModelIndex, role: Int): Any {
        return when (DataRole.valueOf(role)) {
            DataRole.UUID -> "UUID: " + m_dataList[qtModelIndex.row()]
            DataRole.Row -> "Row: " + qtModelIndex.row()
            else -> ""
        }
    }

Um externen Akteuren die Bearbeitung des `QtAbstractItemModel` zu ermöglichen, fügt das Beispiel zwei zusätzliche Methoden zu ` MyDataModel` hinzu. Zum Hinzufügen von Daten zur Zeile dient die Methode ` "addRow()" `; zum Entfernen von Daten gibt es die Methode ` "removeRow()" `. Diese werden von der Hauptaktivität aus verwendet.

    @Synchronized
    fun addRow() {
        beginInsertRows(QtModelIndex(), m_dataList.size, m_dataList.size)
        m_dataList.add(UUID.randomUUID().toString())
        endInsertRows()
    }
    @Synchronized
    fun removeRow() {
        if (!m_dataList.isEmpty()) {
            beginRemoveRows(QtModelIndex(), m_dataList.size - 1, m_dataList.size - 1)
            m_dataList.removeAt(m_dataList.size - 1)
            endRemoveRows()
        }
    }

Hauptaktivität

Die Klasse ` MainActivity ` ist eine einfache, auf Kotlin basierende `Activity`, implementiert jedoch zusätzlich die Schnittstelle `QtQmlStatusChangeListener`, um Ereignisse zum Ladezustand von QML zu überwachen. Sie speichert außerdem das `QtQuickViewContent` -Objekt für die Hauptansicht der QML-Anwendung sowie eine Instanz des oben beschriebenen Datenmodells.

class MainActivity : AppCompatActivity(), QtQmlStatusChangeListener {
    private val m_mainQmlContent: Main = Main()
    private val m_listModel = MyListModel()

Beim Erstellen der Haupt-Activity der Anwendung erstellt das Beispiel zunächst eine `QtQuickView` und fügt sie in die Ansichts-Hierarchie ein.

        val qtQuickView: QtQuickView = QtQuickView(this)

        val params: ViewGroup.LayoutParams = FrameLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
        )
        val qmlFrameLayout: FrameLayout = findViewById<FrameLayout>(R.id.qmlFrame)
        qmlFrameLayout.addView(qtQuickView, params)

Nachdem die `QtQuickView` in die Benutzeroberfläche eingefügt wurde, ermittelt das Beispiel die Schaltflächen, die zur Bearbeitung des Datenmodells dienen, und richtet einige Klick-Listener ein, um die Methoden ` addRow() ` und ` removeRow() ` für das zugehörige Datenmodell aufzurufen.

        val addRowAtEndButton: Button = findViewById<Button>(R.id.addRow)
        val removeRowFromEndButton: Button = findViewById<Button>(R.id.removeRow)
        addRowAtEndButton.setOnClickListener { _: View? ->
            m_listModel.addRow()
        }
        removeRowFromEndButton.setOnClickListener { _: View? ->
            m_listModel.removeRow()
        }

Sobald die Einrichtung der Benutzeroberfläche und die Zuweisung der Listener abgeschlossen sind, kann die QML-Komponente vorbereitet und geladen werden. Das Beispiel legt „ MainActivity “ als Listener für das Signal „statuschange“ der QML-Komponente fest und weist QtQuickView an, die QML-Komponente zu laden.

        m_mainQmlContent.setStatusChangeListener(this)
        qtQuickView.loadContent(m_mainQmlContent)

Sobald die QML-Komponente erfolgreich geladen wurde, weist das Beispiel schließlich den Wert der Instanz „MyDataModel“ der Eigenschaft „ dataModel “ in der QML-Komponente zu.

    override fun onStatusChanged(qtQmlStatus: QtQmlStatus) {
        if (qtQmlStatus === QtQmlStatus.READY) {
            m_mainQmlContent.setDataModel(m_listModel)
        }
    }

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.