《QT实用小工具·五十一》带动画的 CheckBox

1、概述
源码放在文章末尾

该项目实现了带动画效果的多选框,鼠标放在上面或者选中都会呈现炫酷的动画效果,demo演示如下:

在这里插入图片描述

项目部分代码如下所示:


#ifndef LINEARCHECKBOX_H
#define LINEARCHECKBOX_H#include <QCheckBox>
#include <QPropertyAnimation>
#include <QPainter>
#include <QPainterPath>
#include <QDebug>class AniCheckBox : public QCheckBox
{Q_OBJECTQ_PROPERTY(double hover_prog READ getHoverProg WRITE setHoverProg)Q_PROPERTY(double part_prog READ getPartProg WRITE setPartProg)Q_PROPERTY(double check_prog READ getCheckProg WRITE setCheckProg)
public:AniCheckBox(QWidget* parent = nullptr);void setForeColor(QColor c);protected:void paintEvent(QPaintEvent *) override;void enterEvent(QEvent *e) override;void leaveEvent(QEvent *e) override;bool hitButton(const QPoint &) const override;virtual void checkStateChanged(int state);virtual void drawBox(QPainter &painter, QRectF rect);QPropertyAnimation* startAnimation(const QByteArray &property, double begin, double end, int duration = 500, QEasingCurve curve = QEasingCurve::OutQuad);protected:double getHoverProg() const;void setHoverProg(double prog);double getPartProg() const;void setPartProg(double prog);double getCheckProg() const;void setCheckProg(double prog);protected:int boxSide = 0; // 选择框边长,0为自适应QColor foreColor = QColor("#2753ff"); // 前景颜色double hoverProg = 0;   // 鼠标移上去的进度double partyProg = 0;   // 部分选中的进度double checkProg = 0;   // 选中的进度
};#endif // LINEARCHECKBOX_H

#include "anicheckbox.h"AniCheckBox::AniCheckBox(QWidget *parent) : QCheckBox(parent)
{setCursor(Qt::PointingHandCursor);connect(this, &QCheckBox::stateChanged, this, [=](int state) {// qInfo() << "状态变化:" << static_cast<Qt::CheckState>(state);checkStateChanged(state);});
}void AniCheckBox::setForeColor(QColor c)
{this->foreColor = c;
}void AniCheckBox::paintEvent(QPaintEvent *)
{// QCheckBox::paintEvent(e);QPainter painter(this);// painter.setRenderHint(QPainter::Antialiasing, true);QRectF rect;double textLeft;if (boxSide <= 0){// 自适应大小:优先一行文字大小,其次按比例const double fixedProp = 0.8; // 默认比例QFontMetricsF fm(painter.font());double side = fm.height(); // 一行文字的高度if (side >= this->height() * fixedProp)side = this->height() * fixedProp;double margin = side / 2;rect = QRectF(margin, (height() - side) / 2, side, side);textLeft = rect.right() + margin;}else{// 固定大小double margin = (this->height() - boxSide) / 2;rect = QRectF(margin, margin, boxSide, boxSide);textLeft = rect.right() + margin;}// 绘制选择框painter.save();drawBox(painter, rect);painter.restore();// 绘制文字painter.save();painter.drawText(QRectF(textLeft, 0, this->width() - textLeft, this->height()), this->text(), Qt::AlignVCenter | Qt::AlignLeft);painter.restore();
}void AniCheckBox::enterEvent(QEvent *e)
{QCheckBox::enterEvent(e);startAnimation("hover_prog", getHoverProg(), 1);
}void AniCheckBox::leaveEvent(QEvent *e)
{QCheckBox::leaveEvent(e);startAnimation("hover_prog", getHoverProg(), 0);
}bool AniCheckBox::hitButton(const QPoint &) const
{return true;
}void AniCheckBox::checkStateChanged(int state)
{if (state == Qt::Unchecked){startAnimation("check_prog", getCheckProg(), 0, 800, QEasingCurve::OutBounce);}else if (state == Qt::PartiallyChecked){}else if (state == Qt::Checked){startAnimation("check_prog", getCheckProg(), 1, 500, QEasingCurve::OutBack);}
}void AniCheckBox::drawBox(QPainter& painter, QRectF rect)
{painter.setPen(foreColor);painter.setRenderHint(QPainter::Antialiasing, true);// 绘制边缘方框,和悬浮状态有关double radius = 3;radius *= (1 - hoverProg);painter.drawRoundedRect(rect, radius, radius);// 绘制选中状态int state = this->checkState();double prop = 0.6;prop *= checkProg;rect = QRectF(rect.left() + rect.width() * (1 - prop) / 2,rect.top() + rect.height() * (1 - prop) / 2,rect.width() * prop,rect.height() * prop);QPainterPath path;path.addRoundedRect(rect, radius, radius);painter.fillPath(path, foreColor);if (state == Qt::Unchecked){}else if (state == Qt::PartiallyChecked){}else if (state == Qt::Checked){}
}QPropertyAnimation *AniCheckBox::startAnimation(const QByteArray &property, double begin, double end, int duration, QEasingCurve curve)
{QPropertyAnimation* ani = new QPropertyAnimation(this, property);ani->setStartValue(begin);ani->setEndValue(end);ani->setDuration(duration);ani->setEasingCurve(curve);connect(ani, SIGNAL(finished()), ani, SLOT(deleteLater()));connect(ani, SIGNAL(valueChanged(const QVariant&)), this, SLOT(update()));ani->start();return ani;
}double AniCheckBox::getHoverProg() const
{return hoverProg;
}void AniCheckBox::setHoverProg(double prog)
{this->hoverProg = prog;
}double AniCheckBox::getPartProg() const
{return partyProg;
}void AniCheckBox::setPartProg(double prog)
{this->partyProg = prog;
}double AniCheckBox::getCheckProg() const
{return checkProg;
}void AniCheckBox::setCheckProg(double prog)
{this->checkProg = prog;
}

源码下载

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

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

相关文章

OPPO手机支持深度测试+免深度测试解锁BL+ROOT权限机型整理-2024年3月更新

绿厂OPPO手机线上线下卖的都很不错&#xff0c;目前市场份额十分巨大&#xff0c;用户自然也非常多&#xff0c;而近期ROM乐园后台受到很多关于OPPO手机的私信&#xff0c;咨询哪些机型支持解锁BL&#xff0c;ROOT刷机&#xff0c;今天ROM乐园正式盘点当前市场上可以解BL刷root…

Mysql-黑马

Mysql-黑马 编写规范&#xff1a;## 一级1. 二级三级 1.Mysql概述 数据库概念mysql数据仓库 cmd启动和停止 net start mysql180 net stop mysql180备注&#xff1a;其中的mysql180是服务名 客户端连接 远程连接数据仓库 -h 主机号 -P端口号 mysql [-h 127.0.0.1] [-P 33…

1083 是否存在相等的差

solution 输出的是重复的差值&#xff0c;而非全部差值 #include<iostream> #include<algorithm> using namespace std; const int maxn 1e4 10; int flag[maxn] {0}; int main(){int n, x;scanf("%d", &n);for(int i 1; i < n; i){scanf(&…

一文全面了解 wxWidgets 布局器(Sizers)

目录 Sizers背后的理念 共同特征 最小大小 边框 对齐方式 伸缩因子 使用 Sizer 隐藏控件 wxBoxSizer wxStaticBoxSizer wxGridSizer wxFlexGridSizer 布局器&#xff08;Sizers&#xff09;&#xff0c;由wxWidgets类层次结构中的wxSizer类及其派生类表示&#xff0…

个人博客建设必备:精选域名和主机的终极攻略

本文目录 &#x1f30f;引言&#x1f30f;域名的选择&#x1f315;域名的重要性品牌识别营销和宣传可访问性和易记性信任和权威感搜索引擎优化&#xff08;SEO&#xff09;未来的灵活性和扩展性保护品牌 &#x1f315;如何选择域名&#x1f315;工具与资源分享国内的主流域名注…

springboot 自动配置源码解读

什么是自动装配 当我们程序依赖第三方功能组件时&#xff0c;不需要手动将这些组件类加载到IOC容器中。例如 当程序需要用到redis时&#xff0c;在pom.xml文件中引入依赖&#xff0c;然后使用依赖注入的方式直接从IOC容器中拿到相应RedisTemplate实例。 SpringBootApplication …

LeetCode 98.验证二叉搜索树

题目描述 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左 子树 只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 1&#xff…

如何在低代码平台中引用 JavaScript ?

引言 在当今快速发展的数字化时代&#xff0c;企业对业务应用的需求日益复杂且多元。低代码开发平台作为一个创新的解决方案&#xff0c;以直观易用的设计理念&#xff0c;打破了传统的编程壁垒&#xff0c;让非技术人员也能轻松构建功能完备的Web应用程序&#xff0c;无需深入…

Linux搭建mysql环境

搭建 MySQL 环境 1、使用 wget 下载安装包&#xff0c;下载到 opt 目录中 wget http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm2、安装 MySQL 公钥 rpm -i mysql57-community-release-el7-10.noarch.rpmrpm --import https://repo.mysql.com/RPM-GP…

GZIP文件格式解析和Inflate静态Huffman解压缩

GZIP是封装了Deflate压缩的格式文件&#xff1b;Deflate使用了无压缩、HuffmanLZ77进行压缩&#xff1b;解压是Inflate&#xff0c;Huffman包括静态Huffman压缩和动态Huffman压缩两种模式。 Java语言实现了GZIP格式解析、Inflate的静态Huffman解压缩、CRC32校验 算法。 gzip文…

精准测试-Vue前端调用链影响变更分析之一

Vue前端调用链影响变更分析之一 一、背景二、工具调研1、 工具介绍&#xff1a;2、工具使用 三、工具落地集成方案&#xff08;待后续补充&#xff09;变更影响较为简单的实现变更影响较为复杂的实现1、全局关系数据库的构建2、变更影响的简单实现3、变更影响的复杂实现 一、背…

ElasticSearch教程入门到精通——第一部分(基于ELK技术栈elasticsearch 8.x新特性)

ElasticSearch教程入门到精通——第一部分&#xff08;基于ELK技术栈elasticsearch 8.x新特性&#xff09; 1. ElasticSearch安装&#xff08;略&#xff09;2. ElasticSearch基础功能2.1 索引操作2.1.1 创建索引2.1.2 Head 索引2.1.3 查询索引2.1.3.1 查询单独索引2.1.3.2 查询…

Instal IIS on Windows Server 2022 Datacenter

和以往版本一样&#xff0c;没有什么不同&#xff0c;So easy&#xff01; WinR - ServerManager.exe 打开服务器管理器&#xff0c;点击【添加角色和功能】&#xff0c;选择自己想要的角色和功能。 一、开始之前&#xff1a;帮助说明&#xff0c;点击【下一步】&#xff1b;…

双塔模型模型结构、样本选择、训练方式、线上服务、模型更新

召回模型目的是快速选取用户可能感兴趣的物品&#xff0c;凡事用户可能感兴趣的都取回来 然后交给后续排序模型逐一甄别。 双塔模型结构 不止能使用id特征&#xff08;能使用id之外的其他特征&#xff09;&#xff0c;用户侧能用画像等其他特征&#xff0c;包括离散特征和连续…

vue3 element-plus 让el-container占满屏幕

在刚开始用element-plus的布局时&#xff0c;发现无法占满屏幕&#xff1a; 在App.vue中添加如下css代码&#xff1a; <style>html, body, #app {margin: 0;padding: 0;height: 100%;} </style>同时布局代码所在的component如下所示&#xff1a; <template&g…

C++ | Leetcode C++题解之第64题最小路径和

题目&#xff1a; 题解&#xff1a; class Solution { public:int minPathSum(vector<vector<int>>& grid) {if (grid.size() 0 || grid[0].size() 0) {return 0;}int rows grid.size(), columns grid[0].size();auto dp vector < vector <int>…

自定义 Dockerfile 构建 PostgreSQL 15 编译版 Docker 镜像

BG 前几日 Sean 老师发布了一篇文章 – PostgreSQL安装(一): 再简单点儿&#xff0c;用Docker?, 介绍如何快速安装启动 PostgreSQL 数据库。 本文再稍微延伸一点&#xff0c;介绍一下如何自定义 Dockerfile&#xff0c;加入自己想要预制的参数&#xff0c;构建一个自定义的 …

react核心知识

1. 对 React 的理解、特性 React 是靠数据驱动视图改变的一种框架&#xff0c;它的核心驱动方法就是用其提供的 setState 方法设置 state 中的数据从而驱动存放在内存中的虚拟 DOM 树的更新 更新方法就是通过 React 的 Diff 算法比较旧虚拟 DOM 树和新虚拟 DOM 树之间的 Chan…

暂时性解决JDK21 无法使用 TimeUnit的问题

我调用 java.util中的TimeUtil时。 JDK17及以下版本时这样正常可以使用的 但是在JDK21中却是个TimeUtil.class文件 我没法调用内部的属性 解决方式&#xff1a;是我卸载了21&#xff0c;使用的了JDK17. 使用场景&#xff1a;原本项目是基于JDK8 的&#xff0c;但是因为其他…