本文主要用于记录,方便后续工作
高亮效果如下:筛选“的”

- 总结QTableView常用属性设置:
m_ptableview->verticalHeader()->setHidden(true); // 隐藏横向表头
m_ptableview->horizontalHeader()->setStretchLastSection(true); // 表头平铺
m_ptableview->setSelectionBehavior(QAbstractItemView::SelectRows); // 整行选中
m_ptableview->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); // 表头左侧对齐
m_ptableview->setTextElideMode(Qt::TextElideMode::ElideRight); // 设置省略模式为右侧省略
m_ptableview->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); //根据内容 自动调整行高
// Windows 10 下样式问题 添加表头的外侧线
m_ptableview->horizontalHeader()->setStyleSheet(
"QHeaderView::section{"
"border-top:0px solid rgb(218,218,218);"
"border-left:0px solid rgb(218,218,218);"
"border-right:1px solid rgb(218,218,218);"
"border-bottom:1px solid rgb(218,218,218);"
"background-color:rgb(240,240,240);"
"padding:1px;"
"}"
);
- 多列过滤(需自定义QSortFilterProxyModel 重写virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;)
#pragma once
#include <QSortFilterProxyModel>
class CustomSortFilterProxyModel : public QSortFilterProxyModel
{
public:
CustomSortFilterProxyModel(QObject *parent = nullptr);
~CustomSortFilterProxyModel();
virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
};
#include "CustomSortFilterProxyModel.h"
CustomSortFilterProxyModel::CustomSortFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent)
{
setDynamicSortFilter(true);
setFilterCaseSensitivity(Qt::CaseInsensitive);
}
CustomSortFilterProxyModel::~CustomSortFilterProxyModel()
{
}
bool CustomSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
{
//获取model中实际的数据
QString dataColumn0 = sourceModel()->index(source_row, 0, source_parent).data(Qt::DisplayRole).toString();
QString dataColumn1 = sourceModel()->index(source_row, 1, source_parent).data(Qt::DisplayRole).toString();
if (dataColumn0.contains(this->filterRegExp()))
{
return true;
}
else if (dataColumn1.contains(this->filterRegExp()))
{
return true;
}
return false;
}
.h
protected:
bool eventFilter(QObject* watched, QEvent* event);
private:
CusotmSortFilterProxyModel* m_proxyModel = nullptr;
.cpp
// 创建过滤器
m_proxyModel = new CusotmSortFilterProxyModel(this);
m_proxyModel->setSourceModel(m_pDataModel);
// 设置表格视图的模型为过滤器
m_ptableview->setModel(m_proxyModel);
bool ChatAuditWidget::eventFilter(QObject* watched, QEvent* event)
{
if (watched == m_pLineEdit)
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent* pKey = static_cast<QKeyEvent*>(event);
if (pKey->key() == Qt::Key_Return || pKey->key() == Qt::Key_Enter)
{
QString text = m_pLineEdit->text();
// 设置过滤规则
m_proxyModel->setFilterRegExp(QRegExp(text, Qt::CaseInsensitive, QRegExp::FixedString));
//m_proxyModel->setFilterKeyColumn(1); //单列过滤
}
}
}
return ChatAuditWidget::eventFilter(watched, event);
}
- 对筛选出来的包含筛选项的item进行背景标注(重写QStyledItemDelegate中void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;)
#pragma once
#include <QStyledItemDelegate>
class CustomItemDelegate : public QStyledItemDelegate
{
public:
CustomItemDelegate(const QColor& color, const QString& text, QObject* parent = nullptr);
~CustomItemDelegate();
void getFilterText(QString& filterText);
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
private:
QString m_FilterText;
};
#include "CustomItemDelegate.h"
#include <QPainter>
CustomItemDelegate::CustomItemDelegate(QObject* parent)
{
}
CustomItemDelegate::~CustomItemDelegate()
{
}
void CustomItemDelegate::getFilterText(QString& filterText)
{
m_FilterText = filterText;
}
void CustomItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
QString cellText = index.data(Qt::DisplayRole).toString();
// 使用默认样式绘制
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
QStyledItemDelegate::paint(painter, opt, index);
if (!m_FilterText.isEmpty())
{
if (cellText.contains(m_FilterText)) {
painter->save();
// 先覆盖原来的数据,防止重影
painter->fillRect(option.rect, Qt::white);
// 设置字体度量和文本颜色
QFontMetrics metrics(option.font);
painter->setPen(Qt::black);
//遍历每个匹配的位置 并绘制背景
int start = 0;
while ((start = cellText.indexOf(m_FilterText, start, Qt::CaseInsensitive)) != -1) {
// 计算匹配文本的左上角坐标
int xOffset = option.rect.left() + metrics.horizontalAdvance(cellText.left(start));
int yOffset = option.rect.top();
// 计算匹配文本的宽度和高度
double highlightwidth = metrics.horizontalAdvance(m_FilterText);
QRect highlightRect(xOffset + 2, yOffset, highlightwidth + 1, metrics.height() + 11);
// 绘制匹配文本的背景颜色
painter->fillRect(highlightRect, Qt::yellow);
// 更新开始位置以继续查找下一个匹配
start += m_FilterText.length();
}
// 绘制文本
painter->drawText(option.rect, option.displayAlignment, cellText);
painter->restore();
}
}
}
// 设置自定义代理
CustomItemDelegate* pDelegate = new CustomItemDelegate(Qt::yellow, text);
m_ptableview->setItemDelegate(pDelegate);
QString filterText = m_pLineEdit->text();
if (!filterText.isEmpty() && m_lastFilterText != filterText) {
// 不可去掉 防止在第一次筛选基础上继续筛选后的结果与上次结果相同导致tableView不会刷新
m_lastFilterText = filterText;
m_pDelegate->getFilterText(filterText);
}
else {
m_pDelegate->getFilterText(filterText);
}
1316

被折叠的 条评论
为什么被折叠?



