Ejemplo de Fetch More
El ejemplo Fetch More muestra cómo añadir elementos a un modelo de vista de elementos bajo demanda.

Cuando se dispone de conjuntos de datos grandes, o incluso infinitos, es necesario añadir elementos al modelo por lotes y, preferiblemente, sólo cuando la vista los necesita (es decir, cuando se hacen visibles en la vista).
En este ejemplo, implementamos FileListModel - un modelo de vista de elementos que contiene las entradas de un directorio. También tenemos Window, que configura la GUI y alimenta el modelo con directorios.
La interfaz de usuario consiste en un diálogo con una lista que muestra el contenido del directorio raíz. Se puede navegar por los directorios haciendo doble clic.
En la parte inferior, hay una ventana de registro que muestra mensajes cuando la vista pide más datos al modelo.
Para utilizarla, vaya a un directorio grande (por ejemplo, /bin) y desplácese hasta el final. Aparecen mensajes de registro que muestran los datos que se están recuperando.
Hagamos un recorrido por el código de FileListModel.
Definición de la clase FileListModel
La clase FileListModel hereda de QAbstractListModel y contiene el contenido de un directorio. Añadirá elementos a sí mismo sólo cuando la vista se lo pida.
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; };
El secreto está en la reimplementación de fetchMore() y canFetchMore() a partir de QAbstractItemModel. Estas funciones son llamadas por la vista de elementos cuando necesita más elementos.
La función setDirPath() establece el directorio en el que trabajará el modelo. Emitimos numberPopulated() cada vez que añadimos un lote de elementos al modelo.
Mantenemos todas las entradas de directorio en fileList. fileCount es el número de elementos que se han añadido al modelo.
Implementación de la clase FileListModel
Comenzamos comprobando 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(); }
Utilizamos QDir para obtener el contenido del directorio. Necesitamos informar a QAbstractItemModel de que queremos eliminar todos los elementos -si los hay- del modelo.
bool FileListModel::canFetchMore(const QModelIndex &parent) const { if (parent.isValid()) return false; return (fileCount < fileList.size()); }
La función canFetchMore() es llamada por la vista cuando necesita más elementos. Devolvemos true si todavía hay entradas que no hemos añadido al modelo; en caso contrario, devolvemos false.
Y ahora, la función fetchMore() propiamente dicha:
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())); }
Primero calculamos el número de elementos que hay que recuperar. beginInsertRows() y endInsertRows() son obligatorias para que QAbstractItemModel siga el ritmo de las inserciones de filas. Por último, emitimos numberPopulated(), que es recogido por Window.
Para completar el recorrido, vemos también rowCount() y 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 {}; }
Fíjate en que el recuento de filas son sólo los elementos que hemos añadido hasta el momento, es decir, no el número de entradas del directorio.
En data(), devolvemos la entrada correspondiente de fileList. También separamos los lotes con un color de fondo diferente.
© 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.