Qt之QGraphicsView实现截图(漏洞百出且BUG丛生版,部分源码+注释)

news2024/11/28 4:32:47

文章目录

  • 一、截图操作示例图
    • 1.图元绘制示例
    • 2.文本添加操作示例
    • 3.设置操作示例
    • 4.截图拖动示例
    • 5.文件保存示例
    • 6.剪切板粘贴示例
  • 二、内容指路和思路
  • 三、部分源码
    • 1.自定义文本框源码
    • 2.多类型图形数据的存储
    • 3.截图源码
  • 总结
  • 相关文章

一、截图操作示例图

1.图元绘制示例

下方一次绘制的图元为:矩形、圆形、箭头、画笔。
在这里插入图片描述

2.文本添加操作示例

下方为添加文本操作,演示文本过多时,文本框便捷不超出编辑区边界。
在这里插入图片描述

3.设置操作示例

下方为演示设置弹窗更新画笔颜色、画笔粗细更新后的绘制效果。
在这里插入图片描述

4.截图拖动示例

下方为截图图片拖动效果,仅支持未添加图元的情况。
在这里插入图片描述

5.文件保存示例

下方操作为截图保存当前截图,并再次打开保存路径验证保存成功的情况。
在这里插入图片描述

6.剪切板粘贴示例

下方操作为截图确定,并粘贴至Word中的操作
在这里插入图片描述

二、内容指路和思路

  1. 图标准备,可通过阿里巴巴矢量图标库获取
  2. 托盘图标对象,可通过Qt之QSystemTrayIcon(托盘图标)的使用(含源码+注释)查看
  3. 基本图形绘制,画笔实现和矩形绘制
  4. 箭头绘制,Qt绘制带箭头的线段
  5. 文本添加思路,此处博主直接走了个捷径,通过创建一个QTextEdit控件,设置其全透明和显示位置来实现文本添加(第三节附源码)。
  6. 多图形的绘制,不同数据通过QVariant的canConvert、setValue和value函数实现不同类型的存储(第三节附部分源码)。
  7. 图形的改变,主要通过鼠标事件实现并且图片更新要通过 “this->viewport()->update();”重绘图形

三、部分源码

1.自定义文本框源码

CTextEdit.h

#ifndef CTEXTEDIT_H
#define CTEXTEDIT_H

#include <QObject>
#include <QTextEdit>

class CTextEdit : public QTextEdit
{
    Q_OBJECT
public:
    explicit CTextEdit(QWidget *parent = nullptr);
    ~CTextEdit();

    /**
     * @brief setEditTopLeftPos 设置左上角位置
     * @param pos 位置
     */
    void setEditTopLeftPos(const QPoint &pos);

    /**
     * @brief setTextPointSize 设置文本大小
     * @param size 文本大小
     */
    void setTextPointSize(int size);

    /**
     * @brief setEditRange 设置编辑边界
     * @param editRange 编辑边界
     */
    void setEditRange(const QRect &editRange);

    /**
     * @brief editFlag 获取编辑标记
     * @return 编辑标记值
     */
    bool editFlag() const;

    /**
     * @brief setEditFlag 设置标记标记
     * @param editFlag 更新的编辑标记
     */
    void setEditFlag(bool editFlag);

private slots:
    /**
     * @brief on_textChanged 文本更新槽函数
     */
    void on_textChanged();

signals:
    /**
     * @brief editTextFinished 文本编辑完成信号
     * @param text 完成文本
     */
    void editTextFinished(const QString &text);

    // QWidget interface
protected:
    /**
     * @brief focusOutEvent 焦点丢失对象
     * @param event 事件对象
     */
    void focusOutEvent(QFocusEvent *event);

private:
    QRect   m_editRange;    // 编辑边界

    bool    m_editFlag;     // 编辑标记
};

#endif // CTEXTEDIT_H

CTextEdit.cpp

#include "CTextEdit.h"
#include <QDebug>
#include <QScrollBar>

CTextEdit::CTextEdit(QWidget *parent)
    : QTextEdit(parent)
    , m_editFlag(false)
{
    this->setWindowFlag(Qt::FramelessWindowHint, true);
    this->setStyleSheet("border: 1px solid red;background:transparent;");
    this->hide();
    // 文本颜色为红色
    this->setTextColor(Qt::red);
    // 设置默认文本大小
    this->setFontPointSize(10);
    // 设置滚动条隐藏
    this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    // 文本更新信号槽
    connect(this, &CTextEdit::textChanged, this, &CTextEdit::on_textChanged);
}

CTextEdit::~CTextEdit()
{

}

void CTextEdit::setEditTopLeftPos(const QPoint &pos)
{
    const QPoint &editBrPos = m_editRange.bottomRight();
    QPoint brPos;
    brPos.setX(pos.x() + 80 > editBrPos.x()? editBrPos.x(): pos.x() + 20);
    brPos.setY(pos.y() + 30 > editBrPos.y()? editBrPos.y(): pos.y() + 30);
    // 设置显示位置
    this->setGeometry(QRect(pos, brPos));
    // 控件显示
    this->setVisible(true);
}

void CTextEdit::setTextPointSize(int size)
{
    // 设置字体大小
    setFontPointSize(size * 5);
}

void CTextEdit::on_textChanged()
{
    // 获取文本字体样式
    QFont tmpFont = this->font();
    // 设置文本大小
    tmpFont.setPointSize(this->fontPointSize());
    // 创建字体度量对象并传入样式
    QFontMetrics metrics(tmpFont);
    // 获取控件文本
    QString text = this->toPlainText();
    // 获取文本宽度并添加20像素的空间
    int width = metrics.width(text) + 20;

    // 获取左上角的点
    QPoint tlPos = this->geometry().topLeft();
    // 获取窗口大小
    QSize size = this->rect().size();

    // 获取水平/垂直可便宜的最大宽度/高度
    int hOffset = m_editRange.right() - tlPos.x();
    int vOffset = m_editRange.bottom() - tlPos.y();

    // 更新宽度
    size.setWidth(width < hOffset? width: hOffset);

    // 获取滚动条最大值
    int height = this->verticalScrollBar()->maximum();
    // 更新高度
    size.setHeight(height + this->height() < vOffset? height + this->height(): vOffset);

    // 更新显示区域
    this->setGeometry(QRect(tlPos, size));
}

void CTextEdit::focusOutEvent(QFocusEvent *event)
{
    Q_UNUSED(event);
    this->hide();
    // 获取编辑的文本
    QString text = this->toPlainText();
    // 当字符串不为空才进入
    if(!text.isEmpty())
    {
        // 发出编辑完成的文本并清空编辑框内容
        emit editTextFinished(text);
        this->clear();
    }
}

bool CTextEdit::editFlag() const
{
    return m_editFlag;
}

void CTextEdit::setEditFlag(bool editFlag)
{
    m_editFlag = editFlag;
}

void CTextEdit::setEditRange(const QRect &editRange)
{
    m_editRange = editRange;
}

2.多类型图形数据的存储

添加矩形/圆形数据

            // 创建对应图像数据
            QPair<bool, QRect> tmpData;
            // 添加数据
            tmpData.first = ToolType::DRAW_RECTANGLE == m_toolGraphiWgt->curToolType();
            tmpData.second = QRect(m_pressPos, endPos);
            var.setValue<QPair<bool, QRect>>(tmpData);

转换矩形/圆形数据

        // 图像转换为对应类型的存储数据
        QPair<bool, QRect> pair = figureInfo.figureData.value<QPair<bool, QRect>>();
        if(pair.first)
        {
            painter->drawRect(pair.second); // 绘制矩形
        }
        else
        {
            painter->drawEllipse(pair.second);  // 绘制圆形
        }

3.截图源码

    QScreen *screen = QApplication::primaryScreen();
    m_pixmap =  screen->grabWindow(0);

总结

总的来说截图软件没有太大的难点,可能稍微多一点就是细节功能的微调等;其中存在的问题包括:截图程序置顶、截图编辑区域拖动更新大小、鼠标跟踪优化等问题。(可私聊获取源码)

相关文章

Qt之QSystemTrayIcon(托盘图标)的使用(含源码+注释)
Qt之QPainter实现画笔功能(逻辑简单,不懂算我输 含源码+注释)
Qt之QPainter绘制多个矩形/圆形(含源码+注释)
Qt绘制带箭头的线段

友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 o/)

注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/470993.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python小姿势 - ## 安装Python

安装Python 如果你还没有安装Python&#xff0c;那么现在是时候安装它了。有很多不同的选择&#xff0c;但是我们推荐使用Anaconda。 Anaconda是一个用于科学计算的Python发行版&#xff0c;捆绑了许多科学计算所需的包&#xff0c;并且Anaconda的安装包大小也不是很大&#xf…

AVUE做二级联查,本次需求:地市、市县做二级联动

目录 a. 数据库设计 b.前端代码解析***&#xff1a;** c. 后端接口解析&#xff1a; 注意&#xff1a; a. 数据库设计 表结构一定要设计好, 包括&#xff1a;主键、编号&#xff08;code-> 含义&#xff1a;地市、市县的唯一标识&#xff09;、父类编码&#xff08;在本次…

【高危】泛微 e-cology <10.57 存在 SQL注入漏洞(POC)(MPS-ndqt-0im5)

漏洞描述 泛微协同管理应用平台(e-cology)是一套企业大型协同管理平台。 泛微 e-cology 受影响版本存在SQL注入漏洞&#xff0c;未经授权的远程攻击者可通过发送特殊的HTTP请求来获取数据库的敏感信息。 漏洞名称GeoServer 存在 sql 注入漏洞漏洞类型SQL注入发现时间2023/4/…

深度学习 GNN图神经网络(四)线性回归之ESOL数据集水溶性预测

线性回归之ESOL数据集水溶性预测 一、前言二、ESOL数据集三、加载数据集四、数据拆分五、构造模型六、训练模型七、测试结果八、分类问题参考文献 一、前言 本文旨在使用化合物分子的SMILES字符串进行数据模型训练&#xff0c;对其水溶性的值进行预测。 之前的文章《深度学习…

前端开发中获取各种高度宽度

一、前言 前端开发中经常需要获取页面还有屏幕的高度和宽度进行计算,此文即介绍如何用 JavaScript 获取这些尺寸 二、屏幕尺寸 screen.height&#xff1a;屏幕高度screen.width&#xff1a;屏幕宽度screen.availHeight&#xff1a;屏幕可用高度。即屏幕高度减去上下任务栏后的…

2.2 定点加法 减法运算

学习前的建议 以下是一些学习定点加法和减法运算的建议&#xff1a; 掌握定点数的表示方法&#xff1a;在进行定点加法和减法运算之前&#xff0c;需要先了解定点数的表示方法&#xff0c;包括定点数的位数、小数点位置以及符号位等信息。 理解定点加法和减法的原理&#xf…

nginx配置sh脚本远程执行一键安装

背景 本地多机重复操作某些shell指令&#xff0c;分步执行&#xff0c;很耗费时间&#xff0c; 需要远程一键部署&#xff0c;傻瓜化运维&#xff0c;更为通用安装。 即参考docker通用安装 sudo curl https://get.docker.com | sh - # sudo python3 -m pip install docker-co…

SignalR实现简单的Web端实时通讯,跳过WebSocket验证,Swagger加锁后不能访问接口,Script setup不支持动态绑定

版本.Net6Vue3Element-Plus 问题 Swagger加锁后不能访问接口 &#xff08;看第三步&#xff09;跳过WebSocket验证 &#xff08;看第四步里面&#xff09;添加自定义接受方法 &#xff08;看第四步&#xff09;不能使用 第一步、下载包 后端&#xff1a; 前端&#xff1a;…

Android内存优化场景

1、集合类 内存泄露原因 集合类 添加元素后&#xff0c;仍引用着 集合元素对象&#xff0c;导致该集合元素对象不可被回收&#xff0c;从而 导致内存泄漏实例演示 // 通过循环申请Object 对象 & 将申请的对象逐个放入到集合List List<Object> objectList new Arra…

VBA-自定义面板,使用SQL查询Excel数据

需求 定制插件&#xff0c;实现用户打开任意一个工作簿&#xff0c;写sql对Excel中的数据进行查询 案例sql需求场景&#xff1a; 需求 筛选日期小于’2023-4-24’&#xff0c;按group分区&#xff0c;求和各分组下的销售额&#xff0c;返回结果集新建工作表写入 数据源 现…

Docker-compose 启动 lnmp 开发环境

GitHub传送阵 docker-lnmp 项目帮助开发者快速构建本地开发环境&#xff0c;包括Nginx、PHP、MySQL、Redis 服务镜像&#xff0c;支持配置文件和日志文件映射&#xff0c;不限操作系统&#xff1b;此项目适合个人开发者本机部署&#xff0c;可以快速切换服务版本满足学习服务新…

国产开源项目管理软件ZenTao

本文应网友 ukiyoec 要求而写&#xff1b; 什么是禅道 &#xff1f; 禅道 (ZenTao)是国产开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体&#xff0c;是一款专业的研发项目管理软件&#xff0c;完整覆盖了研发项目管理的核心流程。禅…

2023-Hive性能企业级调优

Hive作为大数据平台举足轻重的框架&#xff0c;以其稳定性和简单易用性也成为当前构建企业级数据仓库时使用最多的框架之一。 但是如果我们只局限于会使用Hive&#xff0c;而不考虑性能问题&#xff0c;就难搭建出一个完美的数仓&#xff0c;所以Hive性能调优是我们大数据从业…

前端周总结

在vue里面引入ts文件报错&#xff1a; An import path cannot end with a .ts extension. Consider importing xx.js instead. 方法一&#xff08;最快&#xff09; 把引入的xx.ts后缀删除 方法二 # 在tsconfig.json中加入以下配置 "baseUrl": ".", &quo…

Oracle LiveLabs实验:DB Security - Data Masking and Subsetting (DMS)

概述 本实验介绍了适用于 Enterprise Manager 的 Oracle 数据屏蔽和子集 (DMS) 包的各种特性和功能。 它使用户有机会学习如何配置这些功能&#xff0c;以便在非生产环境中保护他们的敏感数据。 此实验申请地址在这里&#xff0c;时间为60分钟。 本实验也是DB Security Adva…

String AOP

AOP AOP(Aspect Object programmar) 面向切面编程&#xff0c;它是对某一类问题的统一处理&#xff0c;而StringAOP就是AOP思想的一种具体实现就像Ioc和DI。 AOP组成 切面(Aspect) 切⾯&#xff08;Aspect&#xff09;由切点&#xff08;Pointcut&#xff09;和通知&#x…

论文阅读笔记《Grounded Action Transformation for Robot Learning in Simulation》

Grounded Action Transformation for Robot Learning in Simulation 发表于AAAI 2017 仿真机器人学习中的接地动作变换 Hanna J, Stone P. Grounded action transformation for robot learning in simulation[C]//Proceedings of the AAAI Conference on Artificial Intellig…

Linux中的阻塞机制

我们知道在字符设备驱动中&#xff0c;应用层调用read、write等系统调用终会调到驱动中对应的接口。 可以当应用层调用read要去读硬件的数据时&#xff0c;硬件的数据未准备好&#xff0c;那我们该怎么做&#xff1f; 一种办法是直接返回并报错&#xff0c;但是这样应用层要获得…

linux通配符和正则表达式深层解析...

目录&#xff1a; (一)了解通配符和正则的作用 (二)通配符的使用 (三)正则表达式的使用 (四)扩展正则表达式的使用 (一)了解通配符和正则的作用 (1.1)在我们日常的工作中&#xff0c;我们都会使用到通配符或者正则表达式。通配符是一种特殊语句&#xff0c;主要有星号(*)和问号…

交换机和路由器到底有什么区别???

我&#xff1a;度娘度娘&#xff0c;交换机和路由器的区别是什么呢&#xff1f; 度娘&#xff1a;一个工作在第二层数据链路层&#xff0c;一个工作在第三层网络层。 我&#xff1a;哈&#xff1f;那工作在不同层会有什么区别&#xff1f;为什么要工作在不同层&#xff1f; …