PyQt 如何通过连续点击托盘图标显示隐藏主窗口并且在主窗口隐藏时调整界面到托盘图标附近

不废话直接看代码

python 复制代码
# -*- coding=utf-8 -*-
# ==========================================
#       author: Ruben
#         mail: 773849069@qq.com
#         time: 2023/12/8
# ==========================================
u"""
一个托盘图标的小部件
"""
from Qt import QtWidgets, QtGui, QtCore


# --*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*


class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
    """拓展托盘图标,可移动界面至托盘图标附近"""
    clicked = QtCore.Signal()  # 单击
    double_clicked = QtCore.Signal()  # 双击
    right_clicked = QtCore.Signal()  # 右键

    def __init__(self, *args, **kwargs):
        super(SystemTrayIcon, self).__init__(*args, **kwargs)
        self.activated.connect(self.__activated)

    def __activated(self, reason):
        if reason == self.Trigger:
            self.clicked.emit()
        elif reason == self.DoubleClick:
            self.double_clicked.emit()
        elif reason == self.Context:
            self.right_clicked.emit()

    @staticmethod
    def available_geometry(pos):
        """
        传入控件位置返回控件所在的屏幕的可用大小

        Args:
            pos: QtCore.QPoint

        Returns:
            QtCore.QRect
        """
        desktop = QtWidgets.QApplication.instance().desktop()
        return desktop.availableGeometry(pos)

    def move_widget_to_system_tray_icon(self, widget, margin=10):
        """
        将界面移动到托盘图标附近

        Args:
            widget: QWidget
            margin: 10px

        Returns:
            QtCore.QPoint
        """
        center = self.geometry().center()
        tray_x = center.x()
        tray_y = center.y()
        screen_geometry = self.available_geometry(center)

        # 托盘图标和屏幕边缘的距离
        top = abs(tray_y - screen_geometry.top())
        bottom = abs(screen_geometry.bottom() - tray_y)
        left = abs(tray_x - screen_geometry.left())
        right = abs(screen_geometry.right() - tray_x)

        # 获得屏幕边缘的最小距离
        v = min(top, bottom)  # 纵向
        h = min(left, right)  # 横向

        if h < v:  # 纵向菜单栏
            if right > left:  # 左
                x = screen_geometry.left() + margin
                y = tray_y - widget.height()
            else:  # 右
                x = screen_geometry.right() - widget.width() - margin
                y = tray_y - widget.height()
        else:  # 横向菜单栏
            if top < bottom:  # 上
                x = screen_geometry.right() - widget.width() - right
                y = screen_geometry.top() + margin
            else:  # 下
                x = screen_geometry.right() - widget.width() - right
                y = screen_geometry.bottom() - widget.height() - 30 - margin

        widget.move(x, y)


class Application(QtWidgets.QMainWindow):
    def __init__(self, *args, **kwargs):
        """初始化主应用程序窗口"""
        super(Application, self).__init__(*args, **kwargs)
        self._initialise_tray()
        self.setWindowIcon(self.tray_icon())
        self.setWindowTitle("托盘图标演示主界面")

    def tray_icon(self):
        """使用Qt内置的图标"""
        icon = self.style().standardIcon(QtWidgets.QStyle.SP_TrashIcon)
        return icon

    def _initialise_tray(self):
        u"""初始化并添加应用程序图标到系统托盘"""
        self.tray_menu = self._create_tray_menu()
        self.tray = SystemTrayIcon(self.tray_icon(), self)
        self.tray.setContextMenu(self.tray_menu)
        self.tray.clicked.connect(self.show_main_widget)
        self.tray.show()

    def _create_tray_menu(self):
        """创建菜单并连接信号"""
        menu = QtWidgets.QMenu()
        action = menu.addAction("显示主界面")
        action.triggered.connect(self.show_main_widget)
        action = menu.addAction("退出")
        action.triggered.connect(QtWidgets.QApplication.quit)
        return menu

    def focus(self):
        u"""显示窗口并放到最上边"""
        self.activateWindow()
        self.showNormal()
        self.raise_()

    def show_main_widget(self):
        """显示主界面"""
        if self.isMinimized():
            # 在最小化状态时,显示界面
            self.focus()
        elif self.isHidden():
            # 隐藏的状态给它显示并移动到托盘图标附近
            self.tray.move_widget_to_system_tray_icon(self)
            self.focus()
        else:
            # 已显示的给它最小化
            self.showMinimized()


if __name__ == '__main__':
    _app = QtWidgets.QApplication([])
    _app.setQuitOnLastWindowClosed(False)
    _win = Application()
    _win.resize(300, 100)
    _win.show()
    _app.exec_()
相关推荐
FreeCode几秒前
LangGraph1.0智能体开发:运行时系统
python·langchain·agent
青瓷程序设计13 分钟前
植物识别系统【最新版】Python+TensorFlow+Vue3+Django+人工智能+深度学习+卷积神经网络算法
人工智能·python·深度学习
习习.y37 分钟前
关于python中的面向对象
开发语言·python
hmbbcsm1 小时前
练习python题目小记(六)
开发语言·python
wow_DG1 小时前
【Python✨】VS Code 秒开 Python 类型检查:一招 mypy + settings.json 让你的 Bug 原地现形!
python·json·bug
Aspect of twilight1 小时前
LeetCode华为大模型岗刷题
python·leetcode·华为·力扣·算法题
空影星1 小时前
高效追踪电脑使用时间,Tockler助你优化时间管理
python·django·flask
LiLiYuan.2 小时前
【Lombok库常用注解】
java·开发语言·python
不去幼儿园2 小时前
【启发式算法】灰狼优化算法(Grey Wolf Optimizer, GWO)详细介绍(Python)
人工智能·python·算法·机器学习·启发式算法
二川bro2 小时前
数据可视化进阶:Python动态图表制作实战
开发语言·python·信息可视化