首页 > 编程语言 >Python 桌宠代码

Python 桌宠代码

时间:2024-09-18 19:22:53浏览次数:11  
标签:curr 桌宠 width Python 代码 gif animation root self

import tkinter  # 导入 tkinter GUI 库
import os  # 导入 os 库用于文件路径操作
import random  # 导入 random 库用于随机选择
from platform import system  # 导入系统模块以检测操作系统
from PIL import Image, ImageTk  # 导入 Pillow 库用于处理图像透明背景


# 定义一个宠物类
class Pet:
    def __init__(self):
        self.root = tkinter.Tk()  # 创建窗口
        self.delay = 200  # 设置动画帧之间的延迟 (单位:毫秒)
        self.pixels_from_right = 500  # 宠物初始位置相对于右边的像素
        self.pixels_from_bottom = 500  # 宠物初始位置相对于底部的像素
        self.move_speed = 3  # 设置宠物移动速度 (单位:像素)

        # 初始化动画帧数组
        self.animation = dict(
            flower=[self.get_transparent_image('gifs/flower.gif', i) for i in range(55)],  # 加载闲置动画帧
            eat=[self.get_transparent_image('gifs/eat.gif', i) for i in range(39)],  # 加载闲置动画帧
            scorn=[self.get_transparent_image('gifs/scorn.gif', i) for i in range(23)],  # 加载闲置转睡眠动画帧
            sleep=[self.get_transparent_image('gifs/sleep.gif', i) for i in range(36)] * 2,  # 加载睡眠动画帧并复制三次
            listenmusic=[self.get_transparent_image('gifs/listenmusic.gif', i) for i in range(39)],  # 加载左走动画帧
            play=[self.get_transparent_image('gifs/play.gif', i) for i in range(60)]  # 加载右走动画帧
        )

        # 窗口配置
        self.root.overrideredirect(True)  # 移除窗口边框
        if system() == 'Windows':
            self.root.wm_attributes('-transparentcolor', 'white')  # 设置 Windows 的透明颜色为白色
        else:  # 如果是 Mac/Linux
            self.root.wm_attributes('-transparent', True)  # 设置透明属性
            self.root.config(bg='systemTransparent')  # 设置背景为系统透明

        self.root.attributes('-topmost', True)  # 确保窗口位于所有其他窗口之上
        self.root.bind("<Button-1>", self.onLeftClick)  # 绑定左键点击事件
        self.root.bind("<Button-3>", self.showpopumenu)  # 绑定右键点击事件
        self.root.bind("<Key>", self.onKeyPress)  # 绑定键盘按键事件
        self.root.bind("<B1-Motion>", self.on_drag)  # 绑定拖动事件

        self.canvas = tkinter.Canvas(self.root, width=100, height=100, bg="white", highlightthickness=0)
        self.canvas.pack(expand=True)

        screen_width = self.root.winfo_screenwidth()  # 获取屏幕宽度
        screen_height = self.root.winfo_screenheight()  # 获取屏幕高度
        self.min_width = 10  # 设置宠物的最小移动边界
        self.max_width = screen_width - 110  # 设置宠物的最大移动边界

        # 更改窗口的初始位置
        self.curr_width = screen_width - self.pixels_from_right  # 当前宽度
        self.curr_height = screen_height - self.pixels_from_bottom  # 当前高度
        self.root.geometry(f"{imgWidth}x{imgHeight}+{self.curr_width}+{self.curr_height}")

        self.popumenu = tkinter.Menu(self.root, tearoff=False)
        for animation in self.animation.keys():
            self.popumenu.add_command(label=animation, command=lambda anim=animation: self.change_animation(anim))

    def get_transparent_image(self, gif_path, index):
        gif = Image.open(gif_path)
        gif.seek(index)
        return ImageTk.PhotoImage(gif.convert('RGBA'))

    def update(self, i, curr_animation):
        # 更新窗口状态
        self.root.attributes('-topmost', True)  # 确保窗口位于最上层
        animation_arr = self.animation[curr_animation]  # 获取当前动画帧数组
        frame = animation_arr[i]  # 获取当前帧
        self.canvas.delete("all")
        self.canvas.create_image(50, 50, image=frame)
        self.canvas.image = frame

        # 如果需要移动宠物
        if curr_animation in ('play', 'scorn'):
            self.move_window(curr_animation)

        i += 1  # 指向下一帧
        if i == len(animation_arr):
            # 达到当前动画的末尾,决定下一步动画
            next_animation = self.getNextAnimation(curr_animation)
            self.root.after(self.delay, self.update, 0, next_animation)  # 等待一段时间后更新动画
        else:
            self.root.after(self.delay, self.update, i, curr_animation)  # 否则继续当前动画

    def onLeftClick(self, event):
        print("检测到左键点击")  # 左键点击事件处理函数

    def showpopumenu(self, event):
        self.popumenu.post(event.x_root, event.y_root)

    def onKeyPress(self, event):
        if event.char in ('q', 'Q'):
            self.quit()  # 按下 'q' 或 'Q' 键退出程序

    def on_drag(self, event):
        self.curr_width = event.x_root - imgWidth // 2
        self.curr_height = event.y_root - imgHeight // 2
        self.root.geometry(f"{imgWidth}x{imgHeight}+{self.curr_width}+{self.curr_height}")

    def move_window(self, curr_animation):
        if curr_animation == 'play':
            if self.curr_width > self.min_width:
                self.curr_width -= self.move_speed  # 向左移动
        elif curr_animation == 'scorn':
            if self.curr_width < self.max_width:
                self.curr_width += self.move_speed  # 向右移动

        self.root.geometry(f"{imgWidth}x{imgHeight}+{self.curr_width}+{self.curr_height}")  # 更新窗口位置

    def getNextAnimation(self, curr_animation):
        # 获取下一个动画类型
        if curr_animation == 'flower':
            return random.choice(['listenmusic', 'eat', 'play', 'scorn', 'sleep'])  # 随机选择下一动画
        elif curr_animation == 'eat':
            return random.choice(['listenmusic', 'eat', 'play', 'scorn', 'flower'])
        elif curr_animation == 'sleep':
            return random.choice(['listenmusic', 'eat', 'play', 'scorn', 'flower'])  # 随机选择保持睡眠或转为闲置
        elif curr_animation == 'listenmusic':
            return random.choice(['sleep', 'eat', 'play', 'scorn', 'flower'])  # 转为闲置动画
        elif curr_animation == 'play':
            return random.choice(['listenmusic', 'eat', 'sleep', 'scorn', 'flower'])  # 随机选择下一动画
        elif curr_animation == 'scorn':
            return random.choice(['listenmusic', 'eat', 'play', 'sleep', 'flower'])  # 随机选择下一动画
        elif curr_animation == 'eat':
            return random.choice(['listenmusic', 'sleep', 'play', 'scorn', 'flower'])  # 随机选择下一动画

    def change_animation(self, animation):
        self.update(0, animation)

    def run(self):
        self.root.after(self.delay, self.update, 0, 'listenmusic')  # 开始时设置为闲置状态
        self.root.mainloop()  # 启动主事件循环

    def quit(self):
        self.root.destroy()  # 销毁窗口,退出程序


if __name__ == '__main__':
    print('初始化你的桌面宠物...')
    print('要退出,请右键单击宠物')
    imgWidth, imgHeight = 100, 100
    pet = Pet()  # 创建宠物对象
    pet.run()  # 运行宠物



下面是获取gif动画帧数:
from PIL import Image
import os


def extract_gif_frames(gif_path, output_folder, picturename):
    # 打开 GIF 文件
    with Image.open(gif_path) as img:
        frames = []
        durations = []
        total_duration = 0

        # 遍历每一帧
        for frame in range(img.n_frames):
            img.seek(frame)  # 定位到当前帧
            frames.append(img.copy())  # 复制当前帧
            duration = img.info['duration'] / 1000.0  # 获取持续时间(秒)
            durations.append(duration)
            total_duration += duration  # 累加总持续时间

            # 保存每帧为图片,使用指定的 picturename
            frame_filename = os.path.join(output_folder, f'{picturename}_frame_{frame}.png')
            img.save(frame_filename)

    return total_duration, frames, durations


# 使用示例
gif_path = r'C:\Users\33947\AppData\Local\Programs\Python\Python39\Scripts\GUI\pet\gifs\brushteeth.gif'
output_folder = r'C:\Users\33947\AppData\Local\Programs\Python\Python39\Scripts\GUI\pet\picture\brushteeth'
picturename = 'my_gif'  # 自定义文件名前缀
os.makedirs(output_folder, exist_ok=True)  # 创建输出文件夹

total_duration, frames, durations = extract_gif_frames(gif_path, output_folder, picturename)

# 输出总持续时间
print(f"Total duration: {total_duration} seconds")

标签:curr,桌宠,width,Python,代码,gif,animation,root,self
From: https://blog.csdn.net/m0_66960730/article/details/142341494

相关文章

  • AI带货直播虚拟主播的生成代码!
    随着AI技术的飞速发展,AI带货直播虚拟主播已成为电商行业的新宠,这些虚拟主播不仅能24小时不间断地进行直播,还能通过智能互动提升用户体验,为商家带来更多的销售机会,本文将分享五段关键源代码,帮助读者了解AI带货直播虚拟主播背后的技术实现。1、虚拟主播面部捕捉与动画生成在AI带货直......
  • YOLOV8 det 多batch TensorRT 推理(python )
    由于我当前的项目需求是推理四张,所以,demo部分也是基于4张进行演示的,不过基于此套路,可以实现NCHW的任意尺度推理,推理代码如下:importnumpyasnpfromnumpyimportndarrayfromtypingimportList,Tuple,UnionfrommodelsimportTRTModule#isort:skipimportar......
  • centos7下安装Python3.7
    centos7默认安装的是python2.7,然而python2基本上要淘汰了,所以有必要安装最新的python3python,g++这些工具一般安装在/usr/bin目录里通过指令llpython*可以看到python指向的是python2.7我们要安装python3,使python指向python3下面开始具体步骤(参考其他大佬的方法,也是学了......
  • 使用Python计算多个集合的交集详解
    集合(Set)是Python中的一种常用数据结构,专门用于存储不重复的元素。在数据处理中,集合操作常被用来处理去重、并集、交集等问题。尤其在处理多个数据集时,交集操作尤为重要,因为它可以帮助我们找到多个集合中都存在的共同元素。本文将详细探讨如何在Python中高效地进行多个集合的交集操......
  • ffplay python 播放rtsp ffmpeg播放rtsp流
    ffmpeg播放RTSP的一点优化: AVDictionary参数配置。 https://www.ffmpeg.org/doxygen/trunk/libavformat_2options__table_8h-source.html 基于ffmpeg的播放器起播延迟优化 :probesize ONVIF、RTSP/RTP、FFMPEG的开发实录: 这里注意多线程问题,如果你用FFMPEG解多......
  • Python 中常见的数据结构(一)
    Python中常见的数据结构(一)Python是一种功能强大且灵活的编程语言,它提供了多种内置的数据结构,可以帮助我们更好地组织和处理数据。在这个文章中,我们将探讨Python中最常见的一些数据结构,并结合实例来演示它们的使用。1.字典(Dictionary)字典是一种键值对的数据结构,它允许我们根据......
  • Python 中常见的数据结构(二)
    Python中常见的数据结构(二)6.栈(Stack)栈是一种后进先出数据结构,Python中,可以使用list类型创建一个栈,例如:stack=[]stack.append('apple')stack.append('banana')print(stack.pop())#Output:banana在上面的示例中,我们创建了一个名为stack的栈,然后使用append方法添加......
  • Python 实现自动配置华为交换机
    Python实现自动配置华为交换机在网络运维中,配置交换机是非常重要的一步。如果我们可以使用Python来实现配置交换机,那么我们的工作效率将会大大提高。在本文中,我们将学习如何使用Python配置华为交换机。背景知识华为交换机是一种常用的网络设备,用于连接和转发数据包。为了配置......
  • Python 语法糖:让编程更简单(续三)
    Python语法糖:让编程更简单(续三)15.DictionarycomprehensionsDictionarycomprehensions是Python中的一种语法糖,用于简化字典的创建。例如:numbers=[1,2,3,4,5]squared_numbers_dict={x:x**2forxinnumbers}print(squared_numbers_dict)#prints{1:1,2:4,......
  • 让 Python 和 Web 世界合二为一
    Python操作浏览器:让Python和Web世界合二为一在日常开发中,我们经常需要与浏览器进行交互,以实现特定的任务,如爬取网页信息、自动化测试或执行某些操作。这时,Python的一些库和框架可以帮助我们轻松地操作浏览器。下面,我们将探讨Python操作浏览器的方法和示例。SeleniumSeleniu......