如何实现QWidget鼠标悬停隐藏、离开重现的功能?
问题:实现置顶QWidget鼠标悬停隐藏、离开显示
需求与当前问题
需要制作一个用于显示信息的小型QWidget,要求:
- 控件始终置顶
- 鼠标悬停时隐藏,方便无干扰地点击或查看下方内容
- 鼠标离开后重新显示
目前遇到的问题:控件隐藏后无像素绘制,无法追踪鼠标活动,会立即触发leaveEvent,导致控件持续闪烁。
初始示例代码
import sys from PyQt5.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget from PyQt5.QtCore import Qt class TransparentWindow(QWidget): def __init__(self): super().__init__() # 设置窗口属性 self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) # | Qt.WindowTransparentForInput) self.setAttribute(Qt.WA_TranslucentBackground) self.setMouseTracking(True) # 设置示例文本 self.layout = QVBoxLayout() self.label = QLabel(self) self.label.setText("Hello, World!") self.label.setStyleSheet("background-color: rgb(255, 255, 255); font-size: 50px;") self.label.setAlignment(Qt.AlignCenter) self.layout.addWidget(self.label) self.setLayout(self.layout) def enterEvent(self, event): print("Mouse entered the window") self.label.setHidden(True) def leaveEvent(self, event): print("Mouse left the window") self.label.setHidden(False) if __name__ == "__main__": app = QApplication(sys.argv) window = TransparentWindow() window.show() sys.exit(app.exec_())
尝试的方案与困境
- 在控件下方添加近乎透明的QWidget捕捉鼠标事件:解决了隐藏后立即重现的问题,但无法再点击下方内容
- 添加
Qt.WindowTransparentForInput属性:控件对进入/离开事件失去响应
想问:是否有办法让控件仅对点击事件透明,而不影响进入/离开事件?或者必须使用其他全局鼠标追踪库来实现?
平台:Windows 11 23H2
临时实现方案
import sys from PyQt5.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget from PyQt5.QtGui import QCursor from PyQt5.QtCore import Qt, QTimer class TransparentWindow(QWidget): def __init__(self): super().__init__() # 设置窗口属性 self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool) # | Qt.WindowTransparentForInput) self.setAttribute(Qt.WA_TranslucentBackground) self.setMouseTracking(True) # 设置示例文本 self.layout = QVBoxLayout() self.label = QLabel(self) self.label.setText("Hello, World!") self.label.setStyleSheet("background-color: rgb(255, 255, 255); font-size: 50px;") self.label.setAlignment(Qt.AlignCenter) self.layout.addWidget(self.label) self.setLayout(self.layout) self.hidetimer = QTimer(self) self.hidetimer.setSingleShot(True) self.hidetimer.timeout.connect(self.hidecheck) self.hidecheckperiod = 300 def hidecheck(self): if self.geometry().contains(QCursor.pos()): self.hidetimer.start(self.hidecheckperiod) return print("Showing.....") self.setHidden(False) def enterEvent(self, event): self.setHidden(True) self.hidetimer.start(self.hidecheckperiod) print("Hiding.....") if __name__ == "__main__": app = QApplication(sys.argv) window = TransparentWindow() window.show() sys.exit(app.exec_()) if __name__ == "__main__": app = QApplication(sys.argv) window = TransparentWindow() window.show() sys.exit(app.exec_())
内容的提问来源于stack exchange,提问作者sil ora
相关产品推荐
相关产品推荐

