怎么在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中通过自定义表头实现过滤功能
分享网址:http://scyanting.com/article/gphcsh.html