实现一个 PyQt5 浮窗应用,需要使用 PyQt5 的一些特别功能。以下是一个示例代码,展示了如何创建一个浮窗,包括始终置顶、可以拖动、动态调整大小、无法关闭和隐藏任务栏图标。,使主程序可以在关闭时隐藏到系统托盘(任务栏旁边的隐藏图标处)而不是完全退出。用户可以通过托盘图标恢复主程序。这可以通过 QSystemTrayIcon
实现。代码还支持从主程序与浮窗之间的信息传递。
以下是完整的实现代码:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout, QPushButton, QSystemTrayIcon, QMenu, QAction
from PyQt5.QtCore import Qt
class FloatingWindow(QWidget):
def __init__(self):
super(FloatingWindow, self).__init__()
# 设置浮窗样式
self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.setAttribute(Qt.WA_DeleteOnClose)
# 初始化内容
self.label = QLabel("这是一个浮窗示例\n可以拖动和调整透明度", self)
self.label.setStyleSheet("background-color: rgba(255, 255, 255, 200); padding: 10px;")
self.label.setAlignment(Qt.AlignCenter)
# 布局
layout = QVBoxLayout(self)
layout.addWidget(self.label)
self.setLayout(layout)
# 设置初始大小
self.adjustSize()
# 隐藏任务栏图标
self.setWindowFlag(Qt.Tool)
# 初始化拖动参数
self.startPos = None
def update_text(self, new_text: str):
"""更新浮窗中的文本"""
self.label.setText(new_text)
self.adjustSize() # 动态调整大小
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.startPos = event.pos()
def mouseMoveEvent(self, event):
if self.startPos is not None:
self.move(self.pos() + event.pos() - self.startPos)
def mouseReleaseEvent(self, event):
self.startPos = None
def keyPressEvent(self, event):
if event.key() == Qt.Key_Up:
current_opacity = self.windowOpacity()
self.setWindowOpacity(min(current_opacity + 0.1, 1.0)) # 增加透明度
elif event.key() == Qt.Key_Down:
current_opacity = self.windowOpacity()
self.setWindowOpacity(max(current_opacity - 0.1, 0.0)) # 减少透明度
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
# 初始化主界面
self.setWindowTitle('主程序')
self.setGeometry(100, 100, 300, 200)
# 按钮启动浮窗
self.button = QPushButton("启动浮窗", self)
self.button.clicked.connect(self.open_floating_window)
layout = QVBoxLayout(self)
layout.addWidget(self.button)
self.floating_window = None
# 系统托盘图标
self.tray_icon = QSystemTrayIcon(self)
self.tray_icon.setIcon(self.style().standardIcon(QStyle.SP_ComputerIcon))
self.tray_icon.activated.connect(self.tray_icon_clicked)
# 设置菜单
self.tray_menu = QMenu()
restore_action = QAction("恢复", self)
restore_action.triggered.connect(self.show)
quit_action = QAction("退出", self)
quit_action.triggered.connect(QApplication.quit)
self.tray_menu.addAction(restore_action)
self.tray_menu.addAction(quit_action)
self.tray_icon.setContextMenu(self.tray_menu)
def open_floating_window(self):
if self.floating_window is None:
self.floating_window = FloatingWindow()
self.floating_window.show()
# 示例:传递信息到浮窗
self.floating_window.update_text("这是从主程序传来的消息!")
def tray_icon_clicked(self, reason):
if reason == QSystemTrayIcon.Trigger:
self.show()
self.raise_() # 将窗口升到最上面
def closeEvent(self, event):
self.hide() # 关闭主窗口时隐藏而不是退出
self.tray_icon.show() # 在托盘中显示图标
event.ignore() # 忽略关闭事件
if __name__ == "__main__":
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
# 隐藏任务栏图标,运行主程序
sys.exit(app.exec_())
代码说明
-
系统托盘图标
QSystemTrayIcon
:- 在
MainWindow
中创建QSystemTrayIcon
实例,设置图标和响应点击事件。 - 创建一个菜单,提供“恢复”和“退出”功能。
- 在
-
隐藏主窗口:
- 当主窗口关闭时,调用
closeEvent
方法隐藏窗口并显示托盘图标,而不是完全退出程序。这样程序会在后台执行。 self.hide()
用于隐藏窗口,self.tray_icon.show()
用于显示托盘图标。
- 当主窗口关闭时,调用
-
托盘图标点击:
- 使用
tray_icon.activated.connect(self.tray_icon_clicked)
将托盘图标的点击事件连接到处理方法,当用户点击托盘图标时,重新显示主窗口。
- 使用
-
浮窗动态更新:
- 当点击“启动浮窗”按钮时,会创建浮窗并显示传递的信息。
运行程序
- 当运行程序时,用户将看到主窗口。点击“启动浮窗”按钮后,浮窗会显示出来。
- 关闭主窗口后,程序将会隐藏,而不是退出,并在系统托盘中显示图标。
- 用户可以通过点击托盘图标的菜单来恢复或退出程序。
注意
- 运行该程序后需要确保在电脑的任务栏右侧区域中查看托盘图标,该程序将在那里显示运行状态。