国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C > 正文

Qt自定義表頭實現過濾功能的方法

2020-01-26 13:26:15
字體:
來源:轉載
供稿:網友

1. 寫在前面

過濾功能源自項目上交互優化用戶體驗,在表頭添加過濾符號實現過濾,替換以往在表格上方占用一行過濾項進行過濾。

2. 過濾提示

過濾提示就是三態圖標(normal,hover,press)。這三種狀態的實現通過鼠標移動事件和鼠標點擊事件來實現。具體實現如下:

  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。

4. 寫在最后

實現過濾表頭的原理如上所訴。具體完整的項目路徑參考如下地址:

https://github.com/zhugp125/QtDemo/tree/master/FilterHeaderView

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 临汾市| 吉隆县| 凉城县| 苗栗市| 门头沟区| 淮南市| 日喀则市| 正宁县| 收藏| 塔河县| 隆子县| 哈巴河县| 苗栗市| 蓬安县| 延津县| 辽宁省| 石首市| 睢宁县| 青龙| 合山市| 耒阳市| 沁源县| 含山县| 镇平县| 中阳县| 建平县| 威信县| 定州市| 广宗县| 沙田区| 万州区| 南召县| 鄂州市| 南汇区| 玛沁县| 固安县| 盖州市| 南涧| 南岸区| 鹰潭市| 太康县|