【PyQt6】QScreen 屏幕截屏

0 环境

- Python 3.12.1
- PyQt6                          6.6.1  ' pip install PyQt6 '
  PyQt6-Qt6                      6.6.1	 默认安装
  PyQt6-sip                      13.6.0  默认安装

1 简介

屏幕截图的方法: 使用 【PyQt6】的 QScreen.grabWindow() 方法

def grabWindow(self, WId=0, x, y, width, height) -> QPixmap:

WId: 窗口系统标识符, 默认 0 表示 屏幕将被抓取
偏移: x, y,
大小: width, height

如果想要全屏截图, 连参数都不需要写

    screen = QApplication.primaryScreen()
    pixmap = screen.grabWindow()
    pixmap.save('123.png')  # 可以直接保存为文件, qt 会根据扩展名 保存成不同的格式

2 QScreen 类

2.1 获取 QScreen 的对象

QScreen 不能被实例化,只能从 QGuiApplication 来获取

class QGuiApplication(QtCore.QCoreApplication):
...
	@staticmethod
    def screens(
<think> 我们之前讨论的是获取本机IP信息,现在用户询问的是使用PyQt6进行截图的方法。 截图功能在PyQt6中可以通过`QScreen`和`QPixmap`来实现。主要步骤包括: 1. 获取应用程序的主窗口或屏幕对象。 2. 捕获整个屏幕或指定区域的图像。 3. 将图像保存到文件或进行其他处理。 下面我们将详细介绍几种常见的截图方法: - 捕获整个屏幕 - 捕获指定窗口 - 捕获自定义区域 同时,我们还将展示一个简单的截图工具示例,包含保存功能。 注意:在PyQt6中,屏幕捕获功能依赖于`QScreen`类。我们可以通过`QApplication.primaryScreen()`获取主屏幕,然后调用其`grabWindow`方法捕获窗口,或者使用`grabScreen`捕获整个屏幕(但注意`grabScreen`在PyQt6中已被弃用,推荐使用`grabWindow`)。 由于用户要求的是截图方法,我们将提供完整的代码示例,并解释关键步骤。 完整代码示例:一个简单的截图工具,点击按钮后截取整个屏幕并显示在标签中,同时提供保存功能。 </think> # PyQt6 截图实现方法 在 PyQt6 中实现截图功能主要依靠 `QScreen` 类,它提供了捕获屏幕内容的方法。下面我将详细介绍几种常用的截图实现方式。 ## 基本截图方法 ### 1. 截取整个屏幕 ```python import sys from PyQt6.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton from PyQt6.QtGui import QPixmap, QScreen class ScreenshotApp(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("PyQt6 截图工具") self.setGeometry(100, 100, 800, 600) # 创建控件 self.image_label = QLabel(self) self.image_label.setGeometry(50, 50, 700, 400) self.image_label.setStyleSheet("background-color: white; border: 1px solid gray;") self.btn_fullscreen = QPushButton("截取全屏", self) self.btn_fullscreen.setGeometry(50, 470, 150, 30) self.btn_fullscreen.clicked.connect(self.capture_full_screen) def capture_full_screen(self): """截取整个屏幕""" screen = QApplication.primaryScreen() screenshot = screen.grabWindow(0) # 0表示整个屏幕 # 显示截图 self.image_label.setPixmap(screenshot.scaled( self.image_label.width(), self.image_label.height(), aspectRatioMode=Qt.AspectRatioMode.KeepAspectRatio )) # 保存截图 screenshot.save("fullscreen_screenshot.png", "PNG") self.statusBar().showMessage("全屏截图已保存为 fullscreen_screenshot.png") if __name__ == "__main__": app = QApplication(sys.argv) window = ScreenshotApp() window.show() sys.exit(app.exec()) ``` ### 2. 截取特定窗口 ```python class ScreenshotApp(QMainWindow): # ... 前面的代码不变 ... def __init__(self): # ... 添加新按钮 ... self.btn_current_window = QPushButton("截取当前窗口", self) self.btn_current_window.setGeometry(220, 470, 150, 30) self.btn_current_window.clicked.connect(self.capture_current_window) def capture_current_window(self): """截取当前应用程序窗口""" screen = QApplication.primaryScreen() # 使用当前窗口的ID screenshot = screen.grabWindow(self.winId()) # 显示并保存 self.image_label.setPixmap(screenshot.scaled( self.image_label.width(), self.image_label.height(), aspectRatioMode=Qt.AspectRatioMode.KeepAspectRatio )) screenshot.save("window_screenshot.png", "PNG") self.statusBar().showMessage("窗口截图已保存为 window_screenshot.png") ``` ### 3. 截取特定区域 ```python class ScreenshotApp(QMainWindow): # ... 前面的代码不变 ... def __init__(self): # ... 添加新按钮 ... self.btn_custom_area = QPushButton("截取自定义区域", self) self.btn_custom_area.setGeometry(390, 470, 150, 30) self.btn_custom_area.clicked.connect(self.capture_custom_area) # 用于区域选择的变量 self.selection_start = None self.selection_end = None self.selecting = False def mousePressEvent(self, event): """开始选择区域""" if self.btn_custom_area.isChecked(): self.selecting = True self.selection_start = event.position().toPoint() def mouseMoveEvent(self, event): """更新选择区域""" if self.selecting: self.selection_end = event.position().toPoint() self.update() def mouseReleaseEvent(self, event): """结束选择并截图""" if self.selecting: self.selecting = False self.btn_custom_area.setChecked(False) self.capture_selected_area() def paintEvent(self, event): """绘制选择区域""" super().paintEvent(event) if self.selecting and self.selection_start and self.selection_end: painter = QPainter(self) painter.setPen(QPen(Qt.GlobalColor.red, 2, Qt.PenStyle.DashLine)) painter.drawRect(QRect(self.selection_start, self.selection_end)) def capture_selected_area(self): """截取选择的区域""" if not self.selection_start or not self.selection_end: return # 创建矩形区域 rect = QRect(self.selection_start, self.selection_end).normalized() # 截取整个屏幕 screen = QApplication.primaryScreen() full_screenshot = screen.grabWindow(0) # 截取选择区域的子图像 screenshot = full_screenshot.copy(rect) # 显示并保存 self.image_label.setPixmap(screenshot.scaled( self.image_label.width(), self.image_label.height(), aspectRatioMode=Qt.AspectRatioMode.KeepAspectRatio )) screenshot.save("area_screenshot.png", "PNG") self.statusBar().showMessage(f"区域截图已保存为 area_screenshot.png ({rect.width()}x{rect.height()})") # 重置选择 self.selection_start = None self.selection_end = None ``` ## 完整截图工具实现 下面是集成所有功能的完整截图工具: ```python import sys from PyQt6.QtWidgets import ( QApplication, QMainWindow, QLabel, QPushButton, QVBoxLayout, QWidget, QHBoxLayout, QFileDialog ) from PyQt6.QtGui import ( QPixmap, QScreen, QPainter, QPen, QImage, QBitmap, QBrush, QColor ) from PyQt6.QtCore import Qt, QRect, QPoint class ScreenshotApp(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("PyQt6 高级截图工具") self.setGeometry(100, 100, 900, 700) # 主控件 main_widget = QWidget() self.setCentralWidget(main_widget) layout = QVBoxLayout() main_widget.setLayout(layout) # 图像显示区域 self.image_label = QLabel() self.image_label.setMinimumSize(800, 500) self.image_label.setStyleSheet("background-color: white; border: 1px solid gray;") self.image_label.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.addWidget(self.image_label) # 按钮区域 button_layout = QHBoxLayout() self.btn_fullscreen = QPushButton("截取全屏") self.btn_fullscreen.clicked.connect(self.capture_full_screen) button_layout.addWidget(self.btn_fullscreen) self.btn_current_window = QPushButton("截取当前窗口") self.btn_current_window.clicked.connect(self.capture_current_window) button_layout.addWidget(self.btn_current_window) self.btn_custom_area = QPushButton("截取自定义区域") self.btn_custom_area.setCheckable(True) self.btn_custom_area.clicked.connect(self.toggle_area_selection) button_layout.addWidget(self.btn_custom_area) self.btn_save = QPushButton("保存截图") self.btn_save.clicked.connect(self.save_screenshot) button_layout.addWidget(self.btn_save) self.btn_clipboard = QPushButton("复制到剪贴板") self.btn_clipboard.clicked.connect(self.copy_to_clipboard) button_layout.addWidget(self.btn_clipboard) layout.addLayout(button_layout) # 状态栏 self.statusBar().showMessage("准备就绪") # 截图变量 self.current_screenshot = None self.selection_start = None self.selection_end = None self.selecting = False def toggle_area_selection(self): """切换区域选择模式""" if self.btn_custom_area.isChecked(): self.statusBar().showMessage("请按住鼠标左键并拖动选择截图区域") else: self.selecting = False self.update() def capture_full_screen(self): """截取整个屏幕""" screen = QApplication.primaryScreen() self.current_screenshot = screen.grabWindow(0) self.display_screenshot() self.statusBar().showMessage("全屏截图完成") def capture_current_window(self): """截取当前应用程序窗口""" screen = QApplication.primaryScreen() self.current_screenshot = screen.grabWindow(self.winId()) self.display_screenshot() self.statusBar().showMessage("窗口截图完成") def mousePressEvent(self, event): """开始选择区域""" if self.btn_custom_area.isChecked() and event.button() == Qt.MouseButton.LeftButton: self.selecting = True self.selection_start = event.position().toPoint() def mouseMoveEvent(self, event): """更新选择区域""" if self.selecting: self.selection_end = event.position().toPoint() self.update() def mouseReleaseEvent(self, event): """结束选择并截图""" if self.selecting and event.button() == Qt.MouseButton.LeftButton: self.selecting = False self.btn_custom_area.setChecked(False) self.capture_selected_area() def paintEvent(self, event): """绘制选择区域""" super().paintEvent(event) if self.selecting and self.selection_start and self.selection_end: painter = QPainter(self) # 创建半透明遮罩 screen_rect = QApplication.primaryScreen().geometry() mask = QBitmap(screen_rect.size()) mask.fill(Qt.GlobalColor.color0) brush = QBrush(Qt.GlobalColor.color1) painter_mask = QPainter(mask) painter_mask.setBrush(brush) painter_mask.drawRect(QRect(self.selection_start, self.selection_end)) painter_mask.end() # 应用遮罩 bg = QImage(screen_rect.size(), QImage.Format.Format_ARGB32) bg.fill(QColor(0, 0, 0, 150)) bg.setAlphaChannel(mask) # 绘制选择框 painter.drawImage(0, 0, bg) painter.setPen(QPen(Qt.GlobalColor.red, 2, Qt.PenStyle.DashLine)) painter.drawRect(QRect(self.selection_start, self.selection_end)) def capture_selected_area(self): """截取选择的区域""" if not self.selection_start or not self.selection_end: return # 创建矩形区域 rect = QRect(self.selection_start, self.selection_end).normalized() # 截取整个屏幕 screen = QApplication.primaryScreen() full_screenshot = screen.grabWindow(0) # 截取选择区域的子图像 self.current_screenshot = full_screenshot.copy(rect) self.display_screenshot() self.statusBar().showMessage(f"区域截图完成 ({rect.width()}x{rect.height()})") # 重置选择 self.selection_start = None self.selection_end = None def display_screenshot(self): """显示当前截图""" if self.current_screenshot: pixmap = self.current_screenshot.scaled( self.image_label.width(), self.image_label.height(), Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation ) self.image_label.setPixmap(pixmap) def save_screenshot(self): """保存截图到文件""" if not self.current_screenshot: self.statusBar().showMessage("没有可保存的截图") return file_path, _ = QFileDialog.getSaveFileName( self, "保存截图", "", "PNG 图像 (*.png);;JPEG 图像 (*.jpg *.jpeg);;所有文件 (*)" ) if file_path: if file_path.endswith(('.png', '.jpg', '.jpeg')): self.current_screenshot.save(file_path) self.statusBar().showMessage(f"截图已保存到: {file_path}") else: self.current_screenshot.save(file_path + ".png") self.statusBar().showMessage(f"截图已保存到: {file_path}.png") def copy_to_clipboard(self): """复制截图到剪贴板""" if self.current_screenshot: clipboard = QApplication.clipboard() clipboard.setPixmap(self.current_screenshot) self.statusBar().showMessage("截图已复制到剪贴板") if __name__ == "__main__": app = QApplication(sys.argv) window = ScreenshotApp() window.show() sys.exit(app.exec()) ``` ## 关键功能解析 1. **截图方法**: - `screen.grabWindow(0)` - 截取整个屏幕 - `screen.grabWindow(window_id)` - 截取特定窗口 - `pixmap.copy(rect)` - 截取指定区域 2. **鼠标事件处理**: - `mousePressEvent` - 开始选择区域 - `mouseMoveEvent` - 更新选择区域 - `mouseReleaseEvent` - 完成区域选择并截图 3. **图像处理**: - `QPixmap.scaled()` - 缩放图像以适应显示区域 - `QPixmap.save()` - 保存图像到文件 - `QApplication.clipboard().setPixmap()` - 复制图像到剪贴板 4. **半透明遮罩效果**: ```python # 创建半透明遮罩 mask = QBitmap(screen_rect.size()) mask.fill(Qt.GlobalColor.color0) brush = QBrush(Qt.GlobalColor.color1) painter_mask = QPainter(mask) painter_mask.setBrush(brush) painter_mask.drawRect(QRect(self.selection_start, self.selection_end)) ``` ## 高级功能扩展 1. **添加延时截图**: ```python from PyQt6.QtCore import QTimer # 添加延迟截图按钮 self.btn_delayed = QPushButton("延时截图(5秒)") self.btn_delayed.clicked.connect(self.start_delayed_screenshot) def start_delayed_screenshot(self): """开始延时截图""" self.statusBar().showMessage("5秒后截图...") self.hide() # 隐藏窗口避免干扰 QTimer.singleShot(5000, self.capture_delayed_screenshot) def capture_delayed_screenshot(self): """执行延时截图""" self.capture_full_screen() self.show() ``` 2. **添加标注功能**: ```python # 在显示截图后添加绘图功能 self.drawing = False self.draw_points = [] def mousePressEvent(self, event): if self.current_screenshot and not self.selecting: if event.button() == Qt.MouseButton.LeftButton: self.drawing = True self.draw_points = [event.position().toPoint()] def mouseMoveEvent(self, event): if self.drawing: self.draw_points.append(event.position().toPoint()) self.update() def mouseReleaseEvent(self, event): if self.drawing: self.drawing = False # 保存绘图到截图 painter = QPainter(self.current_screenshot) painter.setPen(QPen(Qt.GlobalColor.red, 3)) painter.drawPolyline(QPolygon(self.draw_points)) painter.end() self.display_screenshot() ``` 3. **添加图像编辑工具栏**: ```python # 添加图像编辑工具栏 edit_toolbar = QToolBar("编辑工具") self.addToolBar(Qt.ToolBarArea.BottomToolBarArea, edit_toolbar) btn_pen = QAction(QIcon("pen.png"), "画笔", self) btn_pen.triggered.connect(self.activate_pen) edit_toolbar.addAction(btn_pen) btn_text = QAction(QIcon("text.png"), "添加文字", self) btn_text.triggered.connect(self.add_text) edit_toolbar.addAction(btn_text) ``` 以上代码提供了PyQt6截图功能的完整实现,包括全屏截图、窗口截图、区域截图等功能,并支持保存和复制到剪贴板。可根据实际需求进一步扩展功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值