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

Lorsque vous disposez d’ensembles de données volumineux, voire infinis, vous devrez ajouter des éléments au modèle par lots, et de préférence uniquement lorsque la vue en a besoin (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 disposons également de « Window », qui configure l'interface graphique et alimente le modèle avec des répertoires.
L’interface utilisateur se compose d’une boîte de dialogue comportant une liste affichant le contenu du répertoire racine. Il est possible de naviguer dans les répertoires par double-clic.
En bas de l'écran, une fenêtre de journal affiche des messages lorsque la vue demande des données supplémentaires au modèle.
Pour tester cette fonctionnalité, accédez à un répertoire volumineux (par exemple /bin) et faites défiler la page jusqu'en bas. Des messages de journalisation s'affichent, indiquant les données en cours de récupération.
Examinons le code de FileListModel.
Définition de la classe FileListModel
La classe FileListModel hérite de QAbstractListModel et contient le contenu d’un répertoire. Elle n’ajoutera des éléments à sa liste que lorsque la vue le lui demandera.
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 des méthodes ` fetchMore()` et ` canFetchMore()` issues de ` QAbstractItemModel`. Ces fonctions sont appelées par la vue « item » lorsqu’elle a besoin de nouveaux éléments.
La fonction setDirPath() définit le répertoire sur lequel le modèle va travailler. Nous appelons numberPopulated() chaque fois que nous ajoutons un lot d’éléments au modèle.
Nous conservons toutes les entrées de répertoire dans ` fileList`. ` fileCount ` correspond au nombre d’éléments qui ont été ajoutés au modèle.
Implémentation de la classe FileListModel
Nous commençons par extraire le répertoire 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 un objet ` QDir ` pour récupérer le contenu du répertoire. Nous devons indiquer à ` QAbstractItemModel ` que nous souhaitons supprimer tous les éléments (le cas échéant) 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 de nouveaux éléments. Nous renvoyons `true` s’il reste des entrées que nous n’avons pas encore ajoutées au modèle ; sinon, nous renvoyons `false`.
Et voici 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. Les méthodes ` beginInsertRows()` et ` endInsertRows()` sont obligatoires pour que ` QAbstractItemModel ` puisse suivre le rythme des insertions de lignes. Enfin, nous émettons ` numberPopulated()`, qui est récupéré par ` Window`.
Pour compléter cette présentation, 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, c’est-à-dire qu’il ne s’agit pas du nombre d’entrées dans le répertoire.
Dans data(), nous renvoyons l’entrée appropriée provenant de fileList. Nous distinguons également les lots à l’aide d’une couleur de fond 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.