当前位置: 首页 > news >正文

python:基于pyside6的桌宠源码分享

前言

        这是一份简易的桌宠制作代码,能够为你自建桌宠底层逻辑提供一些必要的帮助。

        一个基于PySide6的桌面宠物程序实现方案,支持电脑CPU、内存、GPU信息窗口显示。

必要的触发动作方法讲解

        在 PySide6 中,触发动作方法通常与事件(Events)和信号(Signals)相关。事件是用户操作(如鼠标点击、键盘按键等)或系统操作(如窗口大小改变)产生的通知,而信号是对象状态改变时发出的消息,它们都可以用来触发特定的方法。 

实现类型事件类型方法名 方法
事件处理方法重写鼠标事件mousePressEvent鼠标按下时触发。
mouseReleaseEvent鼠标释放时触发。
mouseDoubleClickEvent鼠标双击时触发。
mouseMoveEvent鼠标移动时触发。
键盘事件keyPressEvent键盘按键按下时触发。
keyReleaseEvent键盘按键释放时触发。
窗口事件resizeEvent窗口大小改变时触发。
moveEvent窗口位置移动时触发。
closeEvent窗口关闭时触发。
焦点事件focusInEvent控件获得焦点时触发。
focusOutEvent控件失去焦点时触发。
信号与槽连接触发按钮类clicked按钮被点击时发出信号。
pressed按钮被按下时发出信号。
released按钮被释放时发出信号。
复选框和单选框stateChanged复选框或单选框状态改变时发出信号。
滑块valueChanged滑块的值改变时发出信号。
下拉框currentIndexChanged下拉框当前选中项的索引改变时发出信号。
currentTextChanged下拉框当前选中项的文本改变时发出信号。
文本输入框textChanged文本输入框中的文本改变时发出信号。
editingFinished文本输入框编辑完成(如按下回车键或失去焦点)时发出信号。
定时器触发startTimer启动一个定时器,定时器超时会触发 timerEvent 方法。可以通过设置不同的时间间隔来控制触发频率。

一个动态的硬件信息获取桌宠demo 

        一个基于PySide6的桌面宠物程序实现方案。支持两种显示模式:图片序列和GIF动画,可通过鼠标事件控制宠物移动、切换动画(右键)和显示系统信息(双击)。系统信息窗口会展示CPU、内存、GPU等硬件数据。 

 

 

import os
import platform
import sys
import threading
from PySide6.QtCore import Qt, QTimer, QPoint
from PySide6.QtGui import QPixmap, QMovie, QAction
from PySide6.QtWidgets import QApplication, QWidget, QLabel, QMenu, QDialog, QVBoxLayout
from typing import Literal
from pathlib import Path
import psutiltry:import pynvmlpynvml.nvmlInit()handle = pynvml.nvmlDeviceGetHandleByIndex(0)
except ImportError:print("pynvml 未安装,无法监控 GPU 信息。")handle = NoneSHOW_TYPES = ["image", "gif"]
ALLOW_RIGHT_CHANGES = ["gif"]
LITER_TYPES = Literal["image", "gif"]class SequenceData():def __init__(self, files, type: LITER_TYPES = "image", imageTimerMS=100) -> None:self.files = []self.type = typeself.imageTimerMS = imageTimerMSif len(files) == 0:raise Exception("未提供媒体素材。")if type == "image":ext_needs = [".png", ".jpg", ".jpeg"]elif type == "gif":ext_needs = [".gif"]else:raise Exception(f"意料之外的错误-异常类型检测:{type}")for f in files:if not os.path.exists(f):raise Exception(f"资源:【{f}】 不存在。")if Path(f).suffix.lower() not in ext_needs:raise Exception(f"文件后缀检测不通过({ext_needs}):{f}")abs_path = os.path.abspath(f)self.files.append(abs_path)class InfoDialog(QDialog):def __init__(self, parent=None):super().__init__(parent)self.setWindowTitle("系统信息")layout = QVBoxLayout()self.info_label = QLabel(self)layout.addWidget(self.info_label)self.setLayout(layout)class DesktopPet(QWidget):def __init__(self, sequenceData: SequenceData):super().__init__()self.sequenceData = sequenceDataself.current_frame = 0self.videoIndex = 0self.maxVideoIndex = len(sequenceData.files) - 1self.pet_images = []self.movie = Noneself.label = QLabel(self)self.init()def init(self):# 設定無窗、釘選在畫面上self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)self.setAttribute(Qt.WA_TranslucentBackground, True)# 设置if self.sequenceData.type == "image":for f in self.sequenceData.files:self.pet_images.append(QPixmap(f))self.label.setPixmap(self.pet_images[self.current_frame])self.label.resize(self.pet_images[self.current_frame].size())# 切換图片self.timer = QTimer(self)self.timer.timeout.connect(self.updateAnimation)self.timer.start(self.sequenceData.imageTimerMS)elif self.sequenceData.type in ["gif"]:print(self.sequenceData.files[0])self.movie = QMovie(self.sequenceData.files[0])self.label.setMovie(self.movie)self.movie.start()self.movie.frameChanged.connect(self.resizeToMovie)# 拖拉用的位置self.drag_position = QPoint()def resizeToMovie(self):self.label.resize(self.movie.currentPixmap().size())self.resize(self.movie.currentPixmap().size())def updateAnimation(self):if self.sequenceData.type == "image":self.current_frame = (self.current_frame + 1) % len(self.sequenceData.files)self.label.setPixmap(self.pet_images[self.current_frame])self.label.resize(self.pet_images[self.current_frame].size())def videoUpdateAnimation(self):nextVideoIndex = self.videoIndex + 1if nextVideoIndex > self.maxVideoIndex:nextVideoIndex = 0self.movie = QMovie(self.sequenceData.files[nextVideoIndex])self.label.setMovie(self.movie)self.movie.start()self.movie.frameChanged.connect(self.resizeToMovie)self.videoIndex = nextVideoIndex# # 右键菜单# def contextMenuEvent(self, event):#     # 创建一个右键菜单#     menu = QMenu(self)##     # 创建菜单项#     action1 = QAction('选项1', self)#     action2 = QAction('选项2', self)##     # 为菜单项绑定槽函数#     action1.triggered.connect(self.action1_triggered)#     action2.triggered.connect(self.action2_triggered)##     # 将菜单项添加到菜单中#     menu.addAction(action1)#     menu.addAction(action2)##     # 在鼠标右键点击的位置显示菜单#     menu.exec(event.globalPos())## def action1_triggered(self):#     print('选项1被点击')## def action2_triggered(self):#     print('选项2被点击')def mousePressEvent(self, event):if event.button() == Qt.LeftButton:self.drag_position = event.globalPosition().toPoint() - self.frameGeometry().topLeft()elif event.button() == Qt.RightButton:if self.sequenceData.type in ALLOW_RIGHT_CHANGES:self.videoUpdateAnimation()def mouseMoveEvent(self, event):if event.buttons() == Qt.LeftButton:self.move(event.globalPosition().toPoint() - self.drag_position)def get_system_info(self):# 获取CPU名称cpu_name = platform.processor()# 获取内存信息memory_total = round(psutil.virtual_memory().total / (1024 ** 3), 2)# 获取 CPU 使用率cpu_percent = psutil.cpu_percent(interval=0.5)# 获取内存使用率memory_percent = psutil.virtual_memory().percenttry:# 获取 GPU 使用率和温度if handle:gpu_utilization = pynvml.nvmlDeviceGetUtilizationRates(handle).gpu# 获取GPU名称gpu_name = pynvml.nvmlDeviceGetName(handle)gpu_temp = pynvml.nvmlDeviceGetTemperature(handle, pynvml.NVML_TEMPERATURE_GPU)else:gpu_utilization = "N/A"gpu_temp = "N/A"except Exception as e:gpu_utilization = "N/A"gpu_temp = "N/A"gpu_name = "N/A"print(e)return cpu_name, cpu_percent, memory_total, memory_percent, gpu_name, gpu_utilization, gpu_tempdef mouseDoubleClickEvent(self, event):if event.button() == Qt.RightButton:a = threading.Thread(target=self.create_cmsg_window)a.start()def create_cmsg_window(self):# 获取 CPU 使用率cpu_percent = psutil.cpu_percent(interval=1)# 获取 GPU 信息(假设只有一个 NVIDIA GPU)try:cpu_name, cpu_percent, memory_total, memory_percent, gpu_name, gpu_utilization, gpu_temp = self.get_system_info()except Exception as e:cpu_name = "N/A"gpu_utilization = "N/A"gpu_temp = "N/A"memory_total = "N/A"memory_percent = "N/A"# 创建并显示新的对话框info_text = f"CPU 名称: {cpu_name}\nCPU 使用率: {cpu_percent}%\n\n内存使用情况:{memory_total}GB|{memory_percent}%\n\nGPU 名称: {gpu_name}\nGPU 使用率: {gpu_utilization}%\nGPU 温度: {gpu_temp}°C"dialog = InfoDialog(self)dialog.info_label.setText(info_text)dialog.exec()if __name__ == '__main__':app = QApplication(sys.argv)try:gifs = []for root, dirs, files in os.walk('appendix/gifs'):gifs = [os.path.join(root, file) for file in files]sequenceData = SequenceData(gifs, "gif")pet = DesktopPet(sequenceData)pet.show()sys.exit(app.exec())except Exception as e:print(e)
http://www.xdnf.cn/news/908479.html

相关文章:

  • java面试场景提题:
  • 全球知名具身智能/AI机器人实验室介绍之AI FACTORY基于慕尼黑工业大学
  • 数字孪生:如同为现实世界打造的“克隆体”,解锁无限可能
  • RabbitMQ 队列模式
  • CRM管理软件的审批流程设计与优化:提升企业运营效率的关键策略
  • DLL动态库实现文件遍历功能(Windows编程)
  • 浅谈不同二分算法的查找情况
  • hot100 -- 8.二叉树系列
  • 3D Web轻量化引擎HOOPS Communicator的定制化能力全面解析
  • LlamaIndex 工作流简介以及基础工作流
  • Linux驱动:class_create、device_create
  • java面试场景题:电商平台中订单未⽀付过期如何实现⾃动关单
  • 本地部署企业邮箱,让企业办公更安全高效
  • 【51单片机】0. 基础软件安装
  • Blazor-表单提交的艺术:如何优雅地实现 (下)
  • WorldExplorer:基于文本生成的可探索3D虚拟世界
  • 深克隆java对象的方式
  • 基于 openEuler 22.03 LTS SP1 构建 DPDK 22.11.8 开发环境指南
  • Xshell 详细安装与配置教程:从下载到高效使用
  • error: subprocess-exited-with-error【已解决】
  • docker 部署redis集群 配置
  • 【学习笔记】单例类模板
  • 深入理解二叉搜索树:原理到实践
  • libGL error
  • IDEA安装迁移IDEA配置数据位置
  • SQL进阶之旅 Day 19:统计信息与优化器提示
  • 10个成功案例剖析|融质AI创新实践
  • 【多线程初阶】阻塞队列 生产者消费者模型
  • Python备忘
  • CST人工电源网络阻抗计量校准