Beispiel „Fetch More“
Das Beispiel „Fetch More“ zeigt, wie Elemente bei Bedarf zu einem Element-View-Modell hinzugefügt werden.

Bei großen – oder vielleicht sogar unendlichen – Datensätzen müssen Sie Elemente schrittweise zum Modell hinzufügen, und zwar vorzugsweise erst dann, wenn sie von der Ansicht benötigt werden (d. h., wenn sie in der Ansicht sichtbar werden).
In diesem Beispiel implementieren wir „ FileListModel “ – ein Element-View-Modell, das die Einträge eines Verzeichnisses enthält. Außerdem gibt es „ Window “, das die Benutzeroberfläche einrichtet und das Modell mit Verzeichnissen versorgt.
Die Benutzeroberfläche besteht aus einem Dialogfeld mit einer Liste, die den Inhalt des Stammverzeichnisses anzeigt. Durch Doppelklick kann man durch die Verzeichnisse navigieren.
Unten befindet sich ein Protokollfenster, in dem Meldungen angezeigt werden, wenn die Ansicht weitere Daten vom Modell anfordert.
Um dies zu testen, navigieren Sie zu einem großen Verzeichnis (z. B. /bin) und scrollen Sie nach unten. Es erscheinen Protokollmeldungen, die die abgerufenen Daten anzeigen.
Werfen wir einen Blick auf den Code von FileListModel.
Definition der Klasse „FileListModel“
FileListModel erbt von ` QAbstractListModel ` und enthält den Inhalt eines Verzeichnisses. Es fügt sich selbst nur dann Elemente hinzu, wenn es von der Ansicht dazu aufgefordert wird.
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;
};Das Geheimnis liegt in der Neuimplementierung von ` fetchMore()` und ` canFetchMore()` aus ` QAbstractItemModel`. Diese Funktionen werden von der Elementansicht aufgerufen, wenn sie weitere Elemente benötigt.
Die Funktion ` setDirPath() ` legt das Verzeichnis fest, mit dem das Modell arbeiten soll. Wir rufen ` numberPopulated() ` jedes Mal auf, wenn wir dem Modell eine Reihe von Elementen hinzufügen.
Wir speichern alle Verzeichniseinträge in ` fileList`. ` fileCount ` ist die Anzahl der Elemente, die dem Modell hinzugefügt wurden.
Implementierung der Klasse „FileListModel“
Zunächst rufen wir das Verzeichnis „ setDirPath() “ ab.
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();
}Wir verwenden eine ` QDir `, um den Inhalt des Verzeichnisses abzurufen. Wir müssen ` QAbstractItemModel ` mitteilen, dass wir alle Elemente – sofern vorhanden – aus dem Modell entfernen möchten.
bool FileListModel::canFetchMore(const QModelIndex &parent) const
{
if (parent.isValid())
return false;
return (fileCount < fileList.size());
}Die Funktion ` canFetchMore() ` wird von der Ansicht aufgerufen, wenn sie weitere Elemente benötigt. Wir geben `true` zurück, wenn noch Einträge vorhanden sind, die wir dem Modell noch nicht hinzugefügt haben; andernfalls geben wir `false` zurück.
Und nun zur Funktion ` fetchMore() ` selbst:
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()));
}Zunächst berechnen wir die Anzahl der abzurufenden Elemente. „ beginInsertRows()“ und „ endInsertRows()“ sind für „ QAbstractItemModel “ zwingend erforderlich, um mit den Zeileneinfügungen Schritt zu halten. Schließlich geben wir „ numberPopulated() “ aus, das von „ Window “ abgefangen wird.
Um den Überblick zu vervollständigen, sehen wir uns außerdem rowCount() und data() an.
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 {};
}Beachten Sie, dass die Zeilenanzahl nur die bisher hinzugefügten Elemente umfasst, d. h. nicht die Anzahl der Einträge im Verzeichnis.
In data() geben wir den entsprechenden Eintrag aus fileList zurück. Außerdem heben wir die Batches durch unterschiedliche Hintergrundfarben hervor.
© 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.