场景
当我们需要实时刷新QTableView时,而此时tableView的数据量较大,如果全部刷新显然不合理,如果可以只对用户看的到的数据进行刷新那就最好了,经过一番摸索找到了几种方式,可供参考
代码
方法1
cpp
QVector<int> getVisibleRows(QTableView* tableView)
{
QVector<int> visibleRows;
int numRows = tableView->model()->rowCount();
//可见的第一行
int firstVisibleRow = tableView->rowAt(0);
if (firstVisibleRow != -1)
{
//可见的最后一行
int lastVisibleRow = tableView->rowAt(tableView->viewport()->height() - 1);
if (lastVisibleRow == -1)
{
lastVisibleRow = numRows - 1;
}
//遍历所有可见行
for (int row = firstVisibleRow; row <= lastVisibleRow; ++row)
{
visibleRows.append(row);
}
}
return visibleRows;
}
方法2
cpp
QVector<int> getVisibleRows2(QTableView* tableView)
{
QVector<int> visibleRows;
QAbstractItemModel* model = tableView->model();
QRect viewportRect = tableView->viewport()->rect();
int numRows = model->rowCount();
for (int row = 0; row < numRows; ++row)
{
QModelIndex index = model->index(row, 0);
QRect rowRect = tableView->visualRect(index);
if (rowRect.isValid() && viewportRect.intersects(rowRect))
{
visibleRows.append(row);
}
}
return visibleRows;
}
对比
现在来写一个main函数,简单测试一下哪种方法更有效率:
cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 创建一个QTableView并设置数据模型
QTableView* tableView = new QTableView;
QStandardItemModel model(10000, 2);
tableView->setModel(&model);
QPushButton* btnPrint = new QPushButton("GetRows");
QObject::connect(btnPrint, &QPushButton::clicked, [tableView]() {
// 获取可见行的索引
QElapsedTimer timer;
timer.start();
//第一种方式
QVector<int> visibleRows = getVisibleRows(tableView);
//第二种方式
QVector<int> visibleRows = getVisibleRows2(tableView);
qint64 elapsed = timer.elapsed(); // 获取经过的毫秒数
qDebug() << "Time elapsed:" << elapsed << "milliseconds";
qDebug() << "Visible Rows:";
for (int row : visibleRows)
qDebug() << row;
});
QVBoxLayout* mainLayout = new QVBoxLayout;
mainLayout->addWidget(tableView);
mainLayout->addWidget(btnPrint);
QWidget* mainWin = new QWidget;
mainWin->setLayout(mainLayout);
mainWin->show();
return a.exec();
}
我模拟了10000行的数据,两种方式下的耗时分别为
方法1:
方法2