主要是重载paintSection和mousePressEvent这两个函数
headview.h
#ifndef HEADERVIEW_H
#define HEADERVIEW_H#include
#include
#include
#include
#include #include class HeaderView : public QHeaderView
{Q_OBJECT
public://构造函数, 第一个参数设定表头方向HeaderView(Qt::Orientation orientation, QWidget* parent = 0);protected:void paintSection(QPainter* painter, const QRect& rect, int logicalIndex) const;void mousePressEvent(QMouseEvent* event);private://checkbox的开启或关闭状态bool isOn;
};#endif // HEADERVIEW_H
headerview.cpp
#include "headerview.h"HeaderView::HeaderView(Qt::Orientation orientation, QWidget* parent): QHeaderView(orientation, parent)
{}void HeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{painter->save();QHeaderView::paintSection(painter, rect, logicalIndex);painter->restore();if(logicalIndex == 0){QStyleOptionButton option;option.iconSize = QSize(10,10);option.rect = rect;if(isOn)option.state = QStyle::State_On;elseoption.state = QStyle::State_Off;this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);}
}void HeaderView::mousePressEvent(QMouseEvent *event)
{if (isOn) {isOn = false;} else {isOn = true;}this->viewport()->update();QHeaderView::mousePressEvent(event);
}
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓
这里的这个paintSection,是对每一段进行一个绘制。
logicalIndex == 0是代表是表头的第一列。
State_On和State_Off分别代表开关状态。
this->style()->drawPrimitive这个是一个用于绘画各种基本元素的函数,参考Styles Example | Qt Widgets 5.15.8,这个函数是QStyle类的一个纯虚函数,由其他继承自QStyle的子类去实现自己的样式。然后QStrle::PE_IndicatoeCheckBox代表画的是一个复选框。
mousePressEvent这是一个鼠标点击事件。
2. 重载updateGeometries
上面这种重载paintSection的方法,我自己使用之后,发现好像有点延迟,所以就找了另外一种方法,这种方法是直接设置位置,使用的是Qt自己的QCheckBox,反应好像更快了。
headview.h
#ifndef HEADERVIEW_H
#define HEADERVIEW_H#include
#include
#include
#include
#include class HeaderView : public QHeaderView
{Q_OBJECT
public://构造函数, 第一个参数设定表头方向HeaderView(Qt::Orientation orientation, QWidget* parent = 0);protected:void updateGeometries();signals:void checkStateChange(int state);public slots:void slot_setCheckState(Qt::CheckState state);private:QCheckBox* checkBox;
};#endif // HEADERVIEW_H
headerview.cpp
#include "headerview.h"HeaderView::HeaderView(Qt::Orientation orientation, QWidget* parent): QHeaderView(orientation, parent)
{checkBox = new QCheckBox("全选", this);checkBox->show();connect(checkBox, &QCheckBox::clicked, [this] () {emit checkStateChange(checkBox->checkState());});
}void HeaderView::updateGeometries()
{checkBox->move(sectionPosition(0) + 19, 6);
}void HeaderView::slot_setCheckState(Qt::CheckState state)
{checkBox->setCheckState(state);
}
最终效果如下图:

但是后面实际应用的时候,发现一个很严重的问题,那就是如果你使用updateGeometries的这种方式,当列太多,导致表格有水平方向的滚动条时,你往右拖动滚动条,就发现,这个复选框,也会一起跟过来,并且覆盖在第一列上。所以这种方式也是由有着局限性的
在我实际使用中,我使用第一种方法,但是我发现这种方法,我没有找到怎么去设置这个复选框的样式。所以我在这个基础上,进行了样式的改进:
改进后的代码如下:
painter->save();QHeaderView::paintSection(painter, rect, logicalIndex);painter->restore();if(logicalIndex == 0){QStyleOptionButton option;// 设置复选框图标的大小option.iconSize = QSize(16,16);// 设置复选框的文字option.text = "全选";// 设置复选框文字的颜色option.palette.setBrush(QPalette::WindowText, QColor(255, 255, 255));QFont font;font.setFamily("Microsoft YaHei");font.setPixelSize(14);// ???为啥这里option.setFontMetries就不行// ???为啥这里font.setColor没用// 设置复选框文字的大小painter->setFont(font);option.rect = QRect(rect.x()+19, rect.y(), rect.width(), rect.height());if(isOn) {option.state = QStyle::State_On;// 设置复选框的样式option.icon = QIcon(":/images/images/check.png");} else {option.state = QStyle::State_Off;option.icon = QIcon(":/images/images/uncheck.png");}this->style()->drawControl(QStyle::CE_CheckBoxLabel, &option, painter);}
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓