QtableWidget设置表头点击事件,显示筛选框,实现类似excel的表头筛选功能;
通过重写eventFilter事件过滤方法,获取鼠标点击的事件(含点击表格的空白处)

效果图

Widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTableWidget>
#include <QToolButton>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QEvent>#include "FilterWidget.h"
class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = 0);~Widget();//初始化void Init();//插入测试数据void InsertDatas();//筛选void filter(int col, QStringList showList);//关闭筛选框void closeFilterWidget();//事件过滤bool eventFilter(QObject *obj, QEvent *e);//初始化mapvoid initMap();private slots://表头点击槽函数void onHeaderClicked(int);private:QTableWidget *m_tableWidget = nullptr;//筛选框FilterWidget* m_filterWidget = nullptr;//列号,显示的元素QMap<int, QStringList> m_map;};#endif // WIDGET_H

Widget.cpp

#include "widget.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QRadioButton>
#include <QMessageBox>
#include <QSet>
#include <QMouseEvent>#pragma execution_character_set("utf-8")Widget::Widget(QWidget *parent): QWidget(parent)
{//初始化Init();//插入测试数据InsertDatas();QVBoxLayout* lay = new QVBoxLayout(this);lay->setMargin(0);lay->setSpacing(0);setLayout(lay);lay->addWidget(m_tableWidget);//注册事件过滤m_tableWidget->viewport()->installEventFilter(this);
}Widget::~Widget()
{if (m_filterWidget != nullptr){delete m_filterWidget;m_filterWidget = nullptr;}
}//初始化表格
void Widget::Init()
{m_tableWidget = new QTableWidget(this);//表头字体居中m_tableWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignHCenter);//自适应宽度m_tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);//使行列头自适应宽度,最后一列将会填充空白部分m_tableWidget->horizontalHeader()->setStretchLastSection(true);//设置行选中m_tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);//选中多行,可以使用shift,ctrl//SingleSelection-单选//MultiSelection-多选//ExtendedSelection-支持shift,ctrl和Ctr+A操作m_tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);//禁止编辑m_tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);//隐藏垂直表头//m_tableWidget->verticalHeader()->hide();m_tableWidget->setColumnWidth(0, 150);m_tableWidget->setColumnWidth(1, 80);m_tableWidget->setColumnWidth(2, 80);m_tableWidget->setColumnWidth(3, 250);m_tableWidget->setColumnWidth(4, 50);QStringList headerLabels;headerLabels << QString("列1") << QString("列2") << QString("列3") << QString("列4") << QString("列5");m_tableWidget->setColumnCount(headerLabels.size());m_tableWidget->setHorizontalHeaderLabels(headerLabels);//表头点击connect(m_tableWidget->horizontalHeader(), SIGNAL(sectionClicked(int)),this, SLOT(onHeaderClicked(int)));
}//插入测试数据
void Widget::InsertDatas()
{for (int i = 0; i < 2; i++){int row = m_tableWidget->rowCount();m_tableWidget->insertRow(row);m_tableWidget->setItem(row, 0, new QTableWidgetItem(QString("1")));m_tableWidget->setItem(row, 1, new QTableWidgetItem(QString("1")));m_tableWidget->setItem(row, 2, new QTableWidgetItem(QString("1")));m_tableWidget->setItem(row, 3, new QTableWidgetItem(QString("1")));m_tableWidget->setItem(row, 4, new QTableWidgetItem(QString("1")));}for (int i = 0; i < 2; i++){int row = m_tableWidget->rowCount();m_tableWidget->insertRow(row);m_tableWidget->setItem(row, 0, new QTableWidgetItem(QString("2")));m_tableWidget->setItem(row, 1, new QTableWidgetItem(QString("2")));m_tableWidget->setItem(row, 2, new QTableWidgetItem(QString("2")));m_tableWidget->setItem(row, 3, new QTableWidgetItem(QString("2")));m_tableWidget->setItem(row, 4, new QTableWidgetItem(QString("2")));}for (int i = 0; i < 2; i++){int row = m_tableWidget->rowCount();m_tableWidget->insertRow(row);m_tableWidget->setItem(row, 0, new QTableWidgetItem(QString("1")));m_tableWidget->setItem(row, 1, new QTableWidgetItem(QString("3")));m_tableWidget->setItem(row, 2, new QTableWidgetItem(QString("3")));m_tableWidget->setItem(row, 3, new QTableWidgetItem(QString("3")));m_tableWidget->setItem(row, 4, new QTableWidgetItem(QString("2")));}//初始化mapinitMap();
}//初始化map
void Widget::initMap()
{for (int col = 0; col < m_tableWidget->columnCount(); col++){QStringList strList;for (int row = 0; row < m_tableWidget->rowCount(); row++){QString   strItem = m_tableWidget->item(row, col)->text();strList.append(strItem);}m_map[col] = strList;}
}//筛选
void Widget::filter(int col, QStringList showList)
{m_map[col] = showList;for (int i = 0; i < m_tableWidget->rowCount(); i++){bool hidden = false;//遍历mapfor each (int  v_col in m_map.keys()){QString strItem = m_tableWidget->item(i, v_col)->text();if (!m_map.value(v_col).contains(strItem)){hidden = true;break;}}m_tableWidget->setRowHidden(i, hidden);}
}//表头点击槽函数
void Widget::onHeaderClicked(int col)
{//所有itemQSet<QString> items;//显示的itemQSet<QString> showItems;//行数int rows = m_tableWidget->rowCount();//遍历列表for (int i = 0; i < rows; i++){QString strItem = m_tableWidget->item(i, col)->text();items.insert(strItem);if (m_map.value(col).contains(strItem)){showItems.insert(strItem);}}//转为QStringListQStringList strItems;QStringList strShowItems;for each (QString var in items){strItems.append(var);}for each (QString var in showItems){strShowItems.append(var);}//关闭筛选框closeFilterWidget();//新建筛选框m_filterWidget = new FilterWidget(strItems, strShowItems, col, m_tableWidget);m_filterWidget->exec(m_tableWidget->mapFromGlobal(cursor().pos()));
}//事件过滤
bool Widget::eventFilter(QObject *target, QEvent *event)
{QMouseEvent *e = static_cast<QMouseEvent *>(event);if (e == nullptr){return QWidget::eventFilter(target, event);}if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease){closeFilterWidget();}return QWidget::eventFilter(target, event);
}//关闭筛选框
void Widget::closeFilterWidget()
{//清空筛选框if (m_filterWidget != nullptr){QStringList showList = m_filterWidget->getShowList();filter(m_filterWidget->getColumn(), showList);delete m_filterWidget;m_filterWidget = nullptr;}
}

FilterWidget.h

#pragma once
#include <QWidget>
#include <QListWidget>
#include <QListWidgetItem>
#include <QList>
#include <QCheckBox>
#include <QSet>class FilterWidget :public QWidget
{public:FilterWidget(QStringList Items, QStringList showItems, int col, QWidget *parent = 0);~FilterWidget();//获取要显示的列表QStringList getShowList();//获取列号int getColumn();//显示void exec(const QPoint &pos);private slots://勾选状态更改void slot_stateChanged();private:QListWidget* m_ListWidget = nullptr;//要显示的项QStringList m_showList;//列号int m_col;
};

FilterWidget.cpp

#include "FilterWidget.h"#include <QVBoxLayout>
#include <QEventLoop>//Items:所有项
//showItems:显示的项
//col:列号
FilterWidget::FilterWidget(QStringList Items, QStringList showItems, int col, QWidget *parent/*=0*/):QWidget(parent),m_col(col)
{this->setFixedWidth(50);this->setFixedHeight(100);m_ListWidget = new QListWidget(this);QVBoxLayout* lay = new QVBoxLayout(this);lay->setMargin(0);lay->setSpacing(0);setLayout(lay);for each (QString var in Items){QCheckBox* checkBox = new QCheckBox(this);checkBox->setText(var);if (showItems.contains(var)){m_showList.append(var);checkBox->setChecked(true);}connect(checkBox, &QCheckBox::stateChanged, this, &FilterWidget::slot_stateChanged);QListWidgetItem *item = new QListWidgetItem();m_ListWidget->addItem(item);m_ListWidget->setItemWidget(item,checkBox);}lay->addWidget(m_ListWidget);}FilterWidget::~FilterWidget()
{}QStringList FilterWidget::getShowList()
{return m_showList;
}int FilterWidget::getColumn()
{return m_col;
}void FilterWidget::exec(const QPoint & pos)
{setAttribute(Qt::WA_ShowModal, true);move(pos);show();QRect rect = geometry();QEventLoop loop;loop.exec();
}void FilterWidget::slot_stateChanged()
{m_showList.clear();//遍历for (int i = 0; i < m_ListWidget->count(); i++){//先获取QListWidgetItemQListWidgetItem *item = m_ListWidget->item(i);//找到第i个Item对应的CheckBoxQCheckBox *checkBox = static_cast<QCheckBox *>(m_ListWidget->itemWidget(item));if (checkBox->isChecked())m_showList.append(checkBox->text());}
}

示例工程

QTableWidget设置表头筛选(含鼠标点击事件过滤)相关推荐

  1. 关于“QTableWidget设置表头筛选”实现及小改——“QTableWidget设置表头筛选”引用自博主“~南柯一梦~”

    刚开始学习QT,项目要求数据有筛选功能,找到博主"~南柯一梦~"的"QTableWidget设置表头筛选"文章,感觉刚好合用就尝试了下.我先使用的QT5.12版 ...

  2. QTableWidget 设置表头颜色

    QTableWidget 设置表头颜色 方法1: setStyleSheet( "QHeaderView::section {background-color: qlineargradien ...

  3. 【Qt串口调试助手】1.3 - 重写ComboBox下拉框的鼠标点击事件,实现点击下拉框扫描可用串口

    由于ComboBox没有鼠标点击信号,所以如果想实现点击下拉框响应,需要重写ComboBox下拉框的鼠标点击事件.在点击事件中,添加扫描可用串口代码,实现点击下拉框时重新扫描串口.并且下拉框内容输出端 ...

  4. QT之鼠标点击事件学习

    最近在学习点击鼠标事件,在这分享给大家 window.h中的配置 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow& ...

  5. java鼠标点击事件_Java 鼠标点击事件实例

    首先我们应该知道鼠标点击事件怎么实现 其部分代码如下 if (anyEvent.getButton() == MouseEvent.BUTTON1) {} e.getButton()返回值分别为NOB ...

  6. java 鼠标点击按钮事件_Java 鼠标点击事件实例

    首先我们应该知道鼠标点击事件怎么实现 其部分代码如下 if (anyEvent.getButton() == MouseEvent.BUTTON1) {} e.getButton()返回值分别为NOB ...

  7. PyQt5 鼠标点击事件(点击响应事件可自定义):鼠标单击、双击、滚轮滚动、释放、移动等

    自己写通了最常用的鼠标事件,具体响应事件,大家可以自定义,实现的效果如下: 具体代码如下,有任何问题,欢迎小伙伴们交流讨论. # -*- coding: utf-8 -*- ""& ...

  8. 10,python中tkinter模块里的鼠标点击事件

    实践操作: from tkinter import * #鼠标点击事件的回调函数 def callback(event):print( "clicked at:", event.x ...

  9. 【虚幻引擎】UE4/UE5鼠标点击事件实现物体移动

    B站教学链接:https://space.bilibili.com/449549424?spm_id_from=333.1007.0.0 一.原理解析 在UE4/UE5中,引擎有它自己的一套框架体系, ...

最新文章

  1. JPA不同包下同类名查询出错
  2. LeanCloud学习笔记(1)
  3. php生成首页 教程,简单静态页生成 过程_PHP教程
  4. 天涯明夜刀手游微信第一服务器,天涯明月刀手游微信哪个区人多 微信一区选哪个好[多图]...
  5. mac 系统下 autoconf 安装
  6. 一个简单demo通过em实现‘响应式设计、em、文字图标svg’
  7. onvif协议之抓图
  8. es5 html片段拼接,es5的 reduce怎样用在拼接html字符串??? - 社区 - 妙味课堂
  9. 直播电商源码,无加密
  10. kafka_2.12-3.2.0安装包快速下载地址分享
  11. snmpwalk 命令_Snmpwalk命令行示例
  12. java基础实现一个基本的银行管理系统
  13. matlab中linspace函数
  14. 音频特效生成与算法 2
  15. CDR绘制抖音APP图标
  16. [球体积交]Girlfriend 2021牛客多校第2场 F
  17. ETL KETTLE 读取csv文件写入数据库
  18. python抓取抖音热门视频_要是30行代码!7步教会你Python爬取网页抖音热门视频
  19. 【调剂】苏州科技大学电子与信息工程学院2021年硕士研究生招生第二批调剂信息公告...
  20. Spark学习-入门介绍

热门文章

  1. 精选提高开发效率的20个idea插件
  2. can 串口 can 232 can 485 串口转CANbus总线网关模块CAN232/485MB转换器CANCOM
  3. 给刚入坑的ACMer一些编码建议(1)——使用“好”变量名
  4. MFAN通用企业网站后台管理系统源码模板
  5. 电动汽车单轮驱动防滑控制系统ASR
  6. oracle锁表后,系统能否自动解锁?
  7. mipi两线接口_MIPI CSI-2 接口标准
  8. 第十届蓝桥杯单片机省赛题目解析
  9. CNTK与深度强化学习笔记: Cart Pole游戏示例
  10. ubuntu下安装Qt操作流程