《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_OBJECT
    Q_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;
}

源码下载

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C/C++不定参函数使用

C语言中不定参函数的使用和访问 例子 例如&#xff0c;这里想写一个打印的函数&#xff0c;但是参数并不确定该怎么办呢&#xff0c;这就要用到不定参函数 #include<stdarg.h> void printNum(int count,...){va_list ap;va_start(ap,count);//获取指定参数的起始地址&…

【CTF Reverse】XCTF GFSJ0492 insanity Writeup(反汇编+字符串搜索)

insanity 菜鸡觉得前面的题目太难了&#xff0c;来个简单的缓一下 解法 拖进 Exeinfo PE 中分析。 -> Compiler : GCC: (Debian 4.4.7-2) 4.4.7用 IDA 打开。 按 shift F12 打开 String 页面。找到 flag。 Flag 9447{This_is_a_flag}声明 本博客上发布的所有关于网络攻…

Java创建并遍历N叉树(前序遍历)

力扣 title589&#xff1a;N叉树的前序遍历 给定一个 n 叉树的根节点 root &#xff0c;返回 其节点值的 前序遍历 。 n 叉树 在输入中按层序遍历进行序列化表示&#xff0c;每组子节点由空值 null 分隔&#xff08;请参见示例&#xff09;。 思路&#xff1a; 1.初始化时…

电脑自带dll修复在哪里,使用dll修复工具解决dll问题

在我们日常与电脑相伴的工作与学习过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中最常见的就是“无法找到.dll”或“找不到.dll文件”。这种情况通常是由于dll文件丢失或损坏导致的。dll文件是动态链接库文件&#xff0c;它包含了许多程序运行所需的函数和资源…

Ant Design助力:实现用户列表的优雅展示与管理

文章目录 概要前端讲解登录组件注册组件用户列表组件 后端讲解连接数据库db.js路由routes.jsexpress应用app.js 启动项目小结 概要 在上一篇博客&#x1f6aa;中&#xff0c;我们已经成功实现了登录注册系统的基本功能。现在&#xff0c;我们将进一步完善系统&#xff0c;实现…

File contains parsing errors: file:///etc/yum.repos.d/nginx.repo报错解决,文件配置出现问题

执行yum指令出现以下错误&#xff1a; 解决方案&#xff1a;yum的配置文件出现问题&#xff0c; 先删除yum.repos.d目录下所有文件 rm -f /etc/yum.repos.d/* 然后重新下载阿里的资源 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.…

您想拥有一个属于你自己的GPT-3.5-turbo吗?来吧,开始行动起来吧!!!

背景: 在2024年4月的时候,openai公司宣布GPT-3.5-turbo免费使用,无需注册!!! 多么激动人心的消息啊!!! 但是,如何你想申请一个openai api key的时候,发现调用失败,直接报Rate Limit!!! 无语了!!! 不过没关系,我们另辟捷径!!! 下面就开始我的表演啦…

python可视化学习笔记折线图问题-起始点问题

问题描述&#xff1a; 起始点的位置不对 from pyecharts.charts import Line import pyecharts.options as opts # 示例数据 x_data [1,2,3,4,5] y_data [1, 2, 3, 4, 5] # 创建 Line 图表 line Line() line.add_xaxis(x_data) line.add_yaxis("test", y_data) li…

【全网最全】2024五一数学建模B题论文+前四问代码多种保奖进阶思路+建模过程+代码+数据处理+论文写作技巧等(后续会更新)

一定要点击文末的卡片&#xff0c;那是获取资料的入口&#xff01; 点击链接加入群聊【2024五一数学建模】&#xff1a;http://qm.qq.com/cgi-bin/qm/qr?_wv1027&khoTDlhAS5N_Ffp-vucfG5WjeeJFxsWbz&authKey7oCSHS25VqSLauZ2PpiewRQ9D9PklaCxVS5X6i%2BAkDrey992f0t15…

【hackmyvm】vivifytech靶机

渗透思路 信息收集端口扫描端口服务信息目录扫描爆破hydra--sshgit提权 信息收集 ┌──(kali㉿kali)-[~] └─$ fping -ag 192.168.9.0/24 2>/dev/null 192.168.9.119 --主机 192.168.9.164 --靶机个人习惯&#xff0c;也方便后续操作&#xff0c;将IP地址赋值给一个变…

两院院士泌尿外科专家吴阶平教授

吴阶平&#xff08;1917-2011&#xff09;&#xff0c;男&#xff0c;江苏常州人&#xff0c;1933年天津汇文中学毕业&#xff0c;保送到北平燕京大学医预科&#xff0c;1937年毕业于北平燕京大学获理学士学位&#xff0c;1942年毕业于北平协和医学院获医学博士学位&#xff0c…

使用 Langchain、Langfuse、Nemo-gaurdrails、RAGAs构建 RAG 管道并进行监控和评估

原文地址:build-end-to-end-rag-pipeline-with-monitoring-and-evaluation-using-langchain-azure-ai-search 2024 年 4 月 21 日 介绍 使用现代的LLM框架,如Langchain或llamaindex,可以迅速搭建一个用于 RAG 的管道,通常只需编写大约5-6行代码。然而,若要构建一个适用于生…

短视频素材去哪里搬运?短视频素材有哪些类型?

在这个数字化和视觉传达至关重要的时代&#xff0c;选择合适的视频素材对于提升视频内容的吸引力和观众参与度至关重要。无论您是一名广告制片人、社交媒体经理还是独立视频制作者&#xff0c;以下这些精选的视频素材网站将为您提供从高清视频到特效资源的全面支持&#xff0c;…

HSDB使用教程

HSDB&#xff1a;Hostspot Debugger&#xff0c;JVM内置的工具&#xff0c;用于深入分析JVM运行时的内部状态 启动HSDB java -cp D:/tools/jdk-1.8/lib/sa-jdi.jar sun.jvm.hotspot.HSDB 获取进程id jps 连接到指定进程 查找类 通过查询查找对象 输入查询语句 select d from …

算法复杂度分析:揭秘隐藏的计算之谜

复杂度 算法的复杂度指的是执行该算法的程序在运行时所需要的时间和空间资源。时间复杂度不是代码真正的时间&#xff0c;而是数据规模的增长所表达的趋势。 算法的复杂度分析分为时间复杂度和空间复杂度。一般我们说的多的是算法的时间复杂度&#xff0c;希望通过较少时间执行…

iOS 实现视图遮罩效果

有时候&#xff0c;我们会遇到这种需求&#xff0c;只讲视图的某个部分展示出来 这时候&#xff0c;我们可以通过设置该视图layer.mask layerb来实现&#xff0c;需要注意的是&#xff0c;这里的layerb必须要设置backgroundColor&#xff0c;渐变layer有colors,否则达不到效果…

ubuntu sudo apt-get install neo4j 配置安装与设置远程访问

文章目录 下载Adding the Debian repositoryInstalling Neo4j安装流程设置远程访问 下载 neo4j 官方的下载地址&#xff0c;进入页面之后&#xff0c;往下滑&#xff1a; https://neo4j.com/deployment-center/#community 点击 Visit https://debian.neo4j.com/ Adding the …

链表(数组实现的伟大二踢脚)

一.链表与数组 链表作为 C 语言中一种基础的数据结构&#xff0c;在平时写程序的时候用的并不多&#xff0c;但在操作系统里面使用的非常多。不管是RTOS还是Linux等使用非常广泛&#xff0c;所以必须要搞懂链表&#xff0c;链表分为单向链表和双向链表&#xff0c;单向链表很少…

2024.5.1【项目测试报告】模拟微信实现网页聊天室

目录 项目介绍 核心功能 额外拓展 核心技术 项目页面设计 注册页面 登录页面 找回密码页面 网页聊天室页面 个人中心页面 测试计划 功能测试 注册页面 登录页面 找回密码页面 个人中心页面 网页聊天室页面 自动化测试 单例驱动 获取屏幕截图 注册页面自动化测…

GPG的使用

这里写自定义目录标题 安装加密程序生成加密密钥怎么备份自己的密钥就可以使用公钥加密邮件信息了 安装加密程序 下载gpg4win&#xff1a; https://www.gpg4win.org/index.html 免费的&#xff0c;如果使用的是苹果电脑&#xff0c;使用https://gpgtools.org/。 如果是linux&a…