前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >PySide6 项目开发全攻略:托盘图标&悬浮球

PySide6 项目开发全攻略:托盘图标&悬浮球

作者头像
小码农薛尧
发布2025-02-12 14:59:07
发布2025-02-12 14:59:07
11400
代码可运行
举报
文章被收录于专栏:小码农薛尧小码农薛尧
运行总次数:0
代码可运行

PySide6 项目开发全攻略:托盘图标&悬浮球

一、功能概述与实现思路

本方案通过PySide6实现两个增强功能:

功能介绍

  1. 1. 系统托盘图标:当应用窗口最小化时,程序会驻留在系统托盘区域。用户可通过右键点击该图标,呼出包含多种操作选项的菜单,便于快捷操作。
  2. 2. 桌面悬浮球:在关闭主界面后,系统会自动生成一个悬浮于桌面的小球。该悬浮球为用户提供了便捷的交互入口,可快速唤起隐藏的主界面。

实现架构:

代码语言:javascript
代码运行次数:0
复制
项目结构
├── resources/
│   ├── app_mini.ico  # 悬浮球图标
│   └── app_tray.ico  # 托盘图标
├── app_mini.py       # 悬浮球实现

状态流转示意图:

悬浮球代码实现(app_mini.py)

代码语言:javascript
代码运行次数:0
复制
import sys
from PySide6.QtWidgets import  QWidget, QVBoxLayout, QLabel
from PySide6.QtGui import  QMouseEvent, QPixmap, QGuiApplication
from PySide6.QtCore import Qt, QTimer


classFloatingBall(QWidget):
    def__init__(self, main_window):
        super().__init__()
        # 设置悬浮球背景为透明,增强视觉效果
        self.setStyleSheet("background-color: transparent;")
        self.main_window = main_window
        self.init_ui()

    definit_ui(self):
        # 设置窗口标志,使悬浮球无框、始终置顶且不显示在任务栏
        self.setWindowFlags(Qt.WindowType.FramelessWindowHint | Qt.WindowType.WindowStaysOnTopHint | Qt.WindowType.Tool)
        # 设置悬浮球的大小
        self.setGeometry(0, 0, 80, 80)
        # 设置悬浮球的初始透明度
        self.setWindowOpacity(0.8)
        self.setup_background_image()
        # 将悬浮球移动到屏幕右上角
        self.move_to_top_right()
        # 用于记录鼠标拖动时的位置
        self.dragPosition = None
        # 开启鼠标跟踪,以便处理鼠标移动事件
        self.setMouseTracking(True)
        # 启动呼吸灯效果,让悬浮球的透明度周期性变化
        self.breathing_light_window()

    defbreathing_light_window(self):
        # 初始透明度
        self.opacity = 0.2
        # 透明度每次变化的值,控制呼吸的速度和节奏
        self.direction = 0.02
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update_opacity)
        # 设置定时器间隔为 50 毫秒,可根据需要调整呼吸节奏快慢
        self.timer.start(50)

    # 更新透明度
    defupdate_opacity(self):
        self.opacity += self.direction
        ifself.opacity >= 1.0:
            self.direction = -0.02# 达到最大透明度后开始减小透明度
        elifself.opacity <= 0.2:
            self.direction = 0.02# 达到最小透明度后开始增大透明度
        self.setWindowOpacity(self.opacity)

    defsetup_background_image(self):
        layout = QVBoxLayout()
        pixmap = QPixmap('resources/app_mini.ico')
        pixmap = pixmap.scaled(self.size())
        self.background_label = QLabel(self)
        self.background_label.setPixmap(pixmap)
        self.background_label.resize(self.size())
        layout.addWidget(self.background_label)
        self.setLayout(layout)

    defmove_to_top_right(self):
        screen_geo = QGuiApplication.primaryScreen().geometry()
        x = screen_geo.width() - self.width() - 10
        y = 10
        self.move(x, y)

    defmousePressEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.dragPosition = event.globalPos() - self.frameGeometry().topLeft()
            event.accept()

    defmouseMoveEvent(self, event: QMouseEvent):
        if event.buttons() == Qt.MouseButton.LeftButton andself.dragPosition:
            self.move(event.globalPos() - self.dragPosition)
            event.accept()

    # 鼠标释放
    defmouseReleaseEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.dragPosition = None

    defshow_main_window(self):
        self.main_window.show()
        self.main_window.is_floating_ball_visible = False
        self.hide()

    # 鼠标双击,打开主界面
    defmouseDoubleClickEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.show_main_window()

上述代码实现了一个具有透明背景的悬浮球。当主界面关闭时,会创建该悬浮球。用户双击悬浮球后,隐藏的主界面将重新显示。目前,悬浮球仅添加了呼吸灯效果,通过周期性地改变透明度,使其呈现出类似呼吸的动态效果。

主界面代码实现(main_window.py)

代码语言:javascript
代码运行次数:0
复制
import sys

from PySide6.QtWidgets import QWidget, QVBoxLayout, QPushButton, QSystemTrayIcon, QMenu
from PySide6.QtGui import QFont, QIcon, QAction

from app_mini import FloatingBall
from batch_file_renamer import RenameFileApp


classMainWindow(QWidget):
    def__init__(self, tray_icon_visible=False):
        super().__init__()
        # 悬浮球可见状态,false可以创建悬浮球,反之。。。
        self.is_floating_ball_visible = False
        # 任务栏托盘标志位,False没有创建  True已创建
        self.is_tray_icon_visible = tray_icon_visible
        self.floating_ball = FloatingBall(self)

        self.init_ui()

    definit_ui(self):
        self.setWindowTitle("PyQt示例应用")
        self.setGeometry(100, 100, 300, 250)
        self.setStyleSheet("background-color: #F5F5F5;")  # 设置窗口背景色为淡灰色


        layout = QVBoxLayout()


        # 重命名使者
        rename_file_btn = QPushButton("重命名使者")
        rename_file_btn.setFont(QFont('Arial', 14))
        rename_file_btn.setStyleSheet("""
            QPushButton {
                background-color: #9C27B0;
                color: white;
                border-radius: 8px;
                padding: 10px;
            }
            QPushButton:hover {
                background-color: #8E24AA;
            }
        """)
        rename_file_btn.clicked.connect(self.rename_file_btn_clicked)
        layout.addWidget(rename_file_btn)

        self.setLayout(layout)

        # 处理窗口关闭事件,使其最小化到托盘
        self.closeEvent = self.handle_close_event

        # 创建系统托盘图标
        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setIcon(QIcon('resources/app_tray.ico'))  # 这里需要一个名为icon.png的图标文件,可以替换为真实路径
        self.tray_icon.activated.connect(self.tray_icon_activated)

        # 创建托盘菜单
        tray_menu = QMenu()
        show_action = QAction("主界面", self)
        show_action.triggered.connect(self.tray_menu_show_main)
        quit_action = QAction("退出", self)
        quit_action.triggered.connect(sys.exit)
        tray_menu.addAction(show_action)
        tray_menu.addAction(quit_action)
        self.tray_icon.setContextMenu(tray_menu)

    # 从托盘菜单点击显示窗口
    deftray_menu_show_main(self):
        self.show()
        # 悬浮球退出
        ifself.is_floating_ball_visible:
            self.floating_ball.close()
            self.is_floating_ball_visible = False

    # 处理窗口关闭事件
    defhandle_close_event(self, event):

        event.ignore()
        self.hide()

        ifnotself.is_tray_icon_visible:
            self.tray_icon.show()
            self.is_tray_icon_visible = True

        ifnotself.is_floating_ball_visible:
            self.create_floating_ball()


    defcreate_floating_ball(self):
        self.floating_ball.show()
        self.is_floating_ball_visible = True

    # 双击托盘,打开窗口
    deftray_icon_activated(self, reason):
        if reason == QSystemTrayIcon.ActivationReason.DoubleClick:
            self.show()
            # 悬浮球退出
            ifself.is_floating_ball_visible:
                self.floating_ball.close()
                self.is_floating_ball_visible = False

    defrename_file_btn_clicked(self):
        print("按钮<重命名使者>被点击了")
        self.rename_file = RenameFileApp()
        self.rename_file.show()

在主界面代码中,当关闭窗口时,会创建悬浮球和系统托盘图标。系统托盘图标配备了右键菜单,提供了显示主界面和退出应用程序的功能。需要注意的是,每次关闭主界面时,都需要判断悬浮球和托盘图标是否已经创建。如果已经创建,只需将它们显示出来即可,避免重复创建,从而提高程序的性能和稳定性。 效果图如下:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-02-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小码农薛尧 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • PySide6 项目开发全攻略:托盘图标&悬浮球
    • 一、功能概述与实现思路
      • 功能介绍
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档