QTableView 多列过滤筛选 、以及对筛选后的index中的所匹配文字做高亮显示、表头排序及常用属性

本文主要用于记录,方便后续工作

高亮效果如下:筛选“的”

  • 总结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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值