PySide6浮动时钟如何实现始终置顶(含全屏模式)?
解决PySide6浮动时钟始终置顶(含全屏模式)的问题
问题根源
你两次调用setWindowFlags()会覆盖之前的窗口标志,导致Qt.WindowStaysOnTopHint被丢弃。setWindowFlags()每次调用都会重置所有窗口标志,必须将需要的标志通过**按位或(|)**组合后一次性设置。
核心修复步骤
将原代码中分开设置窗口标志的两行:
self.setWindowFlags(Qt.WindowStaysOnTopHint) self.setWindowFlags(Qt.FramelessWindowHint)
替换为:
# 组合置顶、无边框、工具窗口标志,提升全屏场景下的优先级 self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool)
Qt.WindowStaysOnTopHint:基础置顶标志,确保窗口默认在顶层Qt.FramelessWindowHint:保留无边框的浮动效果Qt.Tool:将窗口标记为工具窗口,部分系统下工具窗口优先级更高,可穿透普通全屏应用
完整优化代码(含拖动功能)
为提升实用性,添加鼠标拖动功能让时钟可自由移动:
import sys from PySide6.QtCore import QPoint, Qt, QTime, QTimer from PySide6.QtGui import QFont, QMouseEvent from PySide6.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget class Clock(QWidget): def __init__(self, parent=None) -> None: super().__init__(parent) self.left = 1100 self.top = 800 self.width = 320 self.height = 60 self.drag_pos = QPoint() # 记录拖动起始位置 self.initUI() def initUI(self) -> None: self.setGeometry(self.left, self.top, self.width, self.height) # 一次性设置所有窗口标志 self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool) self.setAttribute(Qt.WA_TranslucentBackground) font = QFont() font.setFamily("Arial") font.setPointSize(50) self.label = QLabel() self.label.setAlignment(Qt.AlignCenter) self.label.setFont(font) layout = QVBoxLayout(self, spacing=0) layout.addWidget(self.label) self.setLayout(layout) timer = QTimer(self) timer.timeout.connect(self.showTime) timer.start(1000) self.show() def showTime(self) -> None: current_time = QTime.currentTime() label_time = current_time.toString('hh:mm') self.label.setText(label_time) # 实现鼠标拖动窗口功能 def mousePressEvent(self, event: QMouseEvent) -> None: if event.button() == Qt.LeftButton: self.drag_pos = event.globalPosition().toPoint() - self.frameGeometry().topLeft() event.accept() def mouseMoveEvent(self, event: QMouseEvent) -> None: if event.buttons() == Qt.LeftButton: self.move(event.globalPosition().toPoint() - self.drag_pos) event.accept() if __name__ == '__main__': App = QApplication(sys.argv) clock = Clock() clock.show() sys.exit(App.exec())
补充说明
- 若遇到使用独占模式的全屏应用(如部分大型游戏),Qt自带的标志可能无法穿透,此时需要调用系统级API(如Windows的
SetWindowPos)来强制置顶,这部分需针对不同操作系统单独处理。 - 若在Linux/macOS下
Qt.Tool效果不佳,可尝试替换为Qt.SplashScreen,但该标志会禁用部分窗口交互特性。
内容的提问来源于stack exchange,提问作者ivaquero
相关产品推荐
相关产品推荐

