不废话直接看代码
# -*- 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_()