在Qt中,QWidget::grab() 和 QScreen::grabWindow() 是两种截取屏幕内容的方法
QWidget::grab()
QWidget::grab() 方法用于截取特定 QWidget 的内容。它只截取该 QWidget 的区域,不包括屏幕上该 QWidget 以外的其他内容。
QPixmap pixmap = myWidget->grab();
pixmap.save("widget_screenshot.png");
特性:
- 只能截取单个 QWidget 的内容。
- 截图的范围仅限于 QWidget 的尺寸和位置。
- 适用于需要截取应用程序内某个特定 QWidget 的情况。
QScreen::grabWindow()
QScreen::grabWindow() 方法用于截取整个屏幕或指定窗口的内容。它可以截取任意窗口或整个屏幕的内容,而不仅限于当前应用程序的窗口。
特性:
- 可以截取整个屏幕或特定窗口的内容。
- 可以指定窗口的ID来截取不同的窗口。
- 适用于需要截取整个屏幕或其他应用程序窗口的情况。
QScreen *screen = QGuiApplication::primaryScreen();
QPixmap pixmap = screen->grabWindow(0); // 0 表示截取整个屏幕
pixmap.save("screen_screenshot.png");
二者联系:
- 它们都返回一个 QPixmap 对象,表示截取到的图像。
- 都可以用来保存图像或进一步处理图像。
区别:
- 作用范围:
- QWidget::grab() 仅限于特定 QWidget 的区域。
- QScreen::grabWindow() 可以截取整个屏幕或指定窗口的区域。
- 使用场景:
- QWidget::grab() 适用于应用程序内的特定组件截图。
- QScreen::grabWindow() 适用于截取整个屏幕或其他应用程序的窗口截图。
示例:
QT:5.15.2
Build:MSVC2019
实现 ScreenshotHelper.h 和 ScreenshotHelper.cpp 工具类
ScreenshotHelper.h
#ifndef SCREENSHOTHELPER_H
#define SCREENSHOTHELPER_H
#include <QWidget>
#include <QPixmap>
#include <QString>
#include <QScreen>
#include <QGuiApplication>
#include <QPainter>
class ScreenshotHelper {
public:
ScreenshotHelper();
~ScreenshotHelper();
enum StitchDirection {
Horizontal,
Vertical
};
static QPixmap capture(QWidget *widget);
static bool save(const QPixmap &pixmap, const QString &filepath);
static bool captureAndSave(QWidget *widget, const QString &filePath);
static QPixmap captureAndScale(QWidget *widget, int width, int height);
static QPixmap scale(const QPixmap &pixmap, int width, int height);
static QPixmap stitch(const QList<QWidget *> &widgets, StitchDirection direction);
};
#endif //SCREENSHOTHELPER_H
ScreenshotHelper.cpp
#include "ScreenshotHelper.h"
ScreenshotHelper::ScreenshotHelper() {
}
ScreenshotHelper::~ScreenshotHelper() {
}
/**
* 截取给定QWidget的截图
* @param widget
* @return
*/
QPixmap ScreenshotHelper::capture(QWidget *widget) {
if (widget) {
QPoint point = widget->mapToGlobal(QPoint(0, 0)); // 获取窗口左上角的位置
QSize size = widget->size(); // 获取窗口的大小
QRect rect(point, size); // 创建一个QRect对象,指定区域位置和大小
QScreen *screen = QGuiApplication::primaryScreen();
QPixmap fullScreenPixmap = screen->grabWindow(0); // 捕获整个屏幕
return fullScreenPixmap.copy(rect); // 截取指定区域
}
return QPixmap();
}
/**
* 将给定的QPixmap保存到指定文件路径
* @param pixmap
* @param filepath
* @return
*/
bool ScreenshotHelper::save(const QPixmap &pixmap, const QString &filepath) {
if (!pixmap.isNull() && !filepath.isEmpty()) {
return pixmap.save(filepath);
}
return false;
}
/**
* 截取并保存截图
* @param widget
* @param filePath
* @return
*/
bool ScreenshotHelper::captureAndSave(QWidget *widget, const QString &filePath) {
QPixmap pixmap = capture(widget);
return save(pixmap, filePath);
}
/**
* 截取并缩放截图到指定大小
* @param widget
* @param width
* @param height
* @return
*/
QPixmap ScreenshotHelper::captureAndScale(QWidget *widget, int width, int height) {
QPixmap pixmap = capture(widget);
if (!pixmap.isNull()) {
return pixmap.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
return QPixmap();
}
QPixmap ScreenshotHelper::scale(const QPixmap &pixmap, int width, int height) {
if (!pixmap.isNull()) {
return pixmap.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
return QPixmap();
}
/**
* 拼接多个QWidget的截图,方向可选水平或垂直
* @param widgets
* @param direction
* @return
*/
QPixmap ScreenshotHelper::stitch(const QList<QWidget *> &widgets, StitchDirection direction) {
QList <QPixmap> pixmaps;
int totalWidth = 0;
int totalHeight = 0;
for (QWidget *widget: widgets) {
QPixmap pixmap = capture(widget);
if (!pixmap.isNull()) {
if (direction == Horizontal) {
totalWidth += pixmap.width();
totalHeight = qMax(totalHeight, pixmap.height());
} else {
totalWidth = qMax(totalWidth, pixmap.width());
totalHeight += pixmap.height();
}
pixmaps.append(pixmap);
}
}
if (pixmaps.isEmpty()) {
return QPixmap();
}
QPixmap stitchedPixmap;
if (direction == Horizontal) {
stitchedPixmap = QPixmap(totalWidth, totalHeight);
} else {
stitchedPixmap = QPixmap(totalWidth, totalHeight);
}
stitchedPixmap.fill(Qt::white);
QPainter painter(&stitchedPixmap);
int currentPos = 0;
for (const QPixmap &pixmap: pixmaps) {
if (direction == Horizontal) {
painter.drawPixmap(currentPos, 0, pixmap);
currentPos += pixmap.width();
} else {
painter.drawPixmap(0, currentPos, pixmap);
currentPos += pixmap.height();
}
}
return stitchedPixmap;
}