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

news2024/11/25 6:31:28

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;
}

源码下载

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

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

相关文章

图像处理1,灰度,data,for循环批处理图片,图片属性查看,图片单通道查看,椒盐噪声的生成,滤波处理,图像分割

图像处理1 灰度处理data库的使用for循环批处理图像对图像属性的查看图片类型图片尺寸图片宽度图像高度通道数总像素个数最大像素值最小像素值&#xff0c;像素平均值图像点像素值 for循环分别显示图像rgb通道椒盐噪声的生成中值滤波处理高斯模糊处理图像切割 灰度处理 from sk…

多国语言免费在线客服系统源码,网站在线客服系统,网页在线客服软件在线聊天通讯平台

详情介绍 多国语言免费在线客服系统源码,网站在线客服系统,网页在线客服软件在线聊天通讯平台 新款在线客服系统全开源无加密:多商户、国际化多语言、智能机器人、自动回复、语音聊天、 文件发送、系统强力防黑加固、不限坐席、国际外贸、超多功能 支持手机移动端和PC网页…

如何从Mac电脑恢复任何删除的视频

Microsoft Office是包括Mac用户在内的人们在世界各地创建文档时使用的最佳软件之一。该软件允许您创建任何类型的文件&#xff0c;如演示文稿、帐户文件和书面文件。您可以使用 MS Office 来完成。所有Microsoft文档都可以在Mac上使用。大多数情况下&#xff0c;您处理文档&…

私有开源LLM实例的三个考虑因素

原文地址&#xff1a;three-considerations-for-private-open-source-llm-instances 2024 年 4 月 29 日 在生产应用中使用商业 LLM APIs 会带来明确且经过充分研究的风险。因此&#xff0c;企业越来越多地转向利用开源的私有托管LLM实例&#xff0c;并通过RAG技术进行增强。 介…

RCE学习

从最近的xyctf中&#xff0c;最大的感受就是自己的rce基础并不牢固&#xff0c;所以马上来恶补一下 漏洞成因 php和其他语言有很多能够执行系统命令或执行其他php代码的函数&#xff0c;因为开发者的使用不当&#xff0c;使得用户能够控制传递给执行命令的函数的参数&#xf…

【C++题解】1300. 小明暑假的零花钱

问题&#xff1a;1300. 小明暑假的零花钱 类型&#xff1a;多分支结构 题目描述&#xff1a; 小明同学的妈妈在期末考试之后决定根据小明的考试成绩奖励小明不同的暑假零花钱&#xff0c;如果考试成绩在90 分以上&#xff08;包括 90 分&#xff09;&#xff0c;零花钱是成绩…

clang:在 Win10 上编译 MIDI 音乐程序

先从 Microsoft C Build Tools - Visual Studio 下载 1.73GB 安装 "Microsoft C Build Tools“ 访问 Swift.org - Download Swift 找到 Windows 10&#xff1a;x86_64 下载 swift-5.10-RELEASE-windows10.exe 大约490MB 建议安装在 D:\Swift\ &#xff0c;安装后大约占…

【Linux系统编程】32.线程同步、锁的使用、互斥锁管理

目录 线程同步 锁的使用 注意事项 pthread_mutex_init 注意 参数mutex 参数attr 返回值 动态初始化 静态初始化 pthread_mutex_destroy 参数mutex 返回值 pthread_mutex_lock 参数mutex 返回值 pthread_mutex_unlock 参数mutex 返回值 pthread_mutex_trylo…

JAVA面试之MQ

如何保证消息的可靠传输&#xff1f;如果消息丢了怎么办 数据的丢失问题&#xff0c;可能出现在生产者、MQ、消费者中。 &#xff08;1&#xff09;生产者发送消息时丢失&#xff1a; ①生产者发送消息时连接MQ失败 ②生产者发送消息到达MQ后未找到Exchange(交换机) ③生产者发…

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

题目&#xff1a; 题解&#xff1a; class Solution:def minPathSum(self, grid: List[List[int]]) -> int:if not grid or not grid[0]:return 0rows, columns len(grid), len(grid[0])dp [[0] * columns for _ in range(rows)]dp[0][0] grid[0][0]for i in range(1, r…

WPF基础应用

WPF参考原文 MVVM介绍 1.常用布局控件 1.1 布局控件 WPF&#xff08;Windows Presentation Foundation&#xff09;提供了多种布局容器来帮助开发者设计用户界面&#xff0c;以下是一些常用的布局&#xff1a; Grid: Grid是最常用的布局容器之一&#xff0c;它允许你通过定…

计算机网络-408考研

后续更新发布在B站账号&#xff1a;谭同学很nice http://【计算机408备考-什么是计算机网络&#xff0c;有什么特点&#xff1f;】 https://www.bilibili.com/video/BV1qZ421J7As/?share_sourcecopy_web&vd_source58c2a80f8de74ae56281305624c60b13http://【计算机408备考…

【论文阅读笔记】TS2Vec: Towards Universal Representation of Time Series

【论文阅读笔记】TS2Vec: Towards Universal Representation of Time Series 摘要 这段文字介绍了一个名为TS2Vec的通用框架&#xff0c;用于学习时间序列数据的表示&#xff0c;可以在任意语义层次上进行。与现有方法不同&#xff0c;TS2Vec通过对增强的上下文视图进行层次化…

C语言指针进阶_字符指针、指针数组、数组指针、函数指针等的介绍

文章目录 前言一、字符指针二、指针数组三、 数组指针1. 数组名和 & 数组名2. 数组指针3. 数组指针解引用 四、数组指针的使用二维数组的传参说明数组指针使用小测验 五、数组传参和指针传参1. 一维数组传参总结2. 二维数组传参总结3. 一级指针传参4. 二级指针传参 六、函数…

React Context

Context https://juejin.cn/post/7244838033454727227?searchId202404012120436CD549D66BBD6C542177 context 提供了一个无需为每层组件手动添加 props, 就能在组件树间进行数据传递的方法 React 中数据通过 props 属性自上而下(由父及子)进行传递&#xff0c;但此种用法对…

Git使用指北

目录 创建一个Git仓库本地仓库添加文件文件提交到本地仓库缓冲区添加远程仓库地址本地仓库推送到远程仓库创建新的分支拉取代码同步删除缓冲区的文件&#xff0c;远程仓库的文件.gitignore文件 创建一个Git仓库 Git仓库分为远程和本地两种&#xff0c;远程仓库如Githu上创建的…

每天五分钟深度学习框架pytorch:如何创建多维Tensor张量元素?

本文重点 上节课程我们学习了如何创建Tensor标量,我们使用torch.tensor。本节课程我们学习如何创建Tensor向量,我们即可以使用torch.Tensor又可以使用torch.tensor,下面我们看一下二者的共同点和不同点。 Tensor张量 tensor张量是一个多维数组,零维就是一个点(就是上一…

Java零基础入门到精通_Day 9

1.ArrayList 编程的时候如果要存储多个数据&#xff0c;使用长度固定的数组存储格式&#xff0c;不一定满足我们的需求&#xff0c;更适应不了变化的需求&#xff0c;那么&#xff0c;此时该如何选择呢? 集 合 集合类的特点:提供一种存储空间可变的存储模型&#xff0c;存储的…

EMP.DLL是什么东西?游戏提示EMP.DLL文件缺失怎么解决

emp.dll文件是Windows操作系统中的一种动态链接库文件&#xff0c;它被设计为可以被多个程序共享使用的模块化文件。这种设计旨在提高系统效率&#xff0c;减少内存消耗&#xff0c;并简化软件的维护和更新。DLL文件通常包含了一系列相关的函数和变量&#xff0c;这些函数和变量…

C++入门系列-内联函数

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 以inline修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用内敛函数的地方展开&#xff0c;这就意味着使用内联函数可以提升程序的运行的效率&#xff0c;减小了调用所需…