您现在的位置是:首页 >技术交流 >Qt之QGraphicsView实现截图(漏洞百出且BUG丛生版,部分源码+注释)网站首页技术交流
Qt之QGraphicsView实现截图(漏洞百出且BUG丛生版,部分源码+注释)
简介Qt之QGraphicsView实现截图(漏洞百出且BUG丛生版,部分源码+注释)
文章目录
一、截图操作示例图
1.图元绘制示例
下方一次绘制的图元为:矩形、圆形、箭头、画笔。
2.文本添加操作示例
下方为添加文本操作,演示文本过多时,文本框便捷不超出编辑区边界。
3.设置操作示例
下方为演示设置弹窗更新画笔颜色、画笔粗细更新后的绘制效果。
4.截图拖动示例
下方为截图图片拖动效果,仅支持未添加图元的情况。
5.文件保存示例
下方操作为截图保存当前截图,并再次打开保存路径验证保存成功的情况。
6.剪切板粘贴示例
下方操作为截图确定,并粘贴至Word中的操作
二、内容指路和思路
- 图标准备,可通过阿里巴巴矢量图标库获取
- 托盘图标对象,可通过Qt之QSystemTrayIcon(托盘图标)的使用(含源码+注释)查看
- 基本图形绘制,画笔实现和矩形绘制
- 箭头绘制,Qt绘制带箭头的线段
- 文本添加思路,此处博主直接走了个捷径,通过创建一个QTextEdit控件,设置其全透明和显示位置来实现文本添加(第三节附源码)。
- 多图形的绘制,不同数据通过QVariant的canConvert、setValue和value函数实现不同类型的存储(第三节附部分源码)。
- 图形的改变,主要通过鼠标事件实现并且图片更新要通过 “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/)
注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。