马上注册,结交更多好友,享用更多功能,让你轻松玩转小K网。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
花哨桌面 经过几个版本的迭代 这个版本将是最后的版本,修复了之前群友们提出的一些问题.同时增加了一些优化
1.新增了托盘功能
退出
切换主题
启动开机启动
启动背景替换
设置图片大小
2.完善了更多主题,可选择,总有一款你喜欢的吧.........
灌篮高手
海贼王
火影忍者
马里奥
哪吒
七龙珠
犬夜叉
默认(宫崎骏风格)
3.摸鱼背景小游戏分数统计
4.自定义主题,大家可以根据自己喜好,在程序下面创建自己的资源,按照格式增加自己的主题风格,自己拓展
5.目前是win10系统开发的 win不兼容,会一点点编程的用源码自己编译改造下哦,随后源码奉上
6.程序也就是学习中突发灵感随手做的项目,大家勿喷哦,就是个娱乐的小玩意
7.软件也就不更新了,搞别的玩去了
下载链接
通过网盘分享的文件:花哨桌面(最终版本).rar
链接: https://pan.baidu.com/s/1YnVzRQE9YOAUoT5bg8VpoA?pwd=tnrj 提取码: tnrj
主题:
花哨桌面 V 4.0.0 (最终版)
源码:
- import ctypes
- import os
- import random
- import sys
- import time
- import configparser
-
- import winshell
- from PyQt5.QtCore import Qt, QTimer, QPoint
- from PyQt5.QtGui import QPainter, QColor, QPixmap, QCursor, QFont, QIcon
- from PyQt5.QtWidgets import QApplication, QWidget, QSystemTrayIcon, QMenu, QAction, QInputDialog, QMessageBox
- from PyQt5.QtGui import QMovie
- from PyQt5.QtWidgets import QLabel
-
- influence_range = 30 # 鼠标影响范围
- QPixmap_size = 150 # 图标大小范围
-
-
- # 开机自动启动实现
- def add_to_startup():
- """通过创建启动项实现开机自动启动"""
- try:
- import winshell
- from win32com.client import Dispatch
- except ImportError:
- print("请安装依赖库:pip install pywin32 winshell")
- return
-
- startup_folder = winshell.startup() # 获取启动目录
- print("添加到启动项:", startup_folder)
- shortcut_path = os.path.join(startup_folder, "花哨桌面.lnk")
- if not os.path.exists(shortcut_path):
- shell = Dispatch('WScript.Shell')
- shortcut = shell.CreateShortCut(shortcut_path)
- # 判断是否是打包后的exe环境
- if getattr(sys, 'frozen', False):
- # 打包后的exe路径
- executable_path = sys.executable
- else:
- # 开发环境,使用当前脚本路径
- executable_path = os.path.abspath(__file__)
- # 快捷方式直接指向 .exe 文件,无需额外参数
- shortcut.Targetpath = executable_path
- shortcut.Arguments = '' # 因为目标已经是exe,不需要参数
- shortcut.WorkingDirectory = os.path.dirname(executable_path) # 设置工作目录为exe所在目录
- shortcut.save()
- print("已添加到开机启动项")
- else:
- print("已存在开机启动项")
-
-
- # 获取桌面窗口句柄并嵌入
- def get_desktop_window():
- # 查找ProgMan窗口
- progman = ctypes.windll.user32.FindWindowW('ProgMan', None)
- # 发送0x052C消息生成WorkerW窗口
- ctypes.windll.user32.SendMessageW(progman, 0x052C, 0, 0)
- hwnd = ctypes.windll.user32.FindWindowExW(None, None, 'WorkerW', None)
- while hwnd:
- # 查找包含SHELLDLL_DefView的子窗口
- shell_view = ctypes.windll.user32.FindWindowExW(hwnd, None, 'SHELLDLL_DefView', None)
- if shell_view:
- return hwnd
- hwnd = ctypes.windll.user32.FindWindowExW(None, hwnd, 'WorkerW', None)
- return None
-
-
- def get_resource_path(relative_path):
- """获取资源文件的路径,支持开发环境和打包后的 exe 环境"""
- base_path = os.path.abspath(".")
- # 判断是否是打包后的exe环境
- if getattr(sys, 'frozen', False):
- # 打包后的exe路径
- base_path = sys.executable
- else:
- # 开发环境,使用当前脚本路径
- base_path = os.path.abspath(__file__)
- return os.path.join(os.path.dirname(base_path) , relative_path)
-
-
- def get_base_path():
- """获取资源文件的基础路径"""
- return get_resource_path("")
-
-
- class Snowflake:
- def __init__(self, max_width, max_height, image_paths):
- self.x = random.randint(0, max_width)
- self.y = random.randint(-max_height, 0) # 从屏幕上方随机位置生成
- self.vx = random.uniform(-1, 1)
- self.vy = random.uniform(0.5, 1.5) # 向下飘落的速度
- self.radius = random.randint(5, 10)
- self.color = QColor(255, 255, 255, 200)
- # 随机加载素材目录下的图片
- image_path = random.choice(image_paths)
- self.image_name = os.path.basename(image_path) # 获取图片名称
- self.pixmap = QPixmap(image_path)
- self.pixmap = self.pixmap.scaled(self.radius * 3, self.radius * 3, Qt.KeepAspectRatio, Qt.SmoothTransformation)
-
- def move(self, max_width, max_height, mouse_pos=None, speed_increment=0):
- # 如果有鼠标位置信息,检测是否需要弹开
- if mouse_pos:
- mouse_x, mouse_y = mouse_pos
- distance = ((self.x - mouse_x) ** 2 + (self.y - mouse_y) ** 2) ** 0.5
- if distance < influence_range: # 增大鼠标影响范围阈值
- self.vx = (self.x - mouse_x) * 0.2 # 增强弹开力度
- self.vy = -(self.y - mouse_y) * 0.2 # 增强弹开力度
- self.x += self.vx * 3 # 增强弹开力度
- self.y += self.vy * 3 # 增强弹开力度
- else:
- self.x += self.vx
- self.y += self.vy + speed_increment # 动态调整速度
- else:
- self.x += self.vx
- self.y += self.vy + speed_increment # 动态调整速度
-
- # 判断是否到达地面或逃出边界
- if self.y >= max_height or self.x < 0 or self.x > max_width:
- return False # 需要销毁
- return True # 继续存在
-
- def draw(self, painter):
- # 使用图片绘制
- # 将 self.x 和 self.y 转换为整数类型
- painter.drawPixmap(QPoint(int(self.x - self.radius), int(self.y - self.radius)), self.pixmap)
-
-
- class DynamicWallpaper(QWidget):
- def __init__(self):
- super().__init__()
- self.base_path = get_base_path() # 获取基础路径
- self.config_path = get_resource_path("花哨.ini")
- self.config = configparser.ConfigParser()
- self.config.read(self.config_path)
-
- # 初始化主题相关变量
- self.current_theme = self.config.get("Settings", "Theme", fallback="默认主题")
- self.themes = self.load_themes()
- self.load_theme(self.current_theme)
-
- # 初始化开机启动状态
- self.startup_enabled = self.config.getboolean("Settings", "Startup", fallback=False)
-
- # 新增:初始化桌面背景修改状态
- self.modify_background_enabled = self.config.getboolean("Settings", "ModifyBackground", fallback=True)
-
- # 初始化系统托盘
- self.tray_icon = QSystemTrayIcon(self)
- self.init_tray_icon()
-
- # 初始化扫把图片列表
- self.broom_pixmap_list = self.load_broom_pixmaps()
- self.current_boomGif = QMovie(os.path.join(self.theme_dir, "boom.gif"))
- self.current_boom = 0
- self.current_broom_index = 0
- self.collision_count = 0
- self.collision_max = 0
- self.image_name = None
- self.broom_effect_duration = QPixmap_size
- self.last_collision_time = 0
-
- # 初始化窗口属性
- self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowTransparentForInput)
- self.setAttribute(Qt.WA_TranslucentBackground)
- self.setGeometry(0, 0, QApplication.desktop().screenGeometry().width(),
- QApplication.desktop().screenGeometry().height())
-
- # 初始化gif窗口属性
- self.gif_label = QLabel(self)
- self.gif_label.setScaledContents(True)
- self.gif_label.hide()
-
- # 创建元素
- self.snowflakes = set()
- for _ in range(50):
- self.snowflakes.add(Snowflake(self.width(), self.height(), self.snowflake_image_paths))
-
- # 定时器更新动画
- self.timer = QTimer(self)
- self.timer.timeout.connect(self.update_snowflakes)
- self.timer.start(30)
-
- # 嵌入到桌面窗口
- desktop_hwnd = get_desktop_window()
- if desktop_hwnd:
- self.winId()
- ctypes.windll.user32.SetParent(int(self.windowHandle().winId()), desktop_hwnd)
-
- self.mouse_pos = None
-
- # 初始化配置项
- self.influence_range = self.config.getint("Settings", "InfluenceRange", fallback=30)
- self.QPixmap_size = self.config.getint("Settings", "QPixmapSize", fallback=150)
-
- def load_broom_pixmaps(self):
- """加载扫把图片"""
- broom_dir = get_resource_path(os.path.join("花哨桌面", self.current_theme, "头像"))
- if not os.path.exists(broom_dir):
- raise FileNotFoundError(f"头像目录不存在: {broom_dir}")
- return [
- QPixmap(os.path.join(broom_dir, f)).scaled(QPixmap_size, QPixmap_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
- for f in random.sample(
- [f for f in os.listdir(broom_dir) if f.endswith(".png")],
- k=len([f for f in os.listdir(broom_dir) if f.endswith(".png")])
- )
- ]
-
- def load_themes(self):
- """加载所有主题"""
- themes_dir = get_resource_path("花哨桌面")
- if not os.path.exists(themes_dir) or not os.path.isdir(themes_dir):
- raise FileNotFoundError(f"主题目录不存在或路径无效: {themes_dir}")
- return [d for d in os.listdir(themes_dir) if os.path.isdir(os.path.join(themes_dir, d))]
-
- def load_theme(self, theme_name):
- """加载指定主题"""
- self.theme_dir = os.path.join(self.base_path, "花哨桌面", theme_name)
- self.current_theme = theme_name
-
- # 加载头像和素材
- self.broom_pixmap_list = self.load_broom_pixmaps()
-
- # 加载素材目录下的图片
- self.snowflake_image_paths = [
- os.path.join(self.theme_dir, "素材", f)
- for f in os.listdir(os.path.join(self.theme_dir, "素材"))
- if f.endswith(".png")
- ]
-
- # 新增:根据配置文件决定是否修改桌面背景
- if self.config.getboolean("Settings", "ModifyBackground", fallback=True):
- # 加载 back 文件夹中的图片文件并设置为桌面背景
- back_dir = os.path.join(self.theme_dir, "back")
- if os.path.exists(back_dir):
- back_files = [f for f in os.listdir(back_dir) if f.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp'))]
- if back_files:
- back_image_path = os.path.join(back_dir, back_files[0])
- self.set_desktop_background(back_image_path)
-
- # 加载 boom.gif
- self.current_boomGif = QMovie(os.path.join(self.theme_dir, "boom.gif"))
- self.current_boomGif.start()
-
- # 重新生成雪花元素
- self.snowflakes = set()
- for _ in range(50):
- self.snowflakes.add(Snowflake(self.width(), self.height(), self.snowflake_image_paths))
-
- def set_desktop_background(self, image_path):
- """使用 Windows API 设置桌面背景"""
- SPI_SETDESKWALLPAPER = 20
- ctypes.windll.user32.SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, image_path, 3)
-
- def init_tray_icon(self):
- """初始化系统托盘"""
- self.tray_icon.setIcon(QIcon(QPixmap("花哨.png"))) # 设置托盘图标
- self.tray_icon.setToolTip("花哨桌面")
-
- # 创建托盘菜单
- menu = QMenu()
-
- # 主题切换菜单
- theme_menu = QMenu("切换主题", self)
- for theme in self.themes:
- action = QAction(theme, self)
- action.triggered.connect(lambda _, t=theme: self.switch_theme(t))
- # 如果当前主题与菜单项一致,在名称前添加选中标记
- if theme == self.current_theme:
- action.setText(f"{theme} ✓")
- theme_menu.addAction(action)
- menu.addMenu(theme_menu)
-
- # 开机启动开关
- self.startup_action = QAction("启用开机启动", self, checkable=True)
- self.startup_action.setChecked(self.startup_enabled) # 使用配置文件中的值
- self.startup_action.triggered.connect(self.toggle_startup)
- menu.addAction(self.startup_action)
-
- # 新增:桌面背景修改开关
- self.modify_background_action = QAction("启用桌面背景修改", self, checkable=True)
- self.modify_background_action.setChecked(self.config.getboolean("Settings", "ModifyBackground", fallback=True))
- self.modify_background_action.triggered.connect(self.toggle_modify_background)
- menu.addAction(self.modify_background_action)
-
- # 添加鼠标影响范围设置
- influence_range_action = QAction("设置鼠标影响范围", self)
- influence_range_action.triggered.connect(self.set_influence_range)
- menu.addAction(influence_range_action)
-
- # 添加图标大小设置
- pixmap_size_action = QAction("设置图标大小", self)
- pixmap_size_action.triggered.connect(self.set_QPixmap_size)
- menu.addAction(pixmap_size_action)
-
- exit_action = QAction("退出", self)
- exit_action.triggered.connect(self.close)
- menu.addAction(exit_action)
-
- self.tray_icon.setContextMenu(menu)
- self.tray_icon.show()
-
- def switch_theme(self, theme_name):
- """切换主题"""
- self.load_theme(theme_name)
- self.update()
- self.update_tray_menu()
- # 保存当前主题到配置文件
- self.save_config()
-
- def update_tray_menu(self):
- """更新托盘菜单内容"""
- menu = self.tray_icon.contextMenu()
- menu.clear()
-
- # 主题切换菜单
- theme_menu = QMenu("切换主题", self)
- for theme in self.themes:
- action = QAction(theme, self)
- action.triggered.connect(lambda _, t=theme: self.switch_theme(t))
- # 如果当前主题与菜单项一致,在名称前添加选中标记
- if theme == self.current_theme:
- action.setText(f"{theme} ✓")
- theme_menu.addAction(action)
- menu.addMenu(theme_menu)
-
- # 开机启动开关
- self.startup_action = QAction("启用开机启动", self, checkable=True)
- self.startup_action.setChecked(os.path.exists(os.path.join(winshell.startup(), "花哨桌面.lnk")))
- self.startup_action.triggered.connect(self.toggle_startup)
- menu.addAction(self.startup_action)
-
- # 新增:桌面背景修改开关
- self.modify_background_action = QAction("启用桌面背景修改", self, checkable=True)
- self.modify_background_action.setChecked(self.config.getboolean("Settings", "ModifyBackground", fallback=True))
- self.modify_background_action.triggered.connect(self.toggle_modify_background)
- menu.addAction(self.modify_background_action)
-
- # 添加鼠标影响范围设置
- influence_range_action = QAction("设置鼠标影响范围", self)
- influence_range_action.triggered.connect(self.set_influence_range)
- menu.addAction(influence_range_action)
-
- # 添加图标大小设置
- pixmap_size_action = QAction("设置图标大小", self)
- pixmap_size_action.triggered.connect(self.set_QPixmap_size)
- menu.addAction(pixmap_size_action)
-
- exit_action = QAction("退出", self)
- exit_action.triggered.connect(self.close)
- menu.addAction(exit_action)
-
- def toggle_startup(self):
- """启用/禁用开机启动"""
- self.startup_enabled = not self.startup_enabled
- self.update_startup_status()
- # 保存开机启动状态到配置文件
- self.save_config()
-
- def update_startup_status(self):
- """更新开机启动状态"""
- if self.startup_enabled:
- add_to_startup()
- else:
- startup_folder = winshell.startup()
- shortcut_path = os.path.join(startup_folder, "花哨桌面.lnk")
- if os.path.exists(shortcut_path):
- os.remove(shortcut_path)
-
- def toggle_modify_background(self):
- """启用/禁用桌面背景修改"""
- self.modify_background_enabled = not self.modify_background_enabled
- self.update_modify_background_status()
- # 保存桌面背景修改状态到配置文件
- self.save_config()
-
- def update_modify_background_status(self):
- """更新桌面背景修改状态"""
- if self.modify_background_enabled:
- self.load_theme(self.current_theme) # 重新加载主题以应用背景修改
- else:
- # 恢复默认桌面背景
- SPI_SETDESKWALLPAPER = 20
- ctypes.windll.user32.SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, "", 3)
-
- def set_influence_range(self):
- """设置鼠标影响范围"""
- new_value, ok = QInputDialog.getInt(self, "设置鼠标影响范围", "请输入新的鼠标影响范围值:", self.influence_range, 20, 50)
- if ok:
- self.influence_range = new_value
- self.save_config()
- QMessageBox.information(self, "成功", f"鼠标影响范围已设置为 {new_value}")
-
- def set_QPixmap_size(self):
- """设置图标大小"""
- new_value, ok = QInputDialog.getInt(self, "设置图标大小", "请输入新的图标大小值:", self.QPixmap_size, 50, 200)
- if ok:
- self.QPixmap_size = new_value
- self.save_config()
- QMessageBox.information(self, "成功", f"图标大小已设置为 {new_value}")
-
- def save_config(self):
- """保存配置到花哨.ini"""
- if not self.config.has_section("Settings"):
- self.config.add_section("Settings")
- self.config.set("Settings", "Theme", self.current_theme)
- self.config.set("Settings", "Startup", str(self.startup_enabled))
- self.config.set("Settings", "ModifyBackground", str(self.modify_background_enabled)) # 新增配置项
- self.config.set("Settings", "InfluenceRange", str(self.influence_range))
- self.config.set("Settings", "QPixmapSize", str(self.QPixmap_size))
- with open(self.config_path, "w") as config_file:
- self.config.write(config_file)
-
- def play_gif_at_position(self, position):
- self.gif_label.setMovie(self.current_boomGif)
- self.gif_label.resize(QPixmap_size, QPixmap_size) # 设置大小
- self.gif_label.move(position.x(), position.y()) # 移动到指定位置
- self.current_boomGif.start()
- self.gif_label.show()
- # 设置定时器,在 2 秒后隐藏和停止动画
- QTimer.singleShot(1000, lambda: self.stop_gif(self.current_boomGif))
-
- def stop_gif(self, movie):
- movie.stop()
- self.gif_label.hide()
-
- def update_snowflakes(self):
- # 根据 collision_count 计算速度增量
- speed_increment = (self.collision_count // 10) * 0.5 # 每增加 10,速度增加 0.1
- # speed_increment = (self.collision_count // 1) * 1
- for flake in list(self.snowflakes): # 使用 list 复制集合以避免修改时迭代
- if not flake.move(self.width(), self.height(), self.mouse_pos, speed_increment): # 如果需要销毁
- self.snowflakes.remove(flake) # 移除
- self.snowflakes.add(
- Snowflake(self.width(), self.height(), self.snowflake_image_paths)) # 在顶部生成新的,传递 image_paths 参数
- self.update() # 触发重绘
-
- def get_current_time(self):
- return int(time.time() * 1000) # 毫秒级时间戳
-
- def paintEvent(self, event):
- painter = QPainter(self)
- painter.setRenderHint(QPainter.Antialiasing)
- # 获取鼠标当前位置
- mouse_pos = QCursor.pos()
- mouse_pos = self.mapFromGlobal(mouse_pos)
- current_broom = self.broom_pixmap_list[self.current_broom_index]
- # 绘制扫把
- if self.current_boom == 0:
- painter.drawPixmap(
- mouse_pos.x() - current_broom.width() // 2 + 40,
- mouse_pos.y() + 20,
- current_broom
- )
- else:
- self.play_gif_at_position(mouse_pos)
-
- # 绘制元素
- for flake in self.snowflakes:
- # 计算距离
- distance = ((flake.x - mouse_pos.x()) ** 2 + (flake.y - mouse_pos.y()) ** 2) ** 0.5
- if distance < influence_range: # 鼠标影响范围阈值
- current_time = self.get_current_time()
- flake.vx = (flake.x - mouse_pos.x()) * 0.2
- flake.vy = -(flake.y - mouse_pos.y()) * 0.2
- flake.x += flake.vx * 3
- flake.y += flake.vy * 3
- flake.color.setAlpha(255)
- self.current_broom_index = (self.current_broom_index + 1) % len(self.broom_pixmap_list)
- # 基于素材记录碰撞逻辑
- if current_time - self.last_collision_time > self.broom_effect_duration:
- name = flake.image_name
- # print(f"当前素材名称:{name}") # 打印图片名称
- self.last_collision_time = current_time
- if "炸弹.png" == name:
- self.current_boom = 1
- self.collision_count = 0
- else:
- self.current_boom = 0
- if self.image_name == name:
- self.collision_count += 1
- if self.collision_count > self.collision_max:
- self.collision_max = self.collision_count
- else:
- self.image_name = name # 更新上次碰撞的素材标识
- self.collision_count = 1
-
- self.update()
- else:
- flake.color.setAlpha(200) # 其他时刻保持正常透明度
- # 绘制元素
- flake.draw(painter)
- # 绘制鼠标影响范围的浅浅背景色为圆形
- painter.setPen(Qt.NoPen) # 不绘制边框
- painter.setBrush(QColor(255, 255, 255, 50)) # 半透明白色背景
-
- painter.drawEllipse(
- mouse_pos.x() - influence_range,
- mouse_pos.y() - influence_range,
- influence_range * 2,
- influence_range * 2
- )
-
- # 在窗体中央绘制碰撞次数
- painter.setPen(QColor(255, 255, 255, 200)) # 透明白色
- painter.setFont(QFont("Arial", 15))
- text = f"max: {self.collision_max} speed: {self.collision_count // 10} count: {self.collision_count}"
- text_rect = painter.boundingRect(self.rect(), Qt.AlignCenter, text)
- painter.drawText(text_rect, Qt.AlignCenter, text)
-
- # 捕获鼠标移动事件
- def mouseMoveEvent(self, event):
- self.mouse_pos = (event.x(), event.y())
-
-
- if __name__ == '__main__':
- add_to_startup()
- mutex = ctypes.windll.kernel32.CreateMutexW(None, True, "Local/SnowfallProgramMutex")
- if ctypes.windll.kernel32.GetLastError() == 0x00000010:
- print("检测到程序已在运行,即将退出...")
- sys.exit(-1)
- app = QApplication(sys.argv)
- w = DynamicWallpaper()
- w.show()
- sys.exit(app.exec_())
复制代码
|