您现在的位置是:首页 >技术交流 >Qt之QGraphicsView实现截图(漏洞百出且BUG丛生版,部分源码+注释)网站首页技术交流

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

lw向北. 2023-06-21 20:00:03
简介Qt之QGraphicsView实现截图(漏洞百出且BUG丛生版,部分源码+注释)

一、截图操作示例图

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/)

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

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。