在鼠标按下时获取屏幕像素
Posted
技术标签:
【中文标题】在鼠标按下时获取屏幕像素【英文标题】:Getting screen pixels on mouse press 【发布时间】:2020-06-13 09:29:23 【问题描述】:当我单击屏幕上的任意位置(包括我的应用程序外部)时,我想获取鼠标坐标处的屏幕像素。
作为第一步,我截图如下:
from PyQt5 import QtWidgets, QtGui
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
w = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
w.setLayout(layout)
self.setCentralWidget(w)
screenshot = QtWidgets.QApplication.primaryScreen().grabWindow(w.winId())
如何将我点击的坐标映射到屏幕截图?
我认为下一步是将屏幕截图转换为Pixmap
以提取像素,但我不知道如何将其与鼠标按下坐标联系起来。
【问题讨论】:
【参考方案1】:在任何 Qt 窗口外部捕获点击事件的唯一方法是通过grabMouse()
。考虑到这仅适用于 Linux:
注意:在 Windows 上,grabMouse() 仅在鼠标位于进程拥有的窗口内时才有效。在 macOS 上,grabMouse() 仅在鼠标位于该小部件的框架内时才有效。
还要注意抓鼠标可能很危险:
警告:鼠标抓取应用程序中的错误经常锁定终端。使用此函数时要格外小心,并考虑在调试时使用 -nograb 命令行选项。
只要小部件抓住鼠标,它就会捕获所有个鼠标事件(包括鼠标滚轮),无论它们的位置如何,所以它也非常重要尽快释放它。然后,就不需要映射坐标了:mousePressEvent
已经提供了基于屏幕坐标的全局位置,并且由于您已经截取了整个屏幕区域,因此这些坐标将匹配。
最后,要获取像素数据,将grabWindow
提供的QPixmap转换成QImage并使用pixelColor
。
由于grabMouse 的平台限制,在以下示例中,我将创建一个透明窗口,充当“假”鼠标抓取器。
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
w = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
w.setLayout(layout)
self.setCentralWidget(w)
self.grabButton = QtWidgets.QPushButton('Grab')
layout.addWidget(self.grabButton)
self.label = QtWidgets.QLabel('Waiting')
layout.addWidget(self.label)
self.grabButton.setCheckable(True)
self.grabButton.toggled.connect(self.startGrab)
self.desktopId = QtWidgets.QApplication.desktop().winId()
if sys.platform != 'linux':
self.grabber = QtWidgets.QWidget(flags=QtCore.Qt.FramelessWindowHint)
self.grabber.setAttribute(QtCore.Qt.WA_TranslucentBackground)
self.grabber.installEventFilter(self)
else:
self.grabber = None
def grabPixel(self, event):
buttonRect = self.grabButton.rect()
buttonRect.translate(self.grabButton.mapToGlobal(QtCore.QPoint()))
if event.globalPos() not in buttonRect:
screenshot = QtWidgets.QApplication.primaryScreen().grabWindow(self.desktopId).toImage()
pixel = screenshot.pixelColor(event.globalPos())
self.label.setText('Click on x\nRGB: '.format(event.globalX(), event.globalY(), pixel.name()))
self.grabButton.toggle()
def startGrab(self, grab):
if grab:
if self.grabber:
rect = QtCore.QRect()
for screen in QtWidgets.QApplication.screens():
rect |= screen.geometry()
self.grabber.setGeometry(rect)
self.grabber.show()
else:
self.grabMouse()
else:
self.releaseMouse()
def eventFilter(self, source, event):
if source == self.grabber and event.type() == QtCore.QEvent.MouseButtonPress:
self.grabPixel(event)
self.grabber.hide()
return super().eventFilter(source, event)
def mousePressEvent(self, event):
self.grabPixel(event)
【讨论】:
评论不用于扩展讨论;这个对话是moved to chat。以上是关于在鼠标按下时获取屏幕像素的主要内容,如果未能解决你的问题,请参考以下文章