I would point out that a list model should not (and it does not) know nothing about user actions, which are handled by the view.
Suppose we have a very simple model like this:
#include <QAbstractListModel>
class Model : public QAbstractListModel
{
Q_OBJECT
QStringList list;
public:
Model()
{
//adds 100 items
for(int i=0; i<100; i++)
list << QString("ITEM #") + QString::number(i+1);
}
int rowCount(const QModelIndex &parent) const
{
return list.size();
}
QVariant data(const QModelIndex &index, int role) const
{
if(index.isValid() && (role == Qt::DisplayRole))
{
int row = index.row();
if(row < list.size())
{
return list[row];
}
}
return QVariant();
}
public slots:
void scrolledToEnd()
{
//adds 10 more items
int count = list.size();
for(int i=count; i<(count + 10); i++)
list << QString("ITEM #") + QString::number(i+1);
emit layoutChanged();
}
};
As you can see, I added a scrolledToEnd
slot, to be called when the user scrolled the view to the end. Extra items are added to the model and the layoutChanged
signal is emitted to update the view. The slot is supposed to be connected to a signal which is emitted by some object who is in control of the view vertical scroll bar.
So, let's lay out a QTableView
in a QMainWindow
ui, and give the window a slot and a signal like these:
public slots:
void scrollValueChanged(int value);
signals:
void scrolledToEnd();
In the window constructor, we set the view model to a new instance of our Model
class:
ui->setupUi(this);
Model * model = new Model();
ui->tableView->setModel(model);
then connect the valueChanged
signal of the view's verticalScrollBar
to the scrollValueChanged
slot of the window:
connect(ui->tableView->verticalScrollBar(), &QScrollBar::valueChanged, this, &MainWindow::scrollValueChanged);
and the scrolledToEnd
signal of the window to the scrolledToEnd
slot of the model:
connect(this, &MainWindow::scrolledToEnd, model, &Model::scrolledToEnd);
In the window slot implementation, if the scroll bar reached its maximum value, the scrolledToEnd
signal is emitted:
void MainWindow::scrollValueChanged(int value)
{
if(value==ui->tableView->verticalScrollBar()->maximum())
{
emit scrolledToEnd();
}
}
The signal will be caught by the model slot, and a new set of ten items will be appended to the model.