PyQt5-覆盖鼠标光标并将Qwidget设置为对输入透明



我正试图用一个具有以下两种行为的QWidget在PyQt5中编写一个简单的应用程序:

  1. 覆盖鼠标光标
  2. 输入透明;这意味着它可以忽略鼠标输入并将其发送到后台小部件或OS UI(即,类似于覆盖行为(

我可以单独实现每种行为,即当我将它们组合在一起时,光标将返回到默认状态(即我失去覆盖它的能力(!

我想知道这在QT中是否可以实现?

from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QWidget
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
# Goal no. 1: override mouse cursor
QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
w = QWidget()
w.setWindowOpacity(0.1)

# Goal no.2: Make widget transparent for input
w.setWindowFlags(w.windowFlags() 
| QtCore.Qt.WindowTransparentForInput | QtCore.Qt.WindowStaysOnTopHint)
w.resize(900, 900)
w.show()
sys.exit(app.exec_())

基于@ekhumuro:的伟大建议

我找到了一个使用透明小部件的解决方案,并在屏幕上绘制一个动画形状,该形状将跟随鼠标光标

步骤是:

  • 创建一个完全透明的小部件(即完全隐藏(
  • 该小部件应覆盖整个屏幕;类似于屏幕截图应用程序
  • 然后将此小部件配置为忽略所有鼠标输入⇒它应该允许鼠标光标与它后面的所有UI交互,就好像这个小部件不是全部存在一样(例如,用户可以点击这个小部件(
  • 然后可以在透明小部件上绘制和移动形状/文本/动画
  • 这些形状的坐标可以根据鼠标光标坐标来确定
  • 这种方法的唯一限制是,我们不会覆盖系统光标,但我们会在它旁边显示动画,我相信这满足了原始用例
from PySide6 import QtCore, QtWidgets, QtGui
from PySide6.QtCore import QTimer
from PySide6.QtGui import QPainter, QFont
from PySide6.QtWidgets import QApplication

class TransparentWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(TransparentWidget, self).__init__(parent)
self.setAttribute(QtCore.Qt.WA_NoSystemBackground)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
# https://stackoverflow.com/questions/52827296/pyside2-pass-mouse-events-to-system
self.setWindowFlags(self.windowFlags()
# | QtCore.Qt.WindowTransparentForInput
| QtCore.Qt.X11BypassWindowManagerHint
| QtCore.Qt.WindowStaysOnTopHint
| QtCore.Qt.WA_MouseNoMask
| QtCore.Qt.WA_TranslucentBackground
| QtCore.Qt.FramelessWindowHint)
self.x = 0
self.y = 0
self.number = 4
def paintEvent(self, event):
print(f"paintEvent {self.x}  {self.y}")
if not self.number:
return
painter = QPainter()
painter.begin(self)
font = QFont()
font.setBold(True)
font.setPixelSize(15)
painter.setFont(font)
pen = QtGui.QPen()
pen.setWidth(3)
pen.setColor(QtCore.Qt.red)
painter.setPen(pen)
painter.setBrush(QtCore.Qt.white)
painter.drawEllipse(self.x + 15, self.y + 15, 30, 30)
pen = QtGui.QPen()
pen.setColor(QtCore.Qt.black)
painter.setPen(pen)
painter.drawText(self.x + 26, self.y + 35, str(self.number))

if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = TransparentWidget()
w.showFullScreen()

def func():
w.x += 1
w.y += 1
w.update()

timer = QTimer()
timer.timeout.connect(func)
timer.start(10)
sys.exit(app.exec())

最新更新