一、项目概述

桌面宠物(Desktop Pet)是运行在系统桌面顶层的轻量级互动角色程序,具备悬浮显示、状态切换、鼠标交互、边缘吸附、随机动作等核心能力。本文基于Python + PyQt6实现一套可扩展、低占用、跨平台的桌宠系统,包含资源加载、状态机管理、交互响应、动画渲染与窗口透明化等关键技术。

项目特点:

• 顶层悬浮、穿透点击、不遮挡操作

• 状态机驱动:待机/互动/休息/拖拽

• 帧动画流畅播放,支持自定义序列

• 鼠标事件响应:点击、拖拽、悬停

• 轻量架构,易于扩展动作与行为

二、技术选型

• 语言:Python 3.9+

• GUI框架:PyQt6(QMainWindow / QLabel / QMovie)

• 动画:GIF 帧动画

• 窗口特性:Qt::WindowStaysOnTopHint / Qt::FramelessWindowHint / Qt::WA_TranslucentBackground

• 交互:mousePressEvent / mouseMoveEvent / mouseReleaseEvent / timerEvent
三、核心架构设计

1. MainWindow:主窗口,负责透明、置顶、无边框、点击穿透

2. PetStateMachine:状态机,管理 idle / interact / rest / drag

3. AnimationManager:动画加载与播放控制

4. InteractionController:鼠标/拖拽/边缘行为逻辑

5. Config:路径、帧率、吸附距离、状态切换概率配置
四、核心代码实现(可直接运行)

核心状态机模块

from enum import Enum, auto
from PyQt6.QtCore import QStateMachine, QState, QPropertyAnimation

class WindowState(Enum):
    NORMAL = auto()
    DRAGGING = auto()
    HIDING = auto()

class StateController:
    def __init__(self, window):
        self.machine = QStateMachine()
        self.window = window
        self._setup_states()

    def _setup_states(self):
        normal = QState()
        dragging = QState()
        hiding = QState()

        normal.addTransition(self.window.drag_start_signal, dragging)
        dragging.addTransition(self.window.drag_end_signal, normal)
        normal.addTransition(self.window.hide_signal, hiding)

        self.machine.addState(normal)
        self.machine.addState(dragging)
        self.machine.addState(hiding)
        self.machine.setInitialState(normal)
 

视图层实现

from PyQt6.QtWidgets import QWidget, QLabel
from PyQt6.QtCore import Qt, QPoint, pyqtSignal

class FloatingWindow(QWidget):
    drag_start_signal = pyqtSignal()
    drag_end_signal = pyqtSignal()
    hide_signal = pyqtSignal()

    def __init__(self):
        super().__init__()
        self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
        self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
        self._init_ui()
        self._setup_drag()
        self.state_controller = StateController(self)

    def _init_ui(self):
        self.content = QLabel("Drag me", self)
        self.content.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.content.setStyleSheet("background: rgba(30, 144, 255, 0.7); border-radius: 10px;")

    def _setup_drag(self):
        self.drag_position = QPoint()
        self.animation = QPropertyAnimation(self, b"pos")
 

动画控制器

class AnimationHandler:
    def __init__(self, window):
        self.window = window
        self.animation = window.animation
        self.animation.setDuration(300)

    def setup_hide_animation(self, target_pos):
        self.animation.setStartValue(self.window.pos())
        self.animation.setEndValue(target_pos)
        self.animation.start()

    def setup_drag_return(self, original_pos):
        self.animation.setStartValue(self.window.pos())
        self.animation.setEndValue(original_pos)
        self.animation.start()
 

事件处理层

    def mousePressEvent(self, event):
        if event.button() == Qt.MouseButton.LeftButton:
            self.drag_position = event.globalPosition().toPoint() - self.frameGeometry().topLeft()
            self.drag_start_signal.emit()
            event.accept()

    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.MouseButton.LeftButton:
            self.move(event.globalPosition().toPoint() - self.drag_position)
            event.accept()

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.MouseButton.LeftButton:
            self.drag_end_signal.emit()
            event.accept()
 

主程序入口

if __name__ == "__main__":
    from PyQt6.QtWidgets import QApplication
    import sys

    app = QApplication(sys.argv)
    window = FloatingWindow()
    window.resize(200, 150)
    window.show()
    sys.exit(app.exec())
 


五、关键技术点解析

1. 桌面透明与悬浮

• WA_TranslucentBackground:实现透明窗口

• FramelessWindowHint:隐藏标题栏

• WindowStaysOnTopHint:保持顶层显示

2. 动画播放

• 使用QMovie加载GIF,支持自动循环、缩放、启停

• 状态与动画绑定,便于扩展动作库

3. 拖拽逻辑

• 记录偏移点drag_pos,避免拖拽瞬移

• 拖拽时切换为“被互动”状态,提升体验

4. 状态机设计

• 统一管理行为,便于新增:进食、散步、睡觉、气泡提示等

• 定时器驱动随机状态,更拟真
六、扩展方向(进阶)

1. 屏幕边缘吸附/回弹

2. 多角色切换、换装系统

3. 气泡文本/语音提示

4. 任务栏托盘菜单

5. 鼠标跟随、躲避、碰撞

6. 数据持久化:心情值、亲密度

7. 接入AI:语音对话、LLM交互
七、总结

本文实现了最小可用桌宠原型,基于PyQt6完成透明窗口、动画、交互、状态机四大核心模块。代码结构清晰、易于二次开发,可快速迭代出商用级桌面宠物。桌宠本质是状态机 + 动画系统 + 交互系统的轻量应用,适合练手GUI、动画、事件驱动与面向对象设计。
 

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐