我正在尝试创建一个小部件来显示信息。此部件旨在始终位于顶部,并在鼠标悬停在其上时设置为隐藏,以便您可以单击或查看其下方的任何内容而不会中断,然后在鼠标离开此部件后重新出现。我目前面临的问题是,一旦部件被隐藏,就没有像素绘制,因此不再跟踪鼠标活动,这会立即触发离开事件,因此部件会不断闪烁。以下是一个例子:
import sys
from PyQt5.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget
from PyQt5.QtCore import Qt
class TransparentWindow(QWidget):
def __init__(self):
super().__init__()
# Set window attributes
self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) # | Qt.WindowTransparentForInput)
self.setAttribute(Qt.WA_TranslucentBackground)
self.setMouseTracking(True)
# Set example text
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 项目,以便我可以使用这些几乎透明的像素来拾取鼠标事件:
def __init__(self):
super().__init__()
# Set window attributes
self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.setMouseTracking(True)
# Set example text
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)
# Set an almost transparent widget
self.box = QWidget(self)
self.box.setStyleSheet("background-color: rgba(255, 255, 255, 0.01)")
self.layout.addWidget(self.box)
这使得消失然后重新出现部分可以工作。但我再也无法点击它下面的任何东西。我尝试添加 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__()
# Set window attributes
self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool) # | Qt.WindowTransparentForInput)
self.setAttribute(Qt.WA_TranslucentBackground)
self.setMouseTracking(True)
# Set example text
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_())
把窗口移开怎么样?我们可以使用计时器
像这样:
您可以轮询光标位置以查看它是否包含在当前窗口几何图形中。这样做的附带好处是允许短暂的延迟,这样当光标快速移动到窗口上时,窗口不会持续显示/隐藏。延迟可以由用户配置。我认为这应该适用于所有平台,但我只在 Linux 上测试过它。
这是一个基本的演示: