You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python+PySide2实现跨多显示器的屏幕矩形截图功能

多显示器跨平台屏幕截图解决方案(PySide2实现)

针对你提出的多显示器场景下截图局限于主屏的问题,以下是修改后的实现代码,核心解决了全屏覆盖所有显示器和跨屏幕坐标正确截取两个关键问题:

import sys
from PySide2.QtCore import *
from PySide2.QtWidgets import *
from PySide2.QtGui import *

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle(' ')
        self.begin = QPoint()
        self.end = QPoint()
        self.setWindowOpacity(0.3)
        QApplication.setOverrideCursor(QCursor(Qt.CrossCursor))
        # 窗口置顶+无框,确保截图操作不受干扰
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
        
        # 计算所有显示器的联合区域,让窗口覆盖全部屏幕
        screens = QApplication.screens()
        min_x = min(screen.geometry().x() for screen in screens)
        min_y = min(screen.geometry().y() for screen in screens)
        max_x = max(screen.geometry().x() + screen.geometry().width() for screen in screens)
        max_y = max(screen.geometry().y() + screen.geometry().height() for screen in screens)
        self.setGeometry(QRect(QPoint(min_x, min_y), QPoint(max_x, max_y)))
        
        print('Capture the screen...')
        self.show()

    def paintEvent(self, event):
        qp = QPainter(self)
        qp.setPen(QPen(QColor('black'), 3))
        qp.setBrush(QColor(128, 128, 255, 128))
        qp.drawRect(QRect(self.begin, self.end))

    def mousePressEvent(self, event):
        self.begin = event.pos()
        self.end = self.begin
        self.update()

    def mouseMoveEvent(self, event):
        self.end = event.pos()
        self.update()

    def mouseReleaseEvent(self, event):
        self.close()
        QApplication.restoreOverrideCursor()

        x1 = min(self.begin.x(), self.end.x())
        y1 = min(self.begin.y(), self.end.y())
        x2 = max(self.begin.x(), self.end.x())
        y2 = max(self.begin.y(), self.end.y())

        self.begin = QPoint()
        self.end = QPoint()

        # 仅处理有效选中区域
        if x1 < x2 and y1 < y2:
            selected_rect = QRect(x1, y1, x2 - x1, y2 - y1)
            # 使用Qt原生方法抓取桌面,避免跨平台坐标偏移问题
            desktop_grab = QApplication.primaryScreen().grabWindow(0)
            cropped_img = desktop_grab.copy(selected_rect)
            cropped_img.save('capture.png')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyWidget()
    sys.exit(app.exec_())

关键修改说明

  • 全屏覆盖所有显示器:遍历系统所有显示器,计算出包含所有屏幕的最小矩形区域,将截图窗口设置为该区域大小,确保用户可以在任意屏幕上选择截图范围。
  • 替换PIL为Qt原生截图:使用QScreen.grabWindow()获取桌面图像,避免ImageGrab在多显示器场景下的坐标偏移(尤其是macOS副屏坐标为负数的情况),提升跨平台兼容性。
  • 优化用户体验:添加窗口置顶属性、释放鼠标后恢复默认光标、增加无效区域判断,避免空截图。

内容的提问来源于stack exchange,提问作者angela

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 02:10:32