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

相关推荐
‘’林花谢了春红‘’3 小时前
C++ list (链表)容器
c++·链表·list
----云烟----3 小时前
QT中QString类的各种使用
开发语言·qt
机器视觉知识推荐、就业指导4 小时前
C++设计模式:建造者模式(Builder) 房屋建造案例
c++
Yang.996 小时前
基于Windows系统用C++做一个点名工具
c++·windows·sql·visual studio code·sqlite3
熬夜学编程的小王6 小时前
【初阶数据结构篇】双向链表的实现(赋源码)
数据结构·c++·链表·双向链表
zz40_6 小时前
C++自己写类 和 运算符重载函数
c++
六月的翅膀7 小时前
C++:实例访问静态成员函数和类访问静态成员函数有什么区别
开发语言·c++
liujjjiyun7 小时前
小R的随机播放顺序
数据结构·c++·算法
¥ 多多¥7 小时前
c++中mystring运算符重载
开发语言·c++·算法