509 lines
12 KiB
C
509 lines
12 KiB
C
|
/**
|
|||
|
* @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
|