이 페이지에서

ListModel QML Type

자유 형식의 목록 데이터 소스를 정의합니다. 더 보기...

Import Statement: import QtQml.Models

속성

방법

  • void append(jsobject dict)
  • void clear()
  • var get(int index)
  • void insert(int index, jsobject dict)
  • void move(int from, int to, int n)
  • void remove(int index, int count)
  • void set(int index, jsobject dict)
  • void setProperty(int index, string property, var value)
  • void sync()

상세 설명

ListModel은 데이터 역할(data roles)을 각각 포함하는 리스트 모델( ListElement ) 정의들의 간단한 컨테이너입니다. 내용은 동적으로 정의하거나 QML에서 명시적으로 정의할 수 있습니다.

모델 내 요소의 개수는 count 속성을 통해 확인할 수 있습니다. 또한 모델의 내용을 조작하기 위해 append(), insert(), move(), remove(), set() 등 익숙한 여러 메서드가 제공됩니다. 이 메서드들은 인자로 사전(dictionary)을 받으며, 모델에 의해 이 사전은 ListElement 객체로 변환됩니다.

setProperty() 메서드를 사용하면 모델을 통해 요소를 조작할 수 있으며, 이를 통해 지정된 요소의 역할을 설정하고 변경할 수 있습니다.

ListModel은 QAbstractListModel 을 상속받으며, Q_INVOKABLE 메서드를 제공합니다. 예를 들어, QAbstractItemModel::index 를 사용하여 행과 열에 대한 QModelIndex 를 가져올 수 있습니다.

사용 예

다음 예제는 "name" 및 "cost"라는 역할을 가진 세 개의 요소를 포함하는 ListModel을 보여줍니다.

사과, 오렌지, 바나나와 가격을 나타낸 목록

import QtQuick

ListModel {
    id: fruitModel

    ListElement {
        name: "Apple"
        cost: 2.45
    }
    ListElement {
        name: "Orange"
        cost: 3.25
    }
    ListElement {
        name: "Banana"
        cost: 1.95
    }
}

각 요소의 역할(속성)은 소문자로 시작해야 하며, 모델 내 모든 요소에서 공통적으로 사용되어야 합니다. ListElement 문서에서는 요소 정의 방법에 대한 추가 지침을 제공합니다.

이 예제 모델에는 ` id ` 속성이 포함되어 있으므로, 이 예제의 ` ListView `와 같은 뷰에서 이를 참조할 수 있습니다:

import QtQuick

Rectangle {
    width: 200; height: 200

    ListModel {
        id: fruitModel
        ...
    }

    Component {
        id: fruitDelegate
        Row {
            spacing: 10
            Text { text: name }
            Text { text: '$' + cost }
        }
    }

    ListView {
        anchors.fill: parent
        model: fruitModel
        delegate: fruitDelegate
    }
}

역할(role)에는 목록 데이터가 포함될 수 있습니다. 다음 예제에서는 과일 속성 목록을 생성합니다:

ListModel {
    id: fruitModel

    ListElement {
        name: "Apple"
        cost: 2.45
        attributes: [
            ListElement { description: "Core" },
            ListElement { description: "Deciduous" }
        ]
    }
    ListElement {
        name: "Orange"
        cost: 3.25
        attributes: [
            ListElement { description: "Citrus" }
        ]
    }
    ListElement {
        name: "Banana"
        cost: 1.95
        attributes: [
            ListElement { description: "Tropical" },
            ListElement { description: "Seedless" }
        ]
    }
}

이 델리게이트는 모든 과일 속성을 표시합니다:

중첩된 속성 데이터를 가진 과일을 나열한 목록

Component {
    id: fruitDelegate
    Item {
        width: 200; height: 50
        Text { id: nameField; text: name }
        Text { text: '$' + cost; anchors.left: nameField.right }
        Row {
            anchors.top: nameField.bottom
            spacing: 5
            Text { text: "Attributes:" }
            Repeater {
                model: attributes
                Text { text: description }
            }
        }
    }
}

목록 모델 수정

ListModel의 내용은 clear(), append(), set(), insert() 및 setProperty() 메서드를 사용하여 생성하고 수정할 수 있습니다. 예를 들면 다음과 같습니다:

    Component {
        id: fruitDelegate
        Item {
            width: 200; height: 50
            Text { text: name }
            Text { text: '$' + cost; anchors.right: parent.right }

            // Double the price when clicked.
            MouseArea {
                anchors.fill: parent
                onClicked: fruitModel.setProperty(index, "cost", cost * 2)
            }
        }
    }

동적으로 콘텐츠를 생성할 때, 사용 가능한 속성 집합은 일단 설정되면 변경할 수 없다는 점에 유의하십시오. 모델에 가장 먼저 추가된 속성만이 해당 모델에서 허용되는 속성입니다.

WorkerScript와 함께 스레드 기반 리스트 모델 사용하기

ListModel은 WorkerScript 와 함께 사용하여 여러 스레드에서 리스트 모델에 접근할 수 있습니다. 이는 리스트 수정이 동기식이며 시간이 다소 소요되는 경우에 유용합니다. 즉, 리스트 작업을 다른 스레드로 이동시켜 메인 GUI 스레드의 차단을 방지할 수 있습니다.

다음은 WorkerScript 를 사용하여 리스트 모델에 현재 시간을 주기적으로 추가하는 예제입니다:

        Timer {
            id: timer
            interval: 2000; repeat: true
            running: true
            triggeredOnStart: true

            onTriggered: {
                var msg = {'action': 'appendCurrentTime', 'model': listModel};
                worker.sendMessage(msg);
            }
        }

포함된 파일인 ` dataloader.mjs`은 다음과 같습니다:

WorkerScript.onMessage = function(msg) {
    if (msg.action == 'appendCurrentTime') {
        var data = {'time': new Date().toTimeString()};
        msg.model.append(data);
        msg.model.sync();   // updates the changes to the list
    }
}

메인 예제의 타이머는 ` WorkerScript::sendMessage()`를 호출하여 워커 스크립트에 메시지를 보냅니다. 이 메시지를 수신하면 ` dataloader.mjs`에서 ` WorkerScript.onMessage() `가 호출되며, 이 함수는 현재 시간을 리스트 모델에 추가합니다.

외부 스레드에서 sync()을 호출하는 점에 유의하십시오. sync()을 호출해야만 해당 스레드에서 리스트에 가한 변경 사항이 메인 스레드의 리스트 모델에 반영됩니다.

‘데이터 모델 ’ 및 Qt Qml.

속성 문서

count : int [read-only]

모델에 포함된 데이터 항목의 수.

dynamicRoles : bool

기본적으로 역할의 유형은 해당 역할이 처음 사용될 때 고정됩니다. 예를 들어, "data"라는 역할을 생성하고 여기에 숫자를 할당하면, 더 이상 "data" 역할에 문자열을 할당할 수 없습니다. 그러나 dynamicRoles 속성이 활성화되면, 특정 역할의 유형은 고정되지 않으며 요소마다 다를 수 있습니다.

dynamicRoles 속성은 ListModel 에 데이터가 추가되기 전에 설정되어야 하며, 메인 스레드에서 설정되어야 합니다.

ListElement 를 통해 정적으로 정의된 데이터를 가진 ListModel 에서는 dynamicRoles 속성을 활성화할 수 없습니다.

동적 역할이 활성화된 ListModel 을 사용하면 상당한 성능 저하가 발생합니다. 성능 저하의 정도는 플랫폼마다 다르지만, 일반적으로 정적 역할 유형을 사용할 때보다 4~6배 정도 느려집니다.

동적 역할 사용으로 인한 성능 저하로 인해, 동적 역할은 기본적으로 비활성화되어 있습니다.

메서드 문서

void append(jsobject dict)

dict 에 있는 값을 사용하여 목록 모델의 끝에 새로운 항목을 추가합니다.

fruitModel.append({"cost": 5.95, "name":"Pizza"})

set() 및 remove()도 참조하십시오 .

void clear()

모델에서 모든 내용을 삭제합니다. 특히, 이 작업은 get()를 사용하여 가져온 모든 객체를 무효화합니다.

append(), remove, get도 참조하십시오 .

var get(int index)

리스트 모델에서 index 위치에 있는 항목을 반환합니다. 이를 통해 JavaScript에서 해당 항목 데이터에 접근하거나 수정할 수 있습니다:

Component.onCompleted: {
    fruitModel.append({"cost": 5.95, "name":"Jackfruit"});
    console.log(fruitModel.get(0).cost);
    fruitModel.get(0).cost = 10.95;
}

index 는 목록의 요소여야 합니다.

반환된 객체의 속성 중 그 자체가 객체인 경우, 해당 속성도 모델이 되며, 이 get() 메서드를 사용하여 요소에 접근할 수 있습니다:

fruitModel.append(..., "attributes":
    [{"name":"spikes","value":"7mm"},
     {"name":"color","value":"green"}]);
fruitModel.get(0).attributes.get(1).value; // == "green"

경고: 반환된객체가 유효한 상태를 유지한다고 보장되지 않습니다. 따라서 속성 바인딩에 사용하거나, 원본 ListModel 이 수정되는 동안 데이터를 저장하는 용도로 사용해서는 안 됩니다.

append() 및 clear()도 참조하십시오 .

void insert(int index, jsobject dict)

index 위치에 dict 에 포함된 값을 가진 새 항목을 목록 모델에 추가합니다.

fruitModel.insert(2, {"cost": 5.95, "name":"Pizza"})

index 은 목록에 존재하는 항목이거나, 목록 끝을 한 칸 넘은 위치여야 합니다(append와 동일).

set() 및 append()도 참조하십시오 .

void move(int from, int to, int n)

n 의 항목을 from 한 칸씩 to 다른 한 칸씩 이동합니다.

from 및 to 범위는 반드시 존재해야 합니다. 예를 들어, 처음 3개의 항목을 목록의 끝으로 이동하려면:

fruitModel.move(0, fruitModel.count - 3, 3)

append()도 참조하십시오 .

void remove(int index, int count = 1)

모델에서 index 에 있는 count 개의 항목을 삭제합니다.

clear()도 참조하십시오 .

void set(int index, jsobject dict)

목록 모델의 index 에 있는 항목을 dict 에 있는 값으로 변경합니다. dict 에 나타나지 않는 속성은 변경되지 않습니다.

fruitModel.set(3, {"cost": 5.95, "name":"Pizza"})

index 가 count()와 같을 경우, 리스트에 새로운 항목이 추가됩니다. 그렇지 않은 경우, index 는 리스트의 요소여야 합니다.

append()도 참조하십시오 .

void setProperty(int index, string property, var value)

목록 모델 내 index 에 있는 항목의 ` property `를 value 로 변경합니다.

fruitModel.setProperty(3, "cost", 5.95)

index 는 목록에 포함된 항목이어야 합니다.

append()도 참조하십시오 .

void sync()

워커 스크립트에서 목록 모델이 수정된 후, 저장되지 않은 변경 사항을 목록 모델에 기록합니다.

© 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.