QtableWidget和QTableView实现选中行的冻结——scrollTo

QtableWidget和QTableView实现选中行的冻结

在Qt列表的使用过程中,有一个列表是按照时间先后顺序瀑布流一样的刷新列表。如果并发量过大,可能列表刷新速度很快,用户如果想点击某条事件查看详情,一瞬间就被刷到界面之外了。为了解决这个问题,需要用户点击时实现列表还是在刷新,但是页面中一直存在用户点击选项这样的功能。

一、目标

  1. 后台数据一直刷新。
  2. 用户点击列表某行数据后实现行的冻结,点击行一直存在在显示页面。
  3. 添加恢复的按钮,点击后列表随着数据的添加继续进行滚动。

二、实现过程

在Qt assistant中查看QtableWidget,发现了这样一个接口

void QTableWidget::scrollToItem(const QTableWidgetItem *item, QAbstractItemView::ScrollHint hint = EnsureVisible)
Scrolls the view if necessary to ensure that the item is visible. The hint parameter specifies more precisely where the item should be located after the operation.

翻译过来就是滚动视图确保item可见。第一个参数设定item,第二个参数设定item显示的位置,总共有三种,分别是top、center、和bottom。
在使用的过程中需要注意一点,就是每次刷新都要调用一次scrollToItem进行设定。因为每次添加或删除操作滚动条都会变化。
例子:

void Widget::on_beginBtn_clicked()//点击按钮添加行
{
    QTableWidgetItem *newItem = new QTableWidgetItem(tr("%1").arg(iRow));

    ui->tableWidget->insertRow(iRow);
    ui->tableWidget->setItem(iRow,0,newItem);
    ui->tableWidget->sortItems(0,Qt::DescendingOrder);
    if(NULL != clickItem)//此处判断点击的item并调用函数设定显示位置
    {
        ui->tableWidget->scrollToItem(clickItem,QAbstractItemView::PositionAtCenter);
    }
    iRow++;

}

但是后来发现我代码中使用的是QTableView,那么QtableWidget的这个函数就不能使用,不过转念一想,QtableWidget不是QTableView的子类吗?看下QtableWidget里面scrollToItem的实现估计就能找到QTableView的实现了。
查看QtableWidget里面scrollToItem的源码如下:

仔细看,里面真的有一个QTableView::scrollTo函数。如下所示:
void QTableView::scrollTo(const QModelIndex &index, ScrollHint hint)
具体的实现这里不贴了,想看的可以搜下源码,主要的实现就是通过QModelIndex的行和列的值对滚动条进行位移。

根据以上说明,在代码中实现的流程主要有两点:

  1. 通过QTableView的Clicked信号,获取当前选中的ModelIndex的位置。
  2. InsertItem的地方调用scrollTo设定位置的值。

不过在实现过程中发现,由于实现过程中有排序,选中的QModelIndex的row()值在InsertRow之后会有变化,所以需要根据要求更改选中的QModelIndex的行列值,具体修改的代码如下:

if (m_currentClickItem.isValid())
{	//如果添加item的position小于当前选中的row值,选中的row值+1
	if (iPosition < m_currentClickItem.row())
	{
		m_currentClickItem = m_currentClickItem.sibling(m_currentClickItem.row() + 1, m_currentClickItem.column());
	}
	ui->PassMsgTableView->scrollTo(m_currentClickItem, QAbstractItemView::PositionAtCenter);
}

到此,我们要实现的选中行的冻结功能就完成了。

三、总结

Qt感觉就是一个宝藏,很多东西他们都帮你想到并且实现了,不过还是要自己费点功夫去找寻,不管是google还是百度。同时,有机会可以看下源码,你会有意外的发现。

你可能感兴趣的:(qt)