Estou tentando criar um pequeno widget para exibir informações. Este widget foi criado para ficar sempre no topo e ficar oculto quando o mouse passar sobre ele, para que você possa clicar ou ver o que estiver abaixo dele sem interrupção, e então reaparecer quando o mouse sair deste widget. O problema que estou enfrentando atualmente é que, uma vez que o widget está oculto, não há pixel desenhado, portanto, nenhuma atividade do mouse é rastreada mais, o que imediatamente aciona o leaveEvent, portanto, o widget continua piscando. Aqui está um exemplo:
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_())
Agora tentei adicionar um item Qwidget quase transparente abaixo dele para poder captar eventos do mouse com esses pixels quase transparentes:
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)
que faz a parte de desaparecer e reaparecer funcionar. Mas não consigo mais clicar em nada que esteja abaixo dela. Tentei adicionar Qt.WindowTransparentForInput, mas ele tornou a janela transparente para eventos de entrada/saída também. Existe alguma solução para tornar esta janela transparente apenas para eventos de clique, mas não para eventos de entrada/saída? Ou preciso usar outras bibliotecas globais de rastreamento de mouse para fazer isso funcionar?
Plataforma: Windows 11 23H2
Obrigado por toda a ajuda! Foi assim que decidi implementar no momento:
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_())