QTableView获取可见的行数

场景

当我们需要实时刷新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

相关推荐
彷徨而立几秒前
【C/C++】什么是 运行时库?运行时库 /MT 和 /MD 的区别?
c语言·c++
qq_417129252 分钟前
C++中的桥接模式变体
开发语言·c++·算法
clever10132 分钟前
在QtCreator 4.10.2中调试qt程序qDebug()输出中文为乱码问题的解决
开发语言·qt
No0d1es2 小时前
电子学会青少年软件编程(C语言)等级考试试卷(三级)2025年12月
c语言·c++·青少年编程·电子学会·三级
吕司2 小时前
Qt的信号与槽
开发语言·qt
bjxiaxueliang3 小时前
一文掌握C/C++命名规范:风格、规则与实践详解
c语言·开发语言·c++
xu_yule4 小时前
网络和Linux网络-13(高级IO+多路转接)五种IO模型+select编程
linux·网络·c++·select·i/o
2301_765703144 小时前
C++与自动驾驶系统
开发语言·c++·算法
轩情吖4 小时前
Qt的窗口(三)
c++·qt
热爱编程的小刘4 小时前
Lesson04---类与对象(下篇)
开发语言·c++·算法