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_()
相关推荐
zjy277771 分钟前
Layui tab选项卡如何动态根据ID值进行程序化切换
jvm·数据库·python
m0_602857764 分钟前
Redis如何修复槽位分配重叠的脏状态_使用redis-cli --cluster fix工具扫描并修复不一致的Slot
jvm·数据库·python
2301_7662834417 分钟前
怎样开启phpMyAdmin的操作审计日志_记录每条执行的SQL
jvm·数据库·python
tang7778924 分钟前
代理IP质量检测实战:Python实现IP可用性、延迟、匿名度自动测试脚本
大数据·爬虫·python·网络协议·tcp/ip
2501_9216494934 分钟前
企业定制金融数据 API:从架构设计到 Python 接入实战
大数据·开发语言·python·websocket·金融·量化
2601_956139421 小时前
政府事业机构品牌策划公司哪家专业
大数据·人工智能·python
Jmayday1 小时前
Pytorch:AI歌词生成器
人工智能·pytorch·python
枫叶林FYL1 小时前
项目八 云资源成本优化与治理平台
后端·python·自然语言处理·flask
reasonsummer1 小时前
【教学类-160-13】20260422 AI视频培训-练习013“豆包AI视频《师幼互动》+豆包图片风格:CG动画”
开发语言·python