Qt-实现矩形区域截图

简介: 本文介绍了如何通过Qt实现屏幕截图功能。首先获取桌面全屏图像并显示在透明窗口上,通过鼠标事件绘制矩形区域,最终截取选中区域的图像。文中提供了核心代码及完整实现,适用于需要屏幕捕捉功能的应用开发。

思路

首先我们先获取到当前桌面的完整图片,然后将其放到一个全屏的透明窗口之中,之后,我们在窗口上进行绘制矩形操作,然后获取到绘制的区域即可。

核心代码

新建一个screenview的界面,设置为全屏窗口模式

setWindowState(Qt::WindowActive|Qt::WindowFullScreen);

获取到桌面的完成图片,保存图片,之前我们已经知道如何获取全屏图片。

screen =QGuiApplication::primaryScreen();
if(const QWindow *window=windowHandle())
    screen=window->screen();
if(!screen)
    return ;
originalPixmap=screen->grabWindow(0);

重写四个方法paintEventmousePressEventmouseMoveEventmouseReleaseEvent,后面的3个鼠标方法,我们主要用来获取鼠标的位置,以便能够在绘制方法里头绘制出矩形区域。

//截图
void screenview::paintEvent(QPaintEvent *event){
    painter.begin(this);
    painter.setPen(QPen(Qt::red,2));
    painter.drawPixmap(0,0,originalPixmap);
    if(sx>=0&&sy>=0)
    {
        painter.drawRect(QRect(sx,sy,ex-sx,ey-sy));
    }
    painter.end();
}
void screenview::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton){
        sx=event->x();
        sy=event->y();
        startpoint=event->pos();
    }
    update();
}
void screenview::mouseMoveEvent(QMouseEvent *event){
    ex=event->x();
    ey=event->y();
    endpoint=event->pos();
    update();
}
void screenview::mouseReleaseEvent(QMouseEvent *event){
    this->close();
    ex=event->x();
    ey=event->y();
    //获取到区域截图
    sourcePixmap=originalPixmap.copy(sx*Scale,sy*Scale,(ex-sx)*Scale,(ey-sy)*Scale);
}
完整代码
//screenview.h
#ifndef SCREENVIEW_H
#define SCREENVIEW_H
#include <QWidget>
#include <QPainter>
#include <QScreen>
#include <QWindow>
#include <QPixmap>
#include <QMouseEvent>
#include <QRubberBand>
#include <QDateTime>
#include <QLabel>
#include "editwindow.h"
#include "mainwindow.h"
//添加
class QRubberBand;
namespace Ui {
class screenview;
}
class screenview : public QWidget
{
    Q_OBJECT
public:
    screenview(QWidget *parent = nullptr,QList<QRect> *ListRect=nullptr,int screentype=0);
    ~screenview();
protected:
    void paintEvent(QPaintEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
protected slots:
    void mouseReleaseEvent(QMouseEvent *event);
    void receiveData(QString str);   //接收传递过来的数据的槽
private:
    Ui::screenview *ui;
    QPainter painter;
    QPixmap originalPixmap;
    QPixmap sourcePixmap;
    QScreen *screen;
    QRubberBand *rubberBand;
    QPoint startpoint;
    QPoint endpoint;
    //记录鼠标位置
    int sx,sy,ex,ey;
    //记录矩形的大小
    int rw,rh;
    //截图类型
    int shottype;
    //固定截图的坐标
    int fixedx,fixedy;
    //固定大小的矩形
    QRect fixedRect;
    //窗口放大倍数
    float Scale;
    //保存所有的矩形
    QList<QRect> *ListRect;
    //当前选中的窗口
    QRect CurrentWindow;
signals:
    void senddata(QPixmap sourcePixmap);
};
#endif // SCREENVIEW_H


#include "screenview.h"
#include "ui_screenview.h"
screenview::screenview(QWidget *parent,QList<QRect> *listRect,int screentype)
    :QWidget(parent),ui(new Ui::screenview)
{
    ui->setupUi(this);
    rubberBand=NULL;
    shottype=screentype;
    screen =QGuiApplication::primaryScreen();
    if(const QWindow *window=windowHandle())
        screen=window->screen();
    if(!screen)
        return ;
    originalPixmap=screen->grabWindow(0);
    //全屏窗口
    setWindowState(Qt::WindowActive|Qt::WindowFullScreen);
    //解决只有鼠标按下时才捕捉鼠标移动
    setMouseTracking(true);
    //获取系统设置的显示比例
    float swidth=this->width();
    float rwidth=originalPixmap.width();
    Scale=rwidth/swidth;
    ListRect=listRect;
}
screenview::~screenview()
{
    delete ui;
}
//截图
void screenview::paintEvent(QPaintEvent *event){
    painter.begin(this);
    painter.setPen(QPen(Qt::red,2));
    painter.drawPixmap(0,0,originalPixmap);
    if(shottype==1)
    {
        //固定窗口截图
        rw=300;
        rh=200;
        int fixx=(ex-rw/2)>0?(ex-rw/2):0;
        int fixy=(ey-rh/2)>0?(ey-rh/2):0;
        fixedRect=QRect(fixx,fixy,rw,rh);
        painter.drawRect(fixedRect);
        painter.setPen(QPen(Qt::black,2));
        painter.drawText(fixx,fixy+rh+10,"F2调整大小");
    }else if(shottype==0)
    {
        if(sx>=0&&sy>=0)
        {
            painter.drawRect(QRect(sx,sy,ex-sx,ey-sy));
        }
    }
    painter.end();
}
void screenview::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton){
        sx=event->x();
        sy=event->y();
        startpoint=event->pos();
        if(shottype==1){
            this->close();
            sourcePixmap=originalPixmap.copy(fixedRect.x()*Scale,fixedRect.y()*Scale,fixedRect.width()*Scale,fixedRect.height()*Scale);
            emit senddata(sourcePixmap);
        }
        else if(shottype==2){
            this->close();
            sourcePixmap=originalPixmap.copy(CurrentWindow.x()*Scale,CurrentWindow.y()*Scale,CurrentWindow.width()*Scale,CurrentWindow.height()*Scale);
            emit senddata(sourcePixmap);
        }
    }
    update();
}
void screenview::mouseMoveEvent(QMouseEvent *event){
    ex=event->x();
    ey=event->y();
    endpoint=event->pos();
    update();
}
void screenview::mouseReleaseEvent(QMouseEvent *event){
    this->close();
    ex=event->x();
    ey=event->y();
    sourcePixmap=originalPixmap.copy(sx*Scale,sy*Scale,(ex-sx)*Scale,(ey-sy)*Scale);
    //将获取到的图片内容发送到编辑窗口,可以直接保存到本地即可
    emit senddata(sourcePixmap);
}
目录
相关文章
Windows下的CMake下载与安装
Windows下的CMake下载与安装
Windows下的CMake下载与安装
|
SQL HIVE
Hive分区+根据分区查询
Hive分区+根据分区查询
|
安全 编译器 开发者
【Qt 学习笔记】Qt信号和槽的其他说明及Lambda表达式
【Qt 学习笔记】Qt信号和槽的其他说明及Lambda表达式
842 0
|
8月前
|
Arthas 监控 Java
下载安装
Arthas 是一款Java诊断工具,使用前需确保服务器已启动Java应用、安装JDK并可访问公网。通过下载 arthas-boot.jar 并启动,可连接目标Java进程进行实时监控与问题排查,支持多进程选择,操作简单高效。
下载安装
|
5月前
|
人工智能 API 网络安全
新手零基础|OpenClaw(AI龙虾)阿里云/本地秒级部署+豆包Seed 2.0接入保姆级教程
在2026年开源AI工具迭代浪潮中,OpenClaw(曾用名Clawdbot、Moltbot)凭借“数据隐私可控、技能插件化扩展、自然语言执行”的核心优势,成为新手零基础入门AI自动化的首选工具。它本质是一款开源的AI智能体执行网关,自身不具备独立的大语言模型推理能力,如同一台“裸机”,需对接外部大模型API才能拥有“智能大脑”,搭配ClawHub技能市场的各类插件,可实现文件管理、代码编写、办公自动化等各类实际任务,真正做到“让AI替人干活”。
2106 0
|
7月前
|
存储 人工智能 数据库
Agentic Memory 实践:用 agents.md 实现 LLM 持续学习
利用 agents.md 文件实现LLM持续学习,让AI Agent记住你的编程习惯、偏好和常用信息,避免重复指令,显著提升效率。每次交互后自动归纳经验,减少冷启动成本,跨工具通用,是高效工程师的必备技能。
791 17
Agentic Memory 实践:用 agents.md 实现 LLM 持续学习
|
机器学习/深度学习 编解码 TensorFlow
RT-DETR改进策略【模型轻量化】| 替换骨干网络为EfficientNet v1 高效的移动倒置瓶颈结构
RT-DETR改进策略【模型轻量化】| 替换骨干网络为EfficientNet v1 高效的移动倒置瓶颈结构
877 0
RT-DETR改进策略【模型轻量化】| 替换骨干网络为EfficientNet v1 高效的移动倒置瓶颈结构
|
存储 SQL Java
Spring Boot使用slf4j进行日志记录
本节课主要对 slf4j 做了一个简单的介绍,并且对 Spring Boot 中如何使用 slf4j 输出日志做了详细的说明,着重分析了 logback.xml 文件中对日志相关信息的配置,包括日志的不同级别...
【Qt 学习笔记】Qt窗口 | 标准对话框 | 颜色对话框QColorDialog
【Qt 学习笔记】Qt窗口 | 标准对话框 | 颜色对话框QColorDialog
3251 3