主要是重载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;
- else
- option.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模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓