You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 10:50:37