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_()
相关推荐
在下不上天5 分钟前
Flume日志采集系统的部署,实现flume负载均衡,flume故障恢复
大数据·开发语言·python
SEVEN-YEARS9 分钟前
深入理解TensorFlow中的形状处理函数
人工智能·python·tensorflow
EterNity_TiMe_14 分钟前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip
Suyuoa25 分钟前
附录2-pytorch yolov5目标检测
python·深度学习·yolo
好看资源平台1 小时前
网络爬虫——综合实战项目:多平台房源信息采集与分析系统
爬虫·python
进击的六角龙2 小时前
深入浅出:使用Python调用API实现智能天气预报
开发语言·python
檀越剑指大厂2 小时前
【Python系列】浅析 Python 中的字典更新与应用场景
开发语言·python
湫ccc2 小时前
Python简介以及解释器安装(保姆级教学)
开发语言·python
孤独且没人爱的纸鹤2 小时前
【深度学习】:从人工神经网络的基础原理到循环神经网络的先进技术,跨越智能算法的关键发展阶段及其未来趋势,探索技术进步与应用挑战
人工智能·python·深度学习·机器学习·ai
羊小猪~~2 小时前
tensorflow案例7--数据增强与测试集, 训练集, 验证集的构建
人工智能·python·深度学习·机器学习·cnn·tensorflow·neo4j