Qt QHeaderView 添加复选框

news2024/12/22 0:08:37

有两种方法:

1. 重载paintSection

主要是重载paintSection和mousePressEvent这两个函数

headview.h

#ifndef HEADERVIEW_H
#define HEADERVIEW_H

#include <QObject>
#include <QHeaderView>
#include <QPainter>
#include <QCheckBox>
#include <QObject>

#include <QDebug>

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 <QObject>
#include <QHeaderView>
#include <QPainter>
#include <QCheckBox>
#include <QObject>

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);
}
  • 连接信号,当鼠标点击QCheckBox时,发射信号。
  • updateGeometries这个函数,就是移动QCheckBox

最终效果如下图:

 

但是后面实际应用的时候,发现一个很严重的问题,那就是如果你使用updateGeometries的这种方式,当列太多,导致表格有水平方向的滚动条时,你往右拖动滚动条,就发现,这个复选框,也会一起跟过来,并且覆盖在第一列上。所以这种方式也是由有着局限性的

在我实际使用中,我使用第一种方法,但是我发现这种方法,我没有找到怎么去设置这个复选框的样式。所以我在这个基础上,进行了样式的改进:

3.改进paintSection

改进后的代码如下:

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模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/32542.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

后端进阶知识 Buffer pool 图文详解 之 free链表

Buffer pool 图文详解 之 free 链表 前言数据页缓存页描述信息初始化 Buffer poolfree 链表获取空闲页数据页是否缓存可关注专栏 》MySQL 进阶知识 收藏点赞加关注 前言 Buffer pool 是 InnerDB 存储引擎的一个重要组件&#xff0c;MySQL 的所有 CRUD 操作都是围绕 Buffer poo…

MariaDB 数据文件 迁移

1. 需求 原MariaDB采用默认安装&#xff0c;安装在/所在的分区下&#xff0c;现在该服务器的磁盘空间不补足了&#xff0c;现在扩展插入了一块新的磁盘&#xff0c;并且挂载到了/www/目录下&#xff0c;现在需要将原来的数据库数据迁移至该目录下。 2. 查询数据存储目录 首先…

预测足球世界杯比赛

目录 1. 下载数据集 2. 数据预处理 3. 模型训练与选择 4. 预测 1. 下载数据集 下载后数据如下&#xff1a; FIFA World Cup | Kaggle 2. 数据预处理 reprocess_dataset() 方法是数据进行预处理。预处理过的数据如下&#xff1a; save_dataset() 方法是对预处理过的数据&…

LibreOJ_10010

链接 点此跳转 思路 题目描述 有 nnn 个小朋友坐成一圈&#xff0c;每人有 aia_iai​ 颗糖果。 每人只能给左右两人传递糖果。每人每次传递一颗糖果的代价为 111 。 求使所有人获得均等糖果的最小代价。 分析 设 xix_ixi​ 表示第 iii 个朋友向第 i−1i-1i−1 个小朋友…

爬虫与云服务器云数据库

腾讯云轻量应用服务器TDSQL-MYSQL数据库PYTHON做爬虫 实现目标&#xff1a;轻量应用服务器上运行Python爬虫&#xff0c;把数据写到TDSQL-MYSQL数据库中。 最近双十一&#xff0c;趁着这一波福利&#xff0c;在腾讯云购买了一个轻量应用服务器和TDSQL-MYSQL版的数据库。买来之…

OpenGL学习

1.1&#xff0c;状态机-上下文-对象 GPU渲染流程 OpenGL自身是一个巨大的状态机(State Machine)&#xff1a;一系列的变量描述OpenGL此刻应当如何运行。 状态机&#xff1a;变量&#xff08;描述该如何操作&#xff09;的大集合 OpenGL的状态通常被称为OpenGL上下文(Contex…

异构图注意力网络Heterogeneous Graph Attention Network ( HAN )

文章目录前言一、基础知识1.异构图&#xff08;Heterogeneous Graph&#xff09;2.元路径3.异构图注意力网络二、异构图注意力网络1.结点级别注意力&#xff08;Node-level Attention&#xff09;2.语义级别注意力&#xff08;Semantic-level Attention&#xff09;总结前言 异…

微信商城小程序怎么开发_分享微信商城小程序的搭建

如何搭建好一个微信商城&#xff1f;这三个功能要会用&#xff01; 1.定期低价秒杀&#xff0c;提高商城流量 除了通过私域流量裂变&#xff0c;低价秒杀是为商城引流提高打开率的良好手段。 以不同节日作为嘘头&#xff0c;在情人节、38妇女节、中秋国庆、七夕节等日子&…

前端框架 Nuxtjs Vue3 SEO解决方案 SSR

目录 一、Nuxtjs安装 二、路由规则 三、公共布局 四、Vue3中TypeScript的使用 一、Nuxtjs安装 参考&#xff1a;Installation Get Started with Nuxt安装 - NuxtJS | Nuxt.js 中文网Installation Get Started with Nuxt yarn create nuxt-app <项目名> 项目运行…

GAMES101 作业0 环境配置 PC下简单配置i

前言 GAMES101提供了计算机图形学相关教学知识&#xff0c;闫教授及其团队也为大家准备了相应课程作业。课程作业部署在虚拟机上&#xff0c;以便免去环境部署的麻烦。但对于一些同学来说&#xff0c;还是希望直接在WIN的VS上使用并编码&#xff0c;本文对此进行简单说明。 环…

神经网络和深度学习-后向传播back propagation

后向传播back propagation 首先我们要了解&#xff0c;前向传播&#xff0c;损失函数这些前置知识&#xff0c;下面我们给出一张神经网络的图 反向传播通过导数链式法则计算损失函数对各参数的梯度&#xff0c;并根据梯度进行参数的更新 下面举个简单的例子 我们需要知道x,y,…

Linux C网络通信过程

socket函数、sockaddr_in结构体 和 bind函数 socket函数的作用是创建一个网络文件描述符&#xff0c;程序通过这个文件描述符将数据发送到网络&#xff0c;也通过这个文件描述符从网络中接受数据。观察一下socket函数&#xff1a; int listenfd; listenfd socket(AF_INET, S…

NNDL 作业11:优化算法比较

目录 1. 编程实现图6-1&#xff0c;并观察特征 2. 观察梯度方向 3. 编写代码实现算法&#xff0c;并可视化轨迹 4. 分析上图&#xff0c;说明原理&#xff08;选做&#xff09; 5. 总结SGD、Momentum、AdaGrad、Adam的优缺点&#xff08;选做&#xff09; 6. Adam这么好&…

Python威布尔分布

文章目录威布尔分布及其性质在Python中生成威布尔分布的随机数指数分布和拉普拉斯分布的对比威布尔分布及其性质 威布尔分布&#xff0c;即Weibull distribution&#xff0c;又被译为韦伯分布、韦布尔分布等&#xff0c;是仅分布在正半轴的连续分布。 在numpy.random中&#…

python中urllib库的使用

1. 获取目标页面的源码 以获取百度页面源码为例 #使用urllib获取百度首页的源码 import urllib.request#1 定义一个url 作为需要访问的网址 url http://www.baidu.com#2 模拟浏览器向服务器发送请求 response响应 response urllib.request.urlopen(url)#3 获取响应中的页面…

Monkey测试

一、什么是 Monkey 测试 Monkey 测试是通过向系统发送伪随机的用户事件流&#xff08;如按键输入、触摸屏输入、手势输入等&#xff09;&#xff0c;实现对应用程序客户端的稳定性测试&#xff1b;通俗来说&#xff0c;Monkey 测试即“猴子测试”&#xff0c;是指像猴子一样&a…

JVM垃圾回收算法整理

JVM垃圾回收算法整理前言关键概念了解标记–清除算法复制算法标记–整理算法分代收集算法仰天大笑出门去&#xff0c;我辈岂是蓬蒿人前言 大概内容&#xff1a; jvm垃圾回收算法&#xff1a; 1、“标记–清除”算法&#xff1b;首先标记出所有需要被回收的对象&#xff0c;然…

搭建自己的SSR

Vue SSR介绍 是什么 官方文档&#xff1a;https://ssr.vuejs.org/Vue SSR&#xff08;Vue.js Server-Side Rendering&#xff09; 是 Vue.js 官方提供的一个服务端渲染&#xff08;同构应用&#xff09;解 决方案使用它可以构建同构应用还是基于原有的 Vue.js 技术栈 官方文档…

XXL-JOB逻辑自测及执行参数配置踩坑

概述 关于XXL-JOB的使用遇到的问题记录。对XXL-JOB不熟的&#xff0c;可以先参考分布式任务调度平台XXL-JOB深度实战 实战 业务DTO定义如下&#xff1a; Data public class AdAccountDTO {private String accountId;/*** yyyy-MM-dd HH:mm:ss*/private String startCreateT…

ThingBoard源码解析-缓存

配置 TB支持两种缓存&#xff1a;Caffeine和Redis,通过配置cache.type来指定使用哪种缓存。 位于 org.thingsboard.server.cache Caffeine 配置类&#xff1a;CaffeineCacheConfiguration Configuration ConditionalOnProperty(prefix "cache", value "t…