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);
}
目录
相关文章
|
4月前
|
消息中间件 人工智能 资源调度
云上AI推理平台全掌握 (5):大模型异步推理服务
针对大模型推理服务中“高计算量、长时延”场景下同步推理的弊端,阿里云人工智能平台 PAI 推出了一套基于独立的队列服务异步推理框架,解决了异步推理的负载均衡、实例异常时任务重分配等问题,确保请求不丢失、实例不过载。
|
4月前
|
存储 Web App开发 前端开发
Python + Requests库爬取动态Ajax分页数据
Python + Requests库爬取动态Ajax分页数据
|
4月前
|
机器学习/深度学习 人工智能 测试技术
【ICML2025】大模型后训练性能4倍提升!阿里云PAI团队研究成果ChunkFlow中选
近日,阿里云 PAI 团队、通义实验室与中国科学院大学前沿交叉科学学院合作在机器学习顶级会议 ICML 2025 上发表论文 Efficient Long Context Fine-tuning with Chunk Flow。ChunkFlow 作为阿里云在变长和超长序列数据集上高效训练解决方案,针对处理变长和超长序列数据的性能问题,提出了以 Chunk 为中心的训练机制,支撑 Qwen 全系列模型的长序列续训练和微调任务,在阿里云内部的大量的业务上带来2倍以上的端到端性能收益,大大降低了训练消耗的 GPU 卡时。
|
4月前
|
算法 物联网 定位技术
蓝牙室内定位技术解决方案:核心技术架构与优化实践
本文探讨了蓝牙iBeacon与Lora结合的室内定位技术,分析其在复杂室内环境中的优势与挑战。通过三层架构实现高精度定位,并提出硬件、算法与部署优化方向,助力智慧仓储、医疗等场景智能化升级。
282 0
蓝牙室内定位技术解决方案:核心技术架构与优化实践
|
4月前
|
传感器 运维 机器人
解析 RS485 总线:从技术内核到终端电阻的可靠性密码
RS485 总线凭借差分传输、多节点组网与长距离通信等特性,成为工业自动化领域的核心通信技术。其稳定运行离不开终端电阻的精准配置,通过匹配 120Ω 阻抗有效抑制信号反射,保障数据完整性。本文从技术原理到工程实践,深入解析 RS485 总线的可靠性设计,揭示终端电阻在抗干扰、布线与故障排查中的关键作用。
310 0
|
4月前
|
人工智能 容灾 专有云
阿里云亮相2025可信云大会,获中国信通院多项权威认证
2025年7月22-23日,由中国信息通信研究院、中国通信标准化协会联合主办的“2025可信云大会”在北京举行。本届大会以“云智融合,可信未来”为主题,汇聚业内专家、头部企业、行业代表等超300人参会,共同探讨人工智能与云计算融合发展的新趋势。 作为国内云计算领域的技术引领者,阿里云在本届大会获得多项权威认证及行业认可,并全面分享在智算服务、一云多芯、可运营云等领域的创新实践,为政企客户打造AI时代的智能化新引擎。
572 0
|
4月前
|
存储 人工智能 前端开发
全球首个搭载Kimi-K2&Qwen3-Coder的Serverless架构VibeCoding解决方案重磅来袭!
Kimi-K2模型近期表现抢眼,编程能力尤为突出,成功挑战了DeepSeek的开源模型榜首地位。其代码生成效果惊艳,配合Qwen3-Coder,展现强大开发潜力。本文介绍基于Serverless架构的VibeCoding方案,依托Function AI,实现从创意到上线的完整编码智能体解决方案,适用于个人、泛开发者及企业用户。方案支持普通与专家两种模式,AI可自主开发小游戏并构建游戏平台,具备数据库交互、多智能体协作、自动化部署等能力。部署简便,访问阿里云Function AI控制台即可快速搭建。
全球首个搭载Kimi-K2&Qwen3-Coder的Serverless架构VibeCoding解决方案重磅来袭!
|
4月前
|
API 开发工具 git
使用git pull遇到Automatic merge failed; fix conflicts and then commit the result.解决方案卓伊凡
使用git pull遇到Automatic merge failed; fix conflicts and then commit the result.解决方案卓伊凡
235 0
使用git pull遇到Automatic merge failed; fix conflicts and then commit the result.解决方案卓伊凡
|
4月前
|
人工智能 自然语言处理 机器人
RPA和按键精灵有什么区别?
在数字时代,RPA与按键精灵虽都实现自动化,但本质差异显著。按键精灵依赖屏幕像素模拟操作,适合简单重复任务;而RPA通过系统集成与对象识别,胜任复杂业务流程,具备高适应性、智能扩展与企业级管理能力。二者适用场景不同,选择关键在于匹配实际需求。
RPA和按键精灵有什么区别?
|
4月前
|
存储 供应链 监控
如何开发一套供应商管理系统?(附架构图+流程图+代码参考)
本文介绍如何开发供应商管理系统,涵盖系统核心功能、业务流程、开发技巧及实现效果,助力企业提升采购效率与供应链管理水平。