Qt浅谈之十三:抓图截屏

转载 2016年05月30日 14:28:55

一、简介

       因Windows下无法登录QQ时就不能抓图了,就很纠结了,而在Linux下,有时也无法抓图。所以专门使用Qt仿照Centos的抓图界面写了一个抓图软件,能实现自己的大部分需求。感兴趣的可以扩展到图片的分割组合及录屏等功能。

二、运行图

(1)本程序运行如下图1所示。

(2)其他相关截图程序的界面,如下图2所示。


三、详解

1、中文问题

(1)不同的操作系统采用编码方式不同,因此必须使用国际化翻译才能减少乱码的实现。其过程如下:

1.pro工程文件里面添加 TRANSLATIONS+=mypro.ts
2.选择Qt Creator环境的菜单栏 工具->外部->Qt语言家->更新翻译
3.桌面开始菜单里面Qt目录打开 Linguist工具
4.Linguist工具加载生成好的mypro.ts文件
5.填好翻译, 保存, Release, 就生成好编译后的qm文件
6.在工程的源文件中, 这样加载qm文件:
QTranslator translator;
translator.load("grabwindows.qm",":/");
a.installTranslator(&translator);

2、系统托盘


[cpp] view plain copy
  1. void GrabWindows::initTrayiconMenu()  
  2. {  
  3.   trayIcon = new QSystemTrayIcon(QIcon(tr(":/applets-screenshooter.ico")), this);  
  4.   trayiconMenu = new QMenu;  
  5.   restoreAction = new QAction(tr("Restore"), this);  
  6.   quitAction = new QAction(tr("Quit"), this);  
  7.   trayiconMenu->addAction(restoreAction);  
  8.   trayiconMenu->addAction(quitAction);  
  9.   trayIcon->setContextMenu(trayiconMenu);  
  10.   trayIcon->show();  
  11.   connect(trayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),  
  12.           this,SLOT(slotIconActivated(QSystemTrayIcon::ActivationReason)));  
  13.     
  14.   connect(restoreAction,SIGNAL(triggered()),this,SLOT(showNormal()));  
  15.   connect(quitAction,SIGNAL(triggered()),this,SLOT(close()));  
  16. }  

分析:QSystemTrayIcon的使用,并结合槽来捕获鼠标左键的信号,鼠标右键信号会自动弹出定义的右键菜单。

3、抓取全屏

[cpp] view plain copy
  1. fullScreenPixmap = QPixmap::grabWindow(QApplication::desktop()->winId());  
  2. fullScreenPixmap->save("fullScreen.jpg","JPG");  
  3. 或  
  4. fullScreenPixmap->save("Screenshot.png","png");  

只要完成了布局,剩下的截图代码非常简单,Qt已经做了很好的封装。

4、抓取当前窗口

[cpp] view plain copy
  1. if (QApplication::activeWindow()) {  
  2.         currentScreenPixmap = QPixmap::grabWindow( QApplication::activeWindow()->winId(), -2, -26, QApplication::activeWindow()->width() + 4, QApplication::activeWindow()->height() + 30);  
  3.         //currentScreenPixmap = QPixmap::grabWindow( QApplication::activeWindow()->winId());  
  4. }  
分析:暂时还有一些问题,不知道为什么当前活动的窗体只能是本窗体,其它窗体的返回值为NULL,其它的函数也试过。也无法获取到相对与本窗口的次窗口指针,感觉Qt没有提供相关的接口,要借助于系统的api接口。该问题先放置,以后有机会解决。

5、抓取任意部分

[cpp] view plain copy
  1. ScreenShotPart::ScreenShotPart(QWidget *parent) :  
  2.     QDialog(parent)  
  3. {  
  4.   //setMouseTracking(true);  
  5.   isDrawing = false;  
  6.   fullScreenPix = QPixmap::grabWindow(QApplication::desktop()->winId());  
  7.   fullTempPix = fullScreenPix;  
  8. }  
  9.   
  10. void ScreenShotPart::showEvent(QShowEvent *event)  
  11. {  
  12.   showFullScreen();  
  13.   setCursor(Qt::CrossCursor);  
  14. }  
  15.   
  16. void ScreenShotPart::paintEvent(QPaintEvent *event)  
  17. {  
  18.   QPainter painter(this);  
  19.   painter.drawPixmap(0, 0, fullTempPix);  
  20.   QDialog::paintEvent(event);  
  21. }  
分析:先截图全屏图片,显示图片占据全屏,然后使用双缓冲技术(否则会出现很多选区框)在该图片上画出选区,然后保存。其原理简单,主要是鼠标时间时记录好初始点和结束点。

[cpp] view plain copy
  1. void ScreenShotPart::mousePressEvent(QMouseEvent *event)  
  2. {  
  3.   if (event->button() == Qt::LeftButton) {  
  4.       isDrawing = true;  
  5.       startPoint = event->pos();  
  6.   }  
  7. }  
  8.   
  9. void ScreenShotPart::mouseMoveEvent(QMouseEvent *event)  
  10. {  
  11.     QPoint pt = event->pos();  
  12.     if (isDrawing) {  
  13.         fullTempPix = fullScreenPix;  
  14.         endPonit = event->pos();  
  15.         paint(fullTempPix);  
  16.     }  
  17. }  
  18.   
  19. void ScreenShotPart::mouseReleaseEvent(QMouseEvent *event)  
  20. {  
  21.     if (event->button() == Qt::LeftButton) {  
  22.       isDrawing = false;  
  23.       endPonit = event->pos();  
  24.       shotRect = QRect(startPoint, endPonit);  
  25.       paint(fullTempPix);  
  26.       savePixMap();  
  27.     }  
  28. }  

6、定时器

[cpp] view plain copy
  1. timer = new QTimer(this);  
  2. timer->start(200 + timeComBox->value() * 1000);  
分析:定时器在此处作用还是挺大的,主要是提供延时让本窗口隐藏,以获得截取的全屏图片,否则全屏总是会有本窗口的内容。

四、不足之处

(1)无法很好的抓取当前窗口,正在考虑如何截取本窗口的下一层窗体。在Windows下截图的当前窗口为空白。

(2)ComboBox下的文件系统路径无法使用,加载了文件系统也无法一次进行选择,效果图也不是很美观,这个问题还待深究。截图图片暂时只能保存到当前程序的运行目录下。

五、总结

(1)还可以根据需要在截图时将背景图片设置成灰色,效果更好。

(2)源码已经打包上传到csdn上可登录下载(http://download.csdn.net/detail/taiyang1987912/7693465)。  

(3)本人思路有限,若有更好的设计建议,也可发邮件沟通,在此先感谢!邮箱地址yang.ao@i-soft.com.cn。


相关文章推荐

QT窗口控件透明效果的实现

一. 背景刷成黑色,前景色设为白色。 方法一、paltette方式,经测试,该方法不会影响到其他控件,推荐使用 QPalette bgpal = palette(); bgpal.setColo...

Qt for android 截屏、Qml保存图片到本地

额、、当你打开这里的时候、估计已经尝试过截图并且失败一次了,别急。 是的,以前在桌面使用grabWindow()截屏刷刷的,很好使的。但是在android下使用还要处理下。 所以Qt在android截...

QML关于控件截图

在写qml程序的时候,遇到了需要截图的功能, 下面来看看怎么获取控件的截图 首先,所有的可视控件其实都继承了QQuickItem这个类的 所以所有控件都有截图的功能,当然这个只能在c++里实现 ...

qml截图方法二

Rectangle{ width: 200 height: 200 color:"red" id:sou...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Qt实现桌面截屏

实现桌面截屏,软件如下: 图1 桌面截屏 主要介绍一个方法grabWindow(WId window, int x = 0, int y = 0, int width = -1, int he...

Qt中截图功能的实现

提要需求:加载一张图片并显示,可以放大缩小,可以截取图片的某个矩形并保存。原以为蛮简单的一个功能,其实还是有点小复杂。最简单Qt图片浏览器可以参考Qt自带的Demo:Image Viewer Exam...

Qt浅谈之十三:抓图截屏

一、简介        简介 二、运行图 (1)如下图1所示。 三、详解 1、开始 (1)开始 四、总结 (1)本博文只发布部分源码,读者可根据思路来进行定...

QT做类似QQ截图功能(带图片编辑功能)

这里采用的方法是按下截屏按钮截取整个桌面,然后通过鼠标的拖动选中截取的区域,并把这个区域用截取的那张大图中相应的位置设置为QLabel背景,其他的保存或者完成等操作通过按钮的响应来完成。值得说的就是这...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Qt浅谈之十三:抓图截屏
举报原因:
原因补充:

(最多只允许输入30个字)