Qt中怎么通过自定义表头实现过滤功能-创新互联

Qt中怎么通过自定义表头实现过滤功能,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:空间域名、网络空间、营销软件、网站建设、朔城网站维护、网站推广。

1)hover状态在鼠标移动事件中实现

void CFilterHeaderView::mouseMoveEvent(QMouseEvent *e){  m_hover = logicalIndexAt(e->pos());  if (m_hover != -1)    updateSection(m_hover);  QHeaderView::mouseMoveEvent(e);}bool CFilterHeaderView::event(QEvent *e){  switch(e->type())  {  case QEvent::Leave:  case QEvent::HoverLeave:    if (m_hover != -1)      updateSection(m_hover);    m_hover = -1;    break;  default:    break;  }  return QHeaderView::event(e);}

如果悬浮在某一列上,hover值等于该列的index,否则等于-1。如果hover值不等于-1,则刷新该列(updateSection)。

mouseMoveEvent中检测鼠标悬浮在那个表格列上。event函数中监听Leave和HoverLeave事件。

2)press状态在鼠标点击事件中实现

void CFilterHeaderView::mousePressEvent(QMouseEvent *e){  m_press = logicalIndexAt(e->pos());  if (m_press != -1)    updateSection(m_press);  QHeaderView::mousePressEvent(e);}void CFilterHeaderView::mouseReleaseEvent(QMouseEvent *e){  m_press = -1;  QHeaderView::mouseReleaseEvent(e);}

press的实现较为简单,鼠标点击更新press,鼠标释放press置为-1。

3)过滤提示的实现。

过滤提示在paintSection函数中实现,首先是调用基类paintSection实现表头的绘制,然后是检测有没有定义过滤角色。如果有定义过滤角色,则根据三态选择对应的图标,绘制位置默认水平靠右垂直居住,也可以自己指定位置。最后是绘制过滤提示。具体实现如下:

void CFilterHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const{  painter->save();  QHeaderView::paintSection(painter, rect, logicalIndex);  painter->restore();  QVariant filterVar = model()->headerData(logicalIndex, orientation(), FilterRole);  if (filterVar.isValid() && filterVar.toBool())  {    QPixmap pix = m_norFilterPix;    bool b_contain = getFilterRect(rect).contains(cursor().pos());    if (logicalIndex == m_hover && b_contain)    {      pix = m_hovFilterPix;    }    if (logicalIndex == m_press && b_contain)    {      pix = m_preFilterPix;    }    int align = Qt::AlignRight | Qt::AlignVCenter;    QVariant alignVar = model()->headerData(logicalIndex, orientation(), FilterAlignmentRole);    if (alignVar.isValid())    {      align = alignVar.toInt();    }    style()->drawItemPixmap(painter, rect, align, pix);  }}

表格绘制的区域和过滤提示绘制的区域不一致,要根据过滤图标大小进行计算过滤提示的区域。只有当鼠标在过滤区域位置上方,hover和press才有效,否则仍然是normal状态。过滤区域绘制的位置可以从外面获取,也可以使用默认位置。最后style()->drawItemPixmap进行绘制。

调用基类paintSection方法前后调用QPainter::save()和QPainter::restore()是必要的。如果不调用,style()->drawItemPixmap是不会起作用的。

4)过滤提示点击信号

点击过滤提示会发出信号,连接此信号可以进行过滤功能的实现。具体实现如下:

void CFilterHeaderView::mouseReleaseEvent(QMouseEvent *e){  if (e->button() == Qt::LeftButton)  {    int section = logicalIndexAt(e->pos());    QVariant filterVar = model()->headerData(section, orientation(), FilterRole);    if (filterVar.isValid() && filterVar.toBool())    {      QRect rect(sectionViewportPosition(section), 0, sectionSize(section), height());      if (getFilterRect(rect).contains(cursor().pos()))      {        emit filterClicked(section);      }    }  }  QHeaderView::mouseReleaseEvent(e);}

过滤信号发出的条件:1. 左键点击,2. 定义了过滤功能,3. 鼠标在过滤提示区域中

3. 使用过滤功能

使用过滤表头的方法如下:

m_tableView = new QTableView(this);  m_model = new QStandardItemModel(this);  m_filterModel = new QSortFilterProxyModel(this);  m_filterModel->setSourceModel(m_model);  m_filterModel->setSortRole(Qt::ToolTipRole);  m_tableView->setModel(m_filterModel);  QHBoxLayout* mainLayout = new QHBoxLayout(this);  mainLayout->setMargin(0);  mainLayout->addWidget(m_tableView);  setLayout(mainLayout);  m_tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);  m_tableView->setSelectionMode(QAbstractItemView::SingleSelection);  m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows);  m_tableView->verticalHeader()->hide();  CFilterHeaderView* pHeader = new CFilterHeaderView(this);  connect(pHeader, &CFilterHeaderView::filterClicked, this, &Widget::onFilterClicked);  m_tableView->setHorizontalHeader(pHeader);

使用过滤表头和使用普通表头没有太大的差别。这里过滤功能有QSortFilterProxyModel实现,水平表头替换成自定义的CFilterHeaderView。

关于Qt中怎么通过自定义表头实现过滤功能问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注创新互联行业资讯频道了解更多相关知识。


文章名称:Qt中怎么通过自定义表头实现过滤功能-创新互联
当前URL:http://scyanting.com/article/ddgdco.html