Exemple Fetch More
L'exemple Fetch More montre comment ajouter des éléments à un modèle de vue à la demande.

Lorsque vous disposez d'ensembles de données volumineux, voire infinis, vous devez ajouter des éléments au modèle par lots et, de préférence, uniquement lorsque la vue a besoin de ces éléments (c'est-à-dire lorsqu'ils deviennent visibles dans la vue).
Dans cet exemple, nous implémentons FileListModel - un modèle de vue d'éléments contenant les entrées d'un répertoire. Nous avons également Window, qui met en place l'interface graphique et alimente le modèle avec des répertoires.
L'interface graphique consiste en une boîte de dialogue avec une liste montrant le contenu du répertoire racine. Les répertoires peuvent être parcourus en double-cliquant.
En bas, il y a une fenêtre de journal affichant les messages lorsque la vue demande au modèle plus de données.
Pour l'utiliser, naviguez jusqu'à un grand répertoire (par exemple /bin) et faites défiler jusqu'en bas. Des messages de journal s'affichent, indiquant les données récupérées.
Jetons un coup d'œil au code de FileListModel.
Définition de la classe FileListModel
La classe FileListModel hérite de la classe QAbstractListModel et contient le contenu d'un répertoire. Il ne s'ajoutera des éléments que si la vue le lui demande.
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; };
Le secret réside dans la réimplémentation de fetchMore() et canFetchMore() à partir de QAbstractItemModel. Ces fonctions sont appelées par la vue des éléments lorsqu'elle a besoin d'éléments supplémentaires.
La fonction setDirPath() définit le répertoire sur lequel le modèle travaillera. Nous émettons numberPopulated() chaque fois que nous ajoutons un lot d'éléments au modèle.
Nous conservons toutes les entrées du répertoire dans fileList. fileCount est le nombre d'éléments qui ont été ajoutés au modèle.
Mise en œuvre de la classe FileListModel
Nous commençons par consulter le site 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(); }
Nous utilisons une adresse QDir pour obtenir le contenu du répertoire. Nous devons informer QAbstractItemModel que nous voulons supprimer tous les éléments - s'il y en a - du modèle.
bool FileListModel::canFetchMore(const QModelIndex &parent) const { if (parent.isValid()) return false; return (fileCount < fileList.size()); }
La fonction canFetchMore() est appelée par la vue lorsqu'elle a besoin d'éléments supplémentaires. Nous renvoyons true s'il y a encore des entrées que nous n'avons pas ajoutées au modèle ; sinon, nous renvoyons false.
Et maintenant, la fonction fetchMore() elle-même :
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())); }
Nous calculons d'abord le nombre d'éléments à récupérer. beginInsertRows() et endInsertRows() sont obligatoires pour que QAbstractItemModel suive les insertions de lignes. Enfin, nous émettons numberPopulated(), qui est récupéré par Window.
Pour terminer la visite, nous examinons également rowCount() et 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 {}; }
Notez que le nombre de lignes correspond uniquement aux éléments que nous avons ajoutés jusqu'à présent, et non au nombre d'entrées du répertoire.
Dans data(), nous renvoyons l'entrée appropriée de fileList. Nous séparons également les lots avec une couleur d'arrière-plan différente.
© 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.