자세히 가져오기 예제
더 가져오기 예는 필요에 따라 항목 뷰 모델에 항목을 추가하는 방법을 보여 줍니다.
데이터 집합이 크거나 심지어 무한대인 경우, 뷰에 항목이 필요할 때(즉, 뷰에 항목이 표시될 때) 모델에 항목을 일괄적으로 추가해야 합니다.
이 예에서는 디렉터리의 항목이 포함된 항목 보기 모델인 FileListModel
을 구현합니다. 또한 GUI를 설정하고 모델에 디렉터리를 공급하는 Window
도 있습니다.
UI는 루트 디렉터리의 내용을 보여주는 목록이 있는 대화 상자로 구성됩니다. 디렉토리는 두 번 클릭하여 탐색할 수 있습니다.
하단에는 뷰가 모델에 추가 데이터를 요청할 때 메시지를 표시하는 로그 창이 있습니다.
이를 실행하려면 큰 디렉터리(예: /bin
)로 이동하여 맨 아래로 스크롤합니다. 검색 중인 데이터를 보여주는 로그 메시지가 나타납니다.
FileListModel
의 코드를 살펴보겠습니다.
FileListModel 클래스 정의
FileListModel
은 QAbstractListModel 을 상속하며 디렉터리의 내용을 포함합니다. 뷰에서 요청할 때만 항목을 추가합니다.
class FileListModel : public QAbstractListModel { Q_OBJECT public: FileListModel(QObject *parent = nullptr); int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QFileInfo fileInfoAt(const QModelIndex &) const; signals: void numberPopulated(const QString &path, int start, int number, int total); public slots: void setDirPath(const QString &path); protected: bool canFetchMore(const QModelIndex &parent) const override; void fetchMore(const QModelIndex &parent) override; private: QFileInfoList fileList; QString path; QFileIconProvider iconProvider; int fileCount = 0; };
비밀은 QAbstractItemModel 에서 fetchMore() 및 canFetchMore()을 재구현한 것입니다. 이 함수는 항목 보기에서 항목이 더 필요할 때 호출됩니다.
setDirPath()
함수는 모델이 작업할 디렉터리를 설정합니다. 모델에 항목 배치를 추가할 때마다 numberPopulated()
함수를 호출합니다.
fileList
에 모든 디렉토리 항목을 보관합니다. fileCount
은 모델에 추가된 항목의 수입니다.
FileListModel 클래스 구현
먼저 setDirPath()
을 확인합니다.
void FileListModel::setDirPath(const QString &path) { QDir dir(path); beginResetModel(); this->path = path; fileList = dir.entryInfoList(QDir::NoDot | QDir::AllEntries, QDir::Name); fileCount = 0; endResetModel(); }
QDir 를 사용하여 디렉토리의 내용을 가져옵니다. 모델에서 모든 항목(있는 경우)을 제거할 것임을 QAbstractItemModel 에 알려야 합니다.
bool FileListModel::canFetchMore(const QModelIndex &parent) const { if (parent.isValid()) return false; return (fileCount < fileList.size()); }
canFetchMore()
함수는 항목이 더 필요할 때 뷰에서 호출됩니다. 모델에 추가하지 않은 항목이 여전히 있으면 참을 반환하고, 그렇지 않으면 거짓을 반환합니다.
이제 fetchMore()
함수 자체입니다:
void FileListModel::fetchMore(const QModelIndex &parent) { if (parent.isValid()) return; const int start = fileCount; const int remainder = int(fileList.size()) - start; const int itemsToFetch = qMin(batchSize, remainder); if (itemsToFetch <= 0) return; beginInsertRows(QModelIndex(), start, start + itemsToFetch - 1); fileCount += itemsToFetch; endInsertRows(); emit numberPopulated(path, start, itemsToFetch, int(fileList.size())); }
먼저 가져올 항목의 수를 계산합니다. beginInsertRows() 및 endInsertRows()는 QAbstractItemModel 이 행 삽입을 따라잡기 위해 필수입니다. 마지막으로 Window
에서 가져온 numberPopulated()
을 출력합니다.
투어를 완료하기 위해 rowCount()
와 data()
도 살펴봅니다.
int FileListModel::rowCount(const QModelIndex &parent) const { return parent.isValid() ? 0 : fileCount; } QVariant FileListModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return {}; const int row = index.row(); if (row >= fileList.size() || row < 0) return {}; switch (role) { case Qt::DisplayRole: return fileList.at(row).fileName(); case Qt::BackgroundRole: { const int batch = row / batchSize; const QPalette &palette = QGuiApplication::palette(); return (batch % 2) != 0 ? palette.alternateBase() : palette.base(); } case Qt::DecorationRole: return iconProvider.icon(fileList.at(row)); } return {}; }
행 수는 지금까지 추가한 항목 수일 뿐, 즉 디렉토리에 있는 항목 수가 아니라는 점에 유의하세요.
data()
에서 fileList
에서 적절한 항목을 반환합니다. 또한 다른 배경색으로 배치를 구분합니다.
© 2025 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.