qt/LedOK/oescreenshot/oescreenshot.h
2022-01-04 18:11:48 +08:00

509 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @author : 陈鲁勇
* @date : 2017年04月
* @version: 1.0
* @note : 根据 Apache 许可证 2.0 版(以下简称“许可证”)授权;
* 除非遵守本许可,否则您不能使用这个文件。
* @remarks: 您可以获得该许可的副本:
* http://www.apache.org/licenses/LICENSE-2.0
* 除非适用法律需要或者书面同意,按本许可分发的软件
* 要按“原样”分发,没有任何形式的,明确或隐含的担保条款。
* 参见按照本许可控制许可权限及限制的特定语言的许可证。
*
* 你可以获得该代码的最新版本:
*
* https://git.oschina.net/Mr_ChenLuYong/screenshot
*
* 开源社区的所有人都期待与你的共同维护。
*
*
* 如果你对这些代码还有不理解的地方可以通过最新的文章进行学习:
*
* 博客地址http://blog.csdn.net/csnd_ayo
*
* 文章地址http://blog.csdn.net/csnd_ayo/article/details/70197915
*
* 期待你提交Bug欢迎Issues。
*
*/
#ifndef OESCREENSHOT_H
#define OESCREENSHOT_H
#include <memory>
#include <QRect>
#include <QWidget>
class OEScreen;
class OERect;
class OEAmplifier;
class QTimer;
class QMenu;
/**
* @class : OEScreenshot
* @brief : 截屏功能的主要入口,
* 管理全局热键,资源的回收与释放.
* @remark: 调用示例( OEScreenshot::Instance(); )
*/
class OEScreenshot : public QWidget {
Q_OBJECT
signals:
/**
* @brief : 鼠标移动(信号)
* @param : int x轴的坐标
* @param : int y轴的坐标
* @date : 2017年04月18日
*/
void cursorPosChange(int, int);
/**
* @brief : 双击(信号)
* @date : 2017年04月18日
*/
void doubleClick(void);
/**
* @brief : 鼠标当前位置最小的子窗口(信号)
* @param : QRect 当前窗口的矩形数据
* @date : 2017年04月18日
*/
void findChildWind(QRect);
public:
/**
* @brief : 构造函数
* @note : 当前依附的父窗口(一般不给父窗口)
* @date : 2017年04月16日
*/
explicit OEScreenshot(QWidget *parent = 0);
~OEScreenshot(void);
/**
* @brief : 窗口实例
* @note : 通过这个函数获得截图器的整个实例
* @return: 返回 OEScreenshot 实例指针
* @date : 2017年04月15日
*/
static OEScreenshot *Instance(void);
/**
* @brief : 摧毁截图窗口
* @note : 通过这个函数可以摧毁整个截图窗口
* @date : 2017年04月30日
*/
static void destroy(void);
protected:
/**
* @brief : 隐藏窗口事件
*/
virtual void hideEvent(QHideEvent *);
/**
* @brief : 关闭窗口事件
*/
virtual void closeEvent(QCloseEvent *);
/**
* @brief : 双击事件
*/
virtual void mouseDoubleClickEvent(QMouseEvent*);
/**
* @brief : 鼠标按下事件
*/
virtual void mousePressEvent(QMouseEvent *);
/**
* @brief : 鼠标释放事件
*/
virtual void mouseReleaseEvent(QMouseEvent *e);
/**
* @brief : 鼠标移动事件
*/
virtual void mouseMoveEvent(QMouseEvent *e);
/**
* @brief : 按键按下事件
*/
virtual void keyPressEvent(QKeyEvent *e);
/**
* @brief : 自绘事件
*/
virtual void paintEvent(QPaintEvent *);
/**
* @brief : 更新当前鼠标选区的窗口
*/
void updateMouse(void);
private:
/**
* @brief : 初始化放大镜 (色彩采集器)
* @note : 他需要屏幕的原画作为放大器的放大元素
* @param : originPainting 放大器必要的元素若为空则默认用originPainting_原画
* @date : 2017年04月15日
* @remark: 需先行调用getGlobalScreen。
*/
void initAmplifier(std::shared_ptr<QPixmap> originPainting = nullptr);
/**
* @brief : 测量控件 (大小感知器)
* @date : 2017年04月27日
*/
void initMeasureWidget(void);
/**
* @brief : 初始化截屏背景
* @return: QPixmap 经过暗色处理的屏幕图
* @date : 2017年04月15日
*/
std::shared_ptr<QPixmap> initGlobalScreen(void);
/**
* @brief : 初始化鼠标
* @note : 为鼠标设置默认状态下的图标样式
* @param : ico 鼠标图片的资源文件路径
* @date : 2017年04月15日
* @remark: 若参数未填写在使用本程序默认的鼠标Logo
*/
void initCursor(const QString& ico = "");
/**
* @brief : 创建截图器
* @note : 若截图器已存在,则返回截图器示例,不会重复创建。
* @param : pos 截图器的起始位置 (给当前鼠标位置即可)
* @date : 2017年04月16日
* @remark: 创建截图器前,需要创建相关的组件,(例:大小感知器,放大取色器)
*/
std::shared_ptr<OEScreen> createScreen(const QPoint &pos);
/**
* @brief : 摧毁截图器
* @note : 若截图器已存在,则摧毁示例,并清理示例创建的连带资源
* @date : 2017年04月16日
*/
void destroyScreen(void);
/**
* @brief : 获得当前屏幕的大小
* @note : 这个函数是支持多屏幕的,示例:双屏幕 QRect-1920, 0, 3840, 1080
* @return: 返回 QRect 引用
* @date : 2017年04月15日
*/
const QRect& getScreenRect(void);
/**
* @brief : 获得屏幕的原画
* @note : 他不会重复获得屏幕原画,如果有,则返回原有的原画
* @return: QPixmap* 指针
* @date : 2017年04月15日
* @remark: 若想重新获得屏幕原画,需要清理原有资源
*/
std::shared_ptr<QPixmap> getGlobalScreen(void);
private:
/// 截屏窗口是否已经展示
bool isLeftPressed_;
/// 用于检测误操作
QPoint startPoint_;
/// 当前桌面屏幕的矩形数据
QRect desktopRect_;
/// 屏幕暗色背景图
std::shared_ptr<QPixmap> backgroundScreen_;
/// 屏幕原画
std::shared_ptr<QPixmap> originPainting_;
/// 截图屏幕
std::shared_ptr<OEScreen> screenTool_;
/// 截图器大小感知器
std::shared_ptr<OERect> rectTool_;
/// 放大取色器
std::shared_ptr<OEAmplifier> amplifierTool_;
/// 当前鼠标选区最小的矩形窗口
QRect windowRect_;
/// 截屏实例对象
static OEScreenshot *self_;
/// 置顶定时器
QTimer* egoisticTimer_;
/// 活动窗口
static bool isActivity_;
private slots:
/**
* @brief : Window下霸道置顶唯我独尊
* @date : 2017年04月28日
* @remark: 使用该函数时会终止右键菜单的行为慎重使用避免BUG
*/
void onEgoistic(void);
};
/**
* @class : OERect
* @brief : 大小感知器
* @note : 主要关乎截图器左上方的大小感知控件
*/
class OERect : public QWidget {
Q_OBJECT
signals:
public:
explicit OERect(QWidget *parent = 0);
protected:
/**
* @brief : 自绘函数
*/
void paintEvent(QPaintEvent *);
public slots:
/**
* @brief : 外部组件位置修改(槽)
* @note : 感知器修改自身位置
* @param : x 横向位置
* @param : y 纵向位置
* @date : 2017年04月15日
*/
void onPostionChange(int x, int y);
/**
* @brief : 外部组件大小修改 (槽)
* @note : 感知器修改显示的大小数据
* @param : w 宽度
* @param : h 高度
* @date : 2017年04月15日
*/
void onSizeChange(int w, int h);
private:
/// 背景色
std::shared_ptr<QPixmap> backgroundPixmap_;
/// 显示的文字信息
QString info_;
};
/**
* @class : OEScreen
* @brief : 截图器
* @note : 主要关乎图片的编辑与保存
*/
class OEScreen : public QWidget {
Q_OBJECT
signals:
/**
* @brief : 截图器大小修改(信号)
* @param : int 宽度
* @param : int 高度
* @date : 2017年04月17日
*/
void sizeChange(int,int);
/**
* @brief : 截图器窗口的位置(信号)
* @param : int 窗口的横向位置
* @param : int 窗口的纵向位置
* @date : 2017年04月17日
*/
void postionChange(int,int);
/**
* @brief : 双击 (信号)
* @date : 2017年04月17日
*/
void doubleClick(void);
protected:
/// 内边距,决定拖拽的触发。
const int PADDING_ = 6;
/// 方位枚举
enum DIRECTION {
UPPER=0,
LOWER=1,
LEFT,
RIGHT,
LEFTUPPER,
LEFTLOWER,
RIGHTLOWER,
RIGHTUPPER,
NONE
};
public:
explicit OEScreen(std::shared_ptr<QPixmap> originPainting, QPoint pos, QWidget *parent = 0);
~OEScreen() { isInit_ = false; }
/**
* @brief : 获得当前截图器是否存在
* @return: true : 存在
* @date : 2017年04月17日
*/
static bool state(void) { return isInit_; }
protected:
/**
* @brief : 获得当前坐标点的边界方位
* @param : cursor 当前鼠标的位置
* @return: DIRECTION 鼠标的方位枚举
* @date : 2017年04月17日
*/
DIRECTION getRegion(const QPoint &cursor);
/**
* @brief : 呼出菜单事件
*/
virtual void contextMenuEvent(QContextMenuEvent *);
/**
* @brief : 双击事件
*/
virtual void mouseDoubleClickEvent(QMouseEvent *e);
/**
* @brief : 鼠标按下事件
*/
virtual void mousePressEvent(QMouseEvent *e);
/**
* @brief : 鼠标释放事件
*/
virtual void mouseReleaseEvent(QMouseEvent *e);
/**
* @brief : 鼠标移动事件
*/
virtual void mouseMoveEvent(QMouseEvent *e);
/**
* @brief : 窗口移动事件
*/
virtual void moveEvent(QMoveEvent *);
/**
* @brief : 窗口大小修改事件
*/
virtual void resizeEvent(QResizeEvent *);
/**
* @brief : 窗口显示事件
*/
virtual void showEvent(QShowEvent *);
/**
* @brief : 窗口隐藏事件
*/
virtual void hideEvent(QHideEvent *);
/**
* @brief : 鼠标进入窗口事件
*/
virtual void enterEvent(QEvent *e);
/**
* @brief : 鼠标离开窗口事件
*/
virtual void leaveEvent(QEvent *e);
/**
* @brief : 窗口关闭事件
*/
virtual void closeEvent(QCloseEvent *);
/**
* @brief : 界面自绘事件
*/
virtual void paintEvent(QPaintEvent *);
private:
/**
* @brief : 获得一个以时间格式命名的文件名
* @return: QString 文件名
* @date : 2017年04月16日
*/
virtual const QString getFileName(void);
public slots:
/**
* @brief : 根据鼠标位置修改窗口大小
* @param : x 鼠标的横向位置
* @param : y 鼠标的纵向位置
* @date : 2017年04月16日
*/
void onMouseChange(int x,int y);
/**
* @brief : 保存屏幕到剪切板中
* @date : 2017年04月16日
*/
void onSaveScreen(void);
protected slots:
/**
* @brief : 保存编辑屏幕到其他路径下
* @note : 会呼出路径选择的窗口
* @date : 2017年04月16日
*/
void onSaveScreenOther(void);
/**
* @brief : 退出当前截图窗口
* @date : 2017年04月16日
*/
void quitScreenshot(void);
private:
/// 是否已经设置初始大小
static bool isInit_;
/// 窗口大小改变时,记录改变方向
DIRECTION direction_;
/// 起点
QPoint originPoint_;
/// 鼠标是否按下
bool isPressed_;
/// 拖动的距离
QPoint movePos_;
/// 标记锚点
QPolygon listMarker_;
/// 屏幕原画
std::shared_ptr<QPixmap> originPainting_;
/// 当前窗口几何数据 用于绘制截图区域
QRect currentRect_;
/// 右键菜单对象
QMenu *menu_;
};
#endif /// OESCREENSHOT_H