您好,登錄后才能下訂單哦!
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中怎么通過自定義表頭實現過濾功能問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。