当我们需要实时刷新QTableView时,而此时tableView的数据量较大,如果全部刷新显然不合理,如果可以只对用户看的到的数据进行刷新那就最好了,经过一番摸索找到了几种方式,可供参考
方法1
- 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
- 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函数,简单测试一下哪种方法更有效率:
- 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
