一、Qt 6 中的 API 变化
- 弃用 QPixmap::grabWindow()
 在 Qt 6 中,QPixmap::grabWindow()已被迁移至QScreen类,需通过QScreen::grabWindow()实现窗口截取。
 原因: Qt 6 重构了图形模块,QPixmap的截屏功能被整合到QScreen中以提高多屏幕支持。
二、替代方法 QScreen::grabWindow()
- 基本语法 - QScreen *screen = QGuiApplication::primaryScreen(); QPixmap pixmap = screen->grabWindow(WId windowId, int x=0, int y=0, int width=-1, int height=-1);- windowId:目标窗口的句柄(- QWidget::winId()获取当前窗口的句柄);- x, y:截取区域的起始坐标(相对于窗口左上角),- width, height:截取区域的尺寸,默认- -1表示截取至右下角。
- 典型用例 截取当前窗口: - QPixmap pixmap = screen->grabWindow(this->winId());- 截取全屏 - QPixmap pixmap = screen->grabWindow(0); // 参数 0 表示整个屏幕:ml-citation{ref="2" data="citationList"}-  - 三、注意事项与常见问题
- 跨平台差异 - Windows:需注意窗口边框和客户区坐标差异,建议通过 QWidget::geometry()获取实际区域3;
- macOS:需启用系统偏好设置中的屏幕录制权限,否则截图为黑屏。
 
- Windows:需注意窗口边框和客户区坐标差异,建议通过 
- 截取子控件 
 若需截取特定控件(如- QWidget),优先使用- QWidget::grab(),避免直接处理窗口句柄- QPixmap widgetPixmap = widget->grab(); // 直接截取控件内容:ml-citation{ref="5" data="citationList"}
- 性能与模糊问题 
- 高分辨率屏幕下可能截取到低质量图像,建议调用 setDevicePixelRatio()调整缩放比例;
- 保存时优先使用无损格式(如 PNG)以减少失真.
四、完整示例代码
#include <QGuiApplication>
#include <QScreen>
#include <QWidget>
#include <QFileDialog>
void captureWindow(QWidget *targetWidget) {
    QScreen *screen = QGuiApplication::primaryScreen();
    WId windowId = targetWidget->winId();
    
    // 截取整个窗口(含边框)
    QPixmap fullWindow = screen->grabWindow(windowId);
    
    // 截取窗口客户区(排除边框)
    QRect clientRect = targetWidget->geometry();
    QPixmap clientArea = screen->grabWindow(windowId, clientRect.x(), clientRect.y(), clientRect.width(), clientRect.height());
    
    // 保存截图
    QString path = QFileDialog::getSaveFileName(nullptr, "保存截图", "", "PNG Image (*.png)");
    if (!path.isEmpty()) {
        clientArea.save(path, "PNG");
    }
}
五、错误排查
- 黑屏或空白图像:检查权限(macOS/Linux)或窗口是否被其他程序遮挡36;
- 坐标偏移:确保截取区域参数基于窗口坐标系,而非屏幕坐标系2;
- Qt 版本兼容性:确认项目配置中已包含 gui和widgets模块的依赖7。
附:关键函数对比
| 方法 | 适用场景 | Qt 版本支持 | 特点 | 
|---|---|---|---|
| QScreen::grabWindow | 截取窗口或全屏 | Qt 5+ | 支持多屏幕,需处理窗口句柄 | 
| QWidget::grab | 截取控件内容 | Qt 4+ | 无需计算坐标,自动适配控件尺寸 |