• 8483阅读
  • 35回复

基于QT的截图工具 [复制链接]

上一主题 下一主题
离线qiuzhiqian
 

只看楼主 倒序阅读 楼主  发表于: 2017-08-06
— 本帖被 alexltr 执行加亮操作(2017-08-20) —
概述
这是一个使用QT设计的截图工具

目前效果图












历程
意动
现在网上免费的截图工具很多,最近用了一款很不错的,叫Snipaste。
这个软件就是基于QT开发的,不过并没有开源,软件设计的很好用,界面也很清新,于是我也想自己尝试这设计一个这样的工具来练练手。
于是就有了这样的一个工程

参考
虽然有了想法,但是还是完全不知道怎么办啊。不用担心,QT有大把的官方例程。
我从官方找到了一个叫做sceenshot的例程,这是一个简单的全屏截图的例子,从这个例子中,我们知道了两个重要的东西
1. **获取屏幕分辨率**
    
  1. const QRect screenGeometry = QApplication::desktop()->screenGeometry(this);
  2. screen_width=screenGeometry.width();
  3. screen_height=screenGeometry.height();



2. **截图API**
    
  1. QScreen *screen = QGuiApplication::primaryScreen();
  2. originalPixmap = screen->grabWindow(0,x,y,width,height);





其实,在有了以上两个知识后,我们就已经可以截取屏幕上的任意区域的图片了。
grabWindow这个函数我也最关心的就是四个参数x,y,width,height。这四个参数就是一个矩形框参数,只要给定了这四个参数,想截哪里截哪里。
比如我想截取屏幕上的从点(30,50)-->(240,350)的区域截图

  1. QScreen *screen = QGuiApplication::primaryScreen();
  2. originalPixmap = screen->grabWindow(0,30,50,(240-30),(350-50));




思考
那么用户在使用过程中,如何通过交互将这四个参数传递给程序呢?方法还是很多的,比如:
1. 我设计四个输入框,用户在截屏前先手动输入这四个参数对应的值,然后点击按键截屏。嗯...想想都感觉好傻。
2. 用鼠标选定一个区域,然后将矩形区域转化为这四个参数值,然后截屏。嗯大家都是这么干的,既然如此,我也这么来吧。

那么,我们的方案基本定下来了,即用户通过点击左键并拖动鼠标来选择需要截屏的区域,然后程序将坐标传递给grabWindow,从而完成截图。

1. 由于我们需要通过点击鼠标、拖动鼠标这些动作完成一些特定的功能,所以我们需要重载各种鼠标事件。
2. 为了让用户知道自己拖动的范围在什么地方,所以在拖动时要绘制出矩形的图形,即我们需要绘制矩形。

所以我们的步骤是:
1. 用户触发截图动作
2. 用户开始截图,按下鼠标左键然后拖动来选定区域,并实时将选在的区域显示在屏幕上
3. 完成截图,图片保存到本地或剪切板

## 深入
现在有了上面的步骤,我们就按照这个步骤来实现,我们可以看到,主要的任务都在第二步。
那么要实现第二步,我们又会想到一些问题

  1. 问:我们要绘制矩形框,这个矩形框绘制在什么上面?
  2. 思考:由QT的特性可以绘制在QWidget或者继承自QWidget的控件上
  3. 答:QWidget及QWidget属性控件


  1. 问:这个控件有什么特性?
  2. 思考:我们来仔细思考一下截图时拖动选框的过程,首先我们能看到整个屏幕当前的画面,然后鼠标可以在整个屏幕范围移动,绘制区域可以在整个屏幕内选择。
  3. 当然还有一点,我们鼠标的动作都是在这个控件上完成的,那么这个控件必须在所有窗体的顶层,即置顶。
  4. 答:全屏,显示屏幕画面,置顶

  1. 问:全屏和置顶好实现,显示屏幕画面怎么弄?
  2. 思考:由于我们的绘图控件是全屏的,并且置顶的,那么其实屏幕画面是在这个绘图控件的下面,即要截屏的画面被绘图控件(以下称为画布)挡住了。
  3. 所以要实现画布显示屏幕画面有两种方法。
  4. 第一种就是让画布透明,画布是透明的,自然就能够显示到下面的屏幕画面了。
  5. 第二种方法就是在屏幕画面被画布挡住之前将屏幕截下来,然后将这个截取的图片显示到幕布上,此处我们用第二种方法来实现。
  6. 答:在画布显示之前先截取屏幕图片,然后显示画布,然后之前截取的屏幕画面在画布上显示。


所以。通过以上的问答,基本就确定了我们的设计思路。

最终思路


1、触发截图(快捷键或单击图标)  
2、截取全屏画面  
3、显示画布,画布全屏,画布置顶,画布显示之前截取的全屏画面  
4、通过重写鼠标和绘图函数来达到显示鼠标拖动区间,  
5、截取鼠标拖动区间图案,弹出保存选项  
6、手动调整截图区域  
7、添加线、矩形以及椭圆标记功能,设置标记画笔  
8、保存截屏到文件或保存截屏到剪切板或放弃截屏  
9、退出  

待完善功能
1、标记大小位置调整  

使用
使用很简单,无需过多介绍,展示一些示意图  
英文界面



中文界面




提醒

如果发现软件的中文无法起作用,可以按以下步骤处理:  
1、请确保你的软件安装目录下面有en.qm何zh_cn.qm这两个文件  
2、如果有这两个文件,但仍然不起作用,请确保你的qm文件和本软件的版本是兼容的  
3、如果以上的方法都没有用,请下载本软件源码,自行编译二进制文件,同时更新qm文件  
4、如果以上还无法解决,请联系我

源码地址:https://github.com/qiuzhiqian/ScreenShotTool
离线xzp21st

只看该作者 1楼 发表于: 2017-08-07
    
离线renzhihe

只看该作者 2楼 发表于: 2017-08-07
非常棒
离线michelle_hxy

只看该作者 3楼 发表于: 2017-08-07
离线snolkmg

只看该作者 4楼 发表于: 2017-08-07
值得学习
离线clickto

只看该作者 5楼 发表于: 2017-08-07
感谢楼主分享!!!
离线stlcours

只看该作者 6楼 发表于: 2017-08-07
给了你一个Star
离线crazy

只看该作者 7楼 发表于: 2017-08-08
很棒的一个软件,开发过程思路讲的也很详细
C/C++/Qt爱好者
邮箱: kevinlq0912@163.com
公众号: devstone
博客:http://kevinlq.com/
离线liuchangyin

只看该作者 8楼 发表于: 2017-08-08
离线qiuzhiqian

只看该作者 9楼 发表于: 2017-08-08
回 xzp21st 的帖子
xzp21st:[表情]  [表情]  [表情]  (2017-08-07 07:49) 

离线qiuzhiqian

只看该作者 10楼 发表于: 2017-08-08
回 crazy 的帖子
crazy:很棒的一个软件,开发过程思路讲的也很详细[表情] [表情]  (2017-08-08 08:15) 

谢谢支持
离线qiuzhiqian

只看该作者 11楼 发表于: 2017-08-08
回 renzhihe 的帖子
renzhihe:非常棒 (2017-08-07 16:17) 

欢迎捧场
离线qiuzhiqian

只看该作者 12楼 发表于: 2017-08-08
回 michelle_hxy 的帖子
michelle_hxy:赞[表情] [表情]  (2017-08-07 16:40) 

谢谢支持
离线qiuzhiqian

只看该作者 13楼 发表于: 2017-08-08
回 snolkmg 的帖子
snolkmg:值得学习[表情]  (2017-08-07 16:56) 

离线qiuzhiqian

只看该作者 14楼 发表于: 2017-08-08
回 stlcours 的帖子
stlcours:给了你一个Star[表情]  (2017-08-07 22:17) 

灰常感谢
离线qiuzhiqian

只看该作者 15楼 发表于: 2017-08-08
回 crazy 的帖子
crazy:很棒的一个软件,开发过程思路讲的也很详细[表情] [表情]  (2017-08-08 08:15) 

大神你好
离线qiuzhiqian

只看该作者 16楼 发表于: 2017-08-08
回 liuchangyin 的帖子
liuchangyin:[表情]  (2017-08-08 09:36) 

离线nigoole

只看该作者 17楼 发表于: 2017-08-09
这种从无到有的发历程比单纯的开源收益太多!感谢贡献
有句话说得好:好好学习,天天向上。加油~~!有上船的朋友联系企鹅393320854
离线nigoole

只看该作者 18楼 发表于: 2017-08-09
画图里面添加个抗锯齿!
  1. void Canvas::paintEvent(QPaintEvent *e)
  2. {
  3.     QPainter painter(this);
  4.     painter.setRenderHint(QPainter::Antialiasing);
  5.    ...
  6. }




有句话说得好:好好学习,天天向上。加油~~!有上船的朋友联系企鹅393320854
离线qiuzhiqian

只看该作者 19楼 发表于: 2017-08-09
回 nigoole 的帖子
nigoole:画图里面添加个抗锯齿!
void Canvas::paintEvent(QPaintEvent *e)
{
    QPainter painter(this);
....... (2017-08-09 10:41) 

OK,thank you
离线pengchengfan

只看该作者 20楼 发表于: 2017-08-10
很有用,拿来用了,顺便研究一下代码,
离线向天承影

只看该作者 21楼 发表于: 2017-08-10
不能太赞!!!
离线liudianwu

只看该作者 22楼 发表于: 2017-08-10
非常不错,文章大赞!
欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线qiuzhiqian

只看该作者 23楼 发表于: 2017-08-11
回 liudianwu 的帖子
liudianwu:非常不错,文章大赞! (2017-08-10 21:17) 

大佬你好
离线wall-e

只看该作者 24楼 发表于: 2017-08-17
那我就勉为其难的拿走啦 ,大赞
离线微笑内敛

只看该作者 25楼 发表于: 2018-01-17
    
离线return

只看该作者 26楼 发表于: 2018-01-18
    
离线林慧

只看该作者 27楼 发表于: 2018-02-02
感谢楼主无私的奉献
离线houwenbin

只看该作者 28楼 发表于: 2018-02-03
不错更新了我对窗口透明操作的认识
离线genven

只看该作者 29楼 发表于: 2018-04-08
你好楼主!我下载学习时,发现截图的清晰度不是很好(不知道是不是我的电脑的问题),请问有什么办法提高保存下来的清晰度呢?
离线白马

只看该作者 30楼 发表于: 2018-04-08
离线dddggg

只看该作者 31楼 发表于: 2018-04-14
学习 开发思路很详细
菜鸟
离线tonyonce

只看该作者 32楼 发表于: 2018-04-14
多谢楼主分享
离线wbcg00

只看该作者 33楼 发表于: 2018-04-14
我还是太天真 以为看了思路就能做出来 ;
在认真学习
离线yyzq

只看该作者 34楼 发表于: 2018-04-19
文章写得很好,看的出来很用心。。。
离线fancy0047

只看该作者 35楼 发表于: 2019-09-18
请问在gitee上面有代码仓库吗?
快速回复
限100 字节
 
上一个 下一个