我要指出的是,列表模型不应该(而且也不应该)对用户操作一无所知,用户操作是由视图处理的。
假设我们有这样一个非常简单的模型:
#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();
}
};
如您所见,我添加了
scrolledToEnd
slot,当用户将视图滚动到末尾时调用。将向模型和
layoutChanged
发出信号以更新视图。插槽应该连接到由控制视图垂直滚动条的某个对象发出的信号。
那么,让我们布置一个
QTableView
在a中
QMainWindow
ui,并为窗口提供如下插槽和信号:
public slots:
void scrollValueChanged(int value);
signals:
void scrolledToEnd();
在窗口构造函数中,我们将视图模型设置为
Model
类别:
ui->setupUi(this);
Model * model = new Model();
ui->tableView->setModel(model);
然后连接
valueChanged
视图的信号
verticalScrollBar
到
scrollValueChanged
窗口插槽:
connect(ui->tableView->verticalScrollBar(), &QScrollBar::valueChanged, this, &MainWindow::scrollValueChanged);
以及
滚动结束
车窗信号至
滚动结束
型号插槽:
connect(this, &MainWindow::scrolledToEnd, model, &Model::scrolledToEnd);
在窗口插槽实现中,如果滚动条达到其最大值
滚动结束
发出信号:
void MainWindow::scrollValueChanged(int value)
{
if(value==ui->tableView->verticalScrollBar()->maximum())
{
emit scrolledToEnd();
}
}
该信号将被模型槽捕获,并将一组新的十个项目附加到模型上。