python实现的可爱卸载动画

在逛掘金时,掘金用户在B站看到的灵感进行的一个卸载窗口的动画效果的实用案例。人类是一种不断在学习的动物,并且是一种模仿能力学习能里比较强的动物。我这里是第三波的学习实践者咯!

相对VUE构建动画效果窗口,我更加喜欢用python来进行实现可爱卸载动画效果。其实,类似的软件卸载窗口,我们可以在一些常用的软件平台上进行看到,他们做的会更加的精美,同时在操作的过程当中也会流畅和丝滑太多。软件在用户在体验过程中进行最后的一次挽留用户的一次机会。
我们自己做的过程当中更多的是对功能的一个实现以及在实现过程当中的学习拓展,搞定后的满满的成就感。我们始终在孜孜不倦,同时又在乐此不疲。希望能够在不同的维度上为你带来一些灵感。
import tkinter as tk
from tkinter import ttkclass EmojiDialog:def __init__(self, parent):self.top = tk.Toplevel(parent)self.top.title("表情弹窗")self.top.geometry("640x480")self.top.configure(bg='#f5f5f7') # 苹果风格背景颜色# 初始化状态变量self.hue_deg = 49self.cheek_alpha = 1.0self.eye_scale = 1.0self.mouth_radius = [5, 5, 5, 5]self.eye_pos = [90, 80, 10, 20]self.is_leaving = False# 创建画布self.canvas = tk.Canvas(self.top, width=600, height=400, bg='#f5f5f7', highlightthickness=0)self.canvas.pack(pady=20)# 绘制初始元素self.draw_emoji()# 绑定事件self.canvas.bind("<Motion>", self.on_mouse_move)self.canvas.bind("<Leave>", self.on_mouse_leave)# 自定义按钮样式self.style = ttk.Style()self.style.theme_use('clam') # 使用'clam'主题,允许更多样式定制self.style.configure('TButton', background='#eaeaea',foreground='black',font=('Helvetica', 12, 'bold'),padding=10,relief='flat')self.style.map('TButton',background=[('active', '#d0d0d0')])# 按钮容器button_frame = ttk.Frame(self.top, style='TFrame')button_frame.pack(pady=20)ttk.Button(button_frame, text="保留", command=self.some_command).pack(side=tk.LEFT, padx=10)ttk.Button(button_frame, text="卸载", command=self.some_command).pack(side=tk.LEFT, padx=10)def draw_emoji(self):self.canvas.delete("all")self.draw_head()self.draw_eyes()self.draw_mouth()self.draw_cheeks()def draw_head(self):base_color = self.hsl_to_rgb(self.hue_deg, 100, 65.29)color_hex = f"#{base_color[0]:02x}{base_color[1]:02x}{base_color[2]:02x}"self.canvas.create_oval(200, 80, 400, 280, outline="#e6d706", width=3, fill=color_hex)def draw_eyes(self):self.draw_eye(250, 140, self.eye_pos[0], self.eye_pos[1]) # 左眼self.draw_eye(350, 140, self.eye_pos[2], self.eye_pos[3]) # 右眼def draw_eye(self, x, y, dx, dy):self.canvas.create_oval(x - 25, y - 25, x + 25, y + 25, fill="white", outline="")scale_factor = 1 + (self.eye_scale - 1) / 3eye_size = 22 * scale_factoreye_x = x + (dx / 100) * 25 - eye_size / 2eye_y = y + (dy / 100) * 25 - eye_size / 2self.canvas.create_oval(eye_x, eye_y, eye_x + eye_size, eye_y + eye_size, fill="#5f0303", outline="")def draw_mouth(self):x, y = 300, 200r = self.mouth_radiusself.canvas.create_rectangle(x - 45 + r[0], y - 20 + r[2],x + 45 - r[1], y + 30 - r[3],fill="#ad2424", outline="#ac0c0c", width=2, activedash=(5, 2))def draw_cheeks(self):cheek_color = self.rgba_to_hex(250, 147, 147, self.cheek_alpha)self.canvas.create_oval(150, 200, 200, 250, fill=cheek_color, outline="")self.canvas.create_oval(400, 200, 450, 250, fill=cheek_color, outline="")def on_mouse_move(self, event):if self.is_leaving:returnx = max(200, min(event.x, 400)) - 200y = max(80, min(event.y, 280)) - 80width, height = 200, 200self.hue_deg = 49 + 91 * (x / width)self.cheek_alpha = max(0.1, 1 - (x / (width - 50)))self.eye_scale = 1 + (x / width) / 3self.eye_pos = [(x / width) * 100, (y / height) * 100,(x / width) * 100, (y / height) * 100]mr = x / widthself.mouth_radius = [max(5, mr * 50), max(5, mr * 50),max(5, 50 - mr * 45), max(5, 50 - mr * 45)]self.draw_emoji()def on_mouse_leave(self, event):self.is_leaving = Trueself.reset_state()self.draw_emoji()self.is_leaving = Falsedef reset_state(self):self.hue_deg = 49self.cheek_alpha = 1.0self.eye_scale = 1.0self.mouth_radius = [5, 5, 5, 5]self.eye_pos = [90, 80, 10, 20]def hsl_to_rgb(self, h, s, l):h /= 360s /= 100l /= 100if s == 0:rgb = (l * 255, l * 255, l * 255)else:def hue_to_rgb(p, q, t):t += 1 if t < 0 else 0t -= 1 if t > 1 else 0if t < 1 / 6: return p + (q - p) * 6 * tif t < 1 / 2: return qif t < 2 / 3: return p + (q - p) * (2 / 3 - t) * 6return pq = l * (1 + s) if l < 0.5 else l + s - l * sp = 2 * l - qr = hue_to_rgb(p, q, h + 1 / 3)g = hue_to_rgb(p, q, h)b = hue_to_rgb(p, q, h - 1 / 3)rgb = (r * 255, g * 255, b * 255)return tuple(int(max(0, min(255, c))) for c in rgb)def rgba_to_hex(self, r, g, b, a):r = int(r * a + 255 * (1 - a))g = int(g * a + 255 * (1 - a))b = int(b * a + 255 * (1 - a))return f"#{r:02x}{g:02x}{b:02x}"def some_command(self):print("命令执行")class MainApp:def __init__(self, root):self.root = rootself.root.geometry("300x200")self.root.configure(bg='#f5f5f7') # 设置主窗口背景颜色ttk.Button(self.root, text="打开弹窗", command=self.open_dialog).pack(expand=True)def open_dialog(self):EmojiDialog(self.root)if __name__ == "__main__":root = tk.Tk()app = MainApp(root)root.mainloop()
相关文章:
python实现的可爱卸载动画
在逛掘金时,掘金用户在B站看到的灵感进行的一个卸载窗口的动画效果的实用案例。人类是一种不断在学习的动物,并且是一种模仿能力学习能里比较强的动物。我这里是第三波的学习实践者咯! 相对VUE构建动画效果窗口,我更加喜欢用pytho…...
微服务的春天:基于Spring Boot的架构设计与实践
微服务的春天:基于Spring Boot的架构设计与实践 在如今的技术领域,微服务架构俨然成为了解决复杂系统开发与运维挑战的关键利器。作为一名资深运维和自媒体创作者,笔名Echo_Wish,我将深入探讨基于Spring Boot的微服务架构设计,结合实例代码说明观点,希望能为大家带来启发…...
*VulnHub-FristiLeaks:1.3暴力解法、细节解法,主打软硬都吃,隧道搭建、寻找exp、提权、只要你想没有做不到的姿势
*VulnHub-FristiLeaks:1.3暴力解法、细节解法,主打软硬都吃,隧道搭建、寻找exp、提权、只要你想没有做不到的姿势 一、信息收集 1、扫靶机ip 经典第一步,扫一下靶机ip arp-scan -l 扫描同网段 nmap -sP 192.168.122.0/242、指纹扫描、端口…...
OpenCV 颜色空间:原理与操作指南
颜色空间原理 RGB 颜色空间 RGB(Red, Green, Blue)是最常见的颜色空间,它通过红、绿、蓝三种颜色通道的不同强度组合来表示颜色。在 OpenCV 中,RGB 图像的每个像素由三个 8 位无符号整数(0 - 255)分别表示…...
国产编辑器EverEdit - 超多样式设置
1 设置-编辑-样式 1.1 设置说明 1.1.1 折叠样式 默认为箭头,折叠样式选项如下: 箭头: 矩形和线条 五边形 圆形图标 1.1.2 光标样式 光标用于指示当前用户输入位置,光标样式选项如下: 默认 纤细 字宽 …...
rabbitmq版本升级并部署高可用
RabbitMQ版本升级 先检查是否已经安装rabbitmq rpm -qa|grep rabbitmq|wc -l //如果结果是0,表示没有安装 rpm -e --nodeps $(rpm -qa|grep rabbitmq) //如安装了,则进行卸载 先检查是否已经安装erlang rpm -qa|grep erlang|wc -l //如果结果…...
Visual Studio 2022新建c语言项目的详细步骤
步骤1:点击创建新项目 步骤2:到了项目模板 --> 选择“控制台应用” (在window终端运行代码。默认打印"Hello World") --> 点击 “下一步” 步骤3:到了配置新项目模块 --> 输入“项目名称” --> 更改“位置”路径&…...
Spring Boot使用JDBC /JPA访问达梦数据库
Spring Boot 是一个广泛使用的 Java 框架,用于快速构建基于 Spring 的应用程序。对于达梦数据库(DMDB)的支持,Spring Boot 本身并没有直接内置对达梦数据库的集成,但你可以通过一些配置和依赖来支持达梦数据库。 以下…...
Spring Boot 消息队列(以RabbitMQ为例)
文章目录 RabbitMQ 简介与安装1. RabbitMQ 简介2. RabbitMQ 安装 Spring Boot 集成 RabbitMQ1. 创建 Spring Boot 项目2. 配置 RabbitMQ3. 定义消息队列和交换机4. 发送消息5. 接收消息6. 测试消息发送和接收 RabbitMQ 简介与安装 1. RabbitMQ 简介 RabbitMQ 是一个开源的消息…...
单元测试与仿真程序之间的选择
为什么写这篇文章 现在的工作需求,让我有必要总结和整理一下。 凡事都有适用的场景。首先这里我需要提示一下,这里的信息,可能并不普适。 但是可以肯定一点的是,有些人,不论做事还是写书,上下文还没有交待…...
确认机制面临的挑战
在传输控制协议中,确认机制(ACK 机制)是确保数据可靠交付、实现拥塞控制和丢包恢复的重要组成部分。然而,随着网络环境和业务需求的不断演进,确认机制在实际应用中面临着诸多挑战。今天我们探讨确认机制主要面临的几项…...
在MATLAB环境中,对矩阵拼接(Matrix Concatenation)的测试
在MATLAB环境中,对矩阵拼接(Matrix Concatenation)的正确性与鲁棒性开展测试时,需要依据不同的拼接场景精心设计测试用例,全面验证矩阵维度、数据顺序、边界条件以及异常处理等关键方面。以下是详尽的测试方法与具体示…...
[MySQL初阶]MySQL(4)基本查询
标题:[MySQL初阶]MySQL(4)基本查询 水墨不写bug 文章目录 一. 数据表设计二、对数据表的操作1. Create 操作(插入数据)查看最近受影响的行数: 2. Retrieve 操作(读取数据)࿰…...
基于STM32的智能家居蓝牙系统(论文+源码)
1总体方案设计 本次基于STM32的智能家居蓝牙系统,其系统总体架构如图2.1所示,采用STM32f103单片机作为控制器,通过DHT11传感器实现温湿度检测,MQ-2烟雾传感器实现烟雾检测,光敏电阻实现光照检测,同时将数据…...
QTS单元测试框架
1.QTS单元测试框架介绍 目前QTS项目采用C/C语言,而CppUnit就是xUnit家族中的一员,它是一个专门面向C的单元测试框架。因此,QTS采用CppUnit测试框架是比较理想的选择。 CppUnit按照层次来管理测试,最底层的就是TestCase,当有了几个TestCase以后,可以将它们组织成Te…...
《水利水电安全员考试各题型对比分析及应对攻略》
《水利水电安全员考试各题型对比分析及应对攻略》 单选题: 特点:四个选项中只有一个正确答案,相对难度较小。主要考查对基础知识的掌握程度。 应对攻略:认真审题,看清题目要求。对于熟悉的知识点,直接选择…...
sqlite3 c++ client选择; c++环境搭建 : abseil-cpp | fnc12/sqlite_orm
sqlite3 c client选择 今日20250305 2.4K星: 7月前最后提交核心: SRombauts/SQLiteCpp.git : 薄封装、命令式sql、非orm、支持事务2.4K星: 1月前最后提交核心: fnc12/sqlite_orm.git : 厚封装、非侵入、真orm、真泛型、类型复杂、支持事务、报错信息不完整(启动事…...
IMX6ULL驱动开发uboot篇02
目录 网络操作 第零步:先将网线跟电脑接好,打开串口连接到开发板上,然后上电,让UBoot停下来 第一步:查看我们的网线构成的虚拟子网是哪一个 第二步:我们必须把虚拟机的网卡模式从NAT改成桥接,…...
智谱AI-FunctionCall
智谱AI-FunctionCall 编写FuncationCall大模型的函数调用,先直观的感受一下的感受下FunctionCall的魅力 文章目录 智谱AI-FunctionCall[toc]1-参考网址2-思路整理3-代码拆件1-[非核心]两个业务函数2-[非核心]业务函数的JsonSchema定义3-[核心]FunctionCall的调用1-打…...
数据保险箱:备份文件的关键价值与自动化实践
在信息化社会,数据已经成为我们生活、工作和学习的核心组成部分。无论是企业机密、个人隐私,还是创意作品、研究数据,它们都以数字形式存在于我们的电子设备中。然而,数据如同脆弱的玻璃制品,稍有不慎就可能面临丢失或…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)
旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据!该数据集源自2025年4月发表于《地理学报》的论文成果…...
链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...
