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

不废话直接看代码

python 复制代码
# -*- coding=utf-8 -*-
# ==========================================
#       author: Ruben
#         mail: [email protected]
#         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_()
相关推荐
zoney hu42 分钟前
PyQt学习记录
pyqt
带娃的IT创业者42 分钟前
《Python实战进阶》No39:模型部署——TensorFlow Serving 与 ONNX
pytorch·python·tensorflow·持续部署
Bruce-li__1 小时前
深入理解Python asyncio:从入门到实战,掌握异步编程精髓
网络·数据库·python
九月镇灵将1 小时前
6.git项目实现变更拉取与上传
git·python·scrapy·scrapyd·gitpython·gerapy
小张学Python1 小时前
AI数字人Heygem:口播与唇形同步的福音,无需docker,无需配置环境,一键整合包来了
python·数字人·heygem
跳跳糖炒酸奶2 小时前
第四章、Isaacsim在GUI中构建机器人(2):组装一个简单的机器人
人工智能·python·算法·ubuntu·机器人
步木木2 小时前
Anaconda和Pycharm的区别,以及如何选择两者
ide·python·pycharm
星始流年2 小时前
解决PyInstaller打包PySide6+QML应用的资源文件问题
python·llm·pyspider
南玖yy2 小时前
Python网络爬虫:从入门到实践
爬虫·python
The Future is mine3 小时前
Python计算经纬度两点之间距离
开发语言·python