티스토리 뷰
QAbstractListModel은 Qt 모델-뷰 프레임워크의 일부로, 리스트 형태의 데이터를 QML에서 사용할 수 있도록 제공하는 추상 클래스입니다. 이 클래스는 데이터를 리스트 형식으로 관리하고, 그 데이터를 뷰(view)에 표시할 때 기본이 되는 기능을 제공하며, 이를 상속받아 사용자 정의 모델을 구현할 수 있습니다.
QAbstractListModel은 특히 QML의 ListView, Repeater, GridView와 같은 UI 컴포넌트와 잘 결합하여 동적이고 반응적인 리스트를 생성할 때 유용합니다.
모델-뷰 구조
- 모델 (Model): 데이터를 관리하는 역할. QAbstractListModel은 이 역할을 수행합니다.
- 뷰 (View): 데이터를 시각적으로 표현하는 역할. 예를 들어 QML의 ListView는 모델의 데이터를 시각적으로 표시합니다.
QAbstractListModel을 사용하면 데이터를 관리하는 로직과 이를 시각적으로 표현하는 로직을 분리할 수 있어, 코드의 재사용성과 유지보수성이 크게 향상됩니다.
QAbstractListModel의 주요 기능
QAbstractListModel은 리스트 데이터를 쉽게 관리하고 QML과 연결할 수 있는 몇 가지 주요 메서드와 기능을 제공합니다.
핵심 메서드 및 멤버 함수
- rowCount(const QModelIndex &parent) const:
- 모델의 총 행(row)의 개수를 반환합니다.
- 뷰에서 모델의 데이터가 얼마나 있는지 알 수 있게 합니다.
- data(const QModelIndex &index, int role = Qt::DisplayRole) const:
- 특정 행의 데이터와 역할(roles)을 기반으로 데이터를 반환합니다.
- index는 행을 나타내며, role은 반환할 데이터의 종류를 지정합니다.
- roleNames() const:
- 사용자 정의 역할(roles)을 정의하여 QML에서 이 데이터를 참조할 수 있게 합니다.
- role은 데이터의 속성을 나타내며, QML에서는 이 이름을 통해 접근합니다.
- setData(const QModelIndex &index, const QVariant &value, int role) (선택적):
- 모델의 데이터를 수정하는 데 사용됩니다.
- 데이터가 변경되면 자동으로 UI에도 반영됩니다.
- insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) 및 removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) (선택적):
- 모델에 행을 추가하거나 제거할 때 사용됩니다.
QAbstractListModel을 상속하여 사용자 정의 모델 구현하기
다음 예제는 QAbstractListModel을 상속하여 간단한 사용자 정의 모델을 구현하고, 이를 QML에서 사용하는 방법을 보여줍니다.
#include <QAbstractListModel>
#include <QStringList>
class MyListModel : public QAbstractListModel {
Q_OBJECT
public:
enum Roles {
NameRole = Qt::UserRole + 1,
AgeRole
};
explicit MyListModel(QObject *parent = nullptr)
: QAbstractListModel(parent) {
// 초기 데이터를 설정
m_data.append({"Alice", 25});
m_data.append({"Bob", 30});
m_data.append({"Charlie", 22});
}
int rowCount(const QModelIndex &parent = QModelIndex()) const override {
Q_UNUSED(parent);
return m_data.count();
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {
if (index.row() < 0 || index.row() >= m_data.count())
return QVariant();
const Person &person = m_data[index.row()];
if (role == NameRole)
return person.name;
else if (role == AgeRole)
return person.age;
return QVariant();
}
QHash<int, QByteArray> roleNames() const override {
QHash<int, QByteArray> roles;
roles[NameRole] = "name";
roles[AgeRole] = "age";
return roles;
}
private:
struct Person {
QString name;
int age;
};
QList<Person> m_data;
};
설명
- MyListModel 클래스는 QAbstractListModel을 상속받아 구현된 사용자 정의 모델입니다.
- Roles 열거형은 QML에서 접근할 데이터의 역할을 정의합니다. Qt::UserRole + 1부터 사용하여 사용자 정의 역할을 설정합니다.
- rowCount(): 모델의 행 수를 반환합니다.
- data(): 특정 행의 데이터를 반환합니다. 여기서는 NameRole과 AgeRole을 통해 이름과 나이를 반환합니다.
- roleNames(): QML에서 사용할 수 있도록 역할의 이름을 정의합니다. 이 이름을 통해 QML에서 모델의 데이터를 참조할 수 있습니다.
QML에서 사용자 정의 모델 사용하기
이제 C++에서 정의한 모델을 QML에서 사용할 수 있습니다. 모델을 QML 컨텍스트에 등록하고, QML의 ListView를 통해 데이터를 시각화합니다.
C++에서 QML에 모델 등록:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "MyListModel.h"
int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
MyListModel model;
// QML 컨텍스트에 모델 등록
engine.rootContext()->setContextProperty("myModel", &model);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml:
import QtQuick 2.15
import QtQuick.Controls 2.15
ApplicationWindow {
visible: true
width: 640
height: 480
ListView {
anchors.fill: parent
model: myModel
delegate: Item {
height: 50
Row {
spacing: 10
Text { text: name } // roleNames에서 정의한 "name"
Text { text: age.toString() } // roleNames에서 정의한 "age"
}
}
}
}
설명
- model: myModel: C++에서 등록한 myModel을 사용하여 ListView의 모델로 지정합니다.
- delegate: 각 행의 데이터를 시각적으로 표현하는 데 사용됩니다. name과 age 역할을 통해 모델의 데이터를 참조합니다.
요약
- QAbstractListModel은 리스트 형태의 데이터를 관리하고, 이를 뷰와 연동하는 데 필요한 기능을 제공합니다.
- 이를 상속받아 사용자 정의 모델을 구현할 수 있으며, QML과 결합하여 반응적이고 동적인 UI를 쉽게 만들 수 있습니다.
- QML에서의 사용을 위해서는 역할(role)을 정의하고, 데이터를 QML에 등록하여 ListView 등과 연결하면 됩니다.
- 모델-뷰 구조를 사용하면 데이터와 UI 간의 분리를 통해 코드의 유지보수성과 확장성이 크게 향상됩니다.
QAbstractListModel을 사용한 C++과 QML의 결합은 복잡한 데이터를 효율적으로 관리하고 이를 직관적이고 아름다운 UI로 표현하는 데 매우 유용합니다.
개인적으로 학습하면서 정리한 내용입니다.
잘못된 내용이 있을 경우 알려주시면 확인 후 수정 및 반영하도록 하겠습니다.
오늘도 감사합니다.(__)
'개발 > QT, QML' 카테고리의 다른 글
QML의 ParallelAnimation (1) | 2024.11.11 |
---|---|
QML의 positionViewAtIndex 함수 (0) | 2024.11.10 |
[QT,QML] C++과 QML 간의 시그널-슬롯 통신 (0) | 2024.11.08 |
[QT,QML] QML의 Connections (2) | 2024.11.07 |
[QT,QML] Q_PROPERTY의 MEMBER 키워드 (5) | 2024.11.06 |