最近发现好多次打开QQ仅仅想用它来截屏 ⊙﹏⊙b汗

不如自己来写一个截屏工具,集成到自己的小工具箱里面

动手之前考虑一下要怎么实现,我考虑过的方案大概有下面两种  :

1. 监控全局鼠标事件 (真是“初生牛犊不怕虎“    ~~o(>_<)o ~~  )。

2. 将窗口设置为屏幕大小(去掉标题栏),设置窗口背景透明(这个时候窗口不就是我们的屏幕了么哈哈),然后用mouseEvent来获取鼠标事件(连全局鼠标监控都省了)。

最终栽在了背景透明的实现上。(透明后窗口是黑的)

最后受到第二种方法启发,想到一种简单的方法:先截取全屏,将窗口设置为屏幕大小(去掉标题栏),将窗口背景设置为刚才截取的图片,然后在上面用用mouseEvent来获取鼠标事件,完成截屏。

头文件 SreenShoot.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#ifndef SCREENSHOOT_H
#define SCREENSHOOT_H
 
#include <QWidget>
#include <QRubberBand> // 用于创建一个橡皮筋选框
#include <QLabel> // 动态显示截图区域尺寸
#include <QDateTime> // 用当前系统时间动态生成截图的文件名
#include <QScreen> // 用来截取全屏
#include <QDesktopWidget> // 用于获取屏幕尺寸
#include <QApplication>
#include <QPalette> // 对话框的调色板,用于将图片设置为窗体背景
#include <QMouseEvent> // 重载用于获取鼠标事件
#include <QString> // 配合上面的<QDateTime> 用于存储文件名
#include <windows.h> // 调用win32API
#include <QImage> // 用于储存图片对象
#include <QDir> // 用于获取当前程序目录,得到截图的路径
#include <QDesktopServices> //配合 <QDir> 用系统浏览器打开图片
#include <QFile> // 删除文件
 
class ScreenShoot : public QWidget
{
Q_OBJECT
 
public:
 
static ScreenShoot* Instance()
{
if(!instance)
instance = new ScreenShoot();
return instance;
}
 
 
void mouseMoveEvent(QMouseEvent *e); // 处理鼠标移动
void mousePressEvent(QMouseEvent *e); // 处理鼠标按下
void mouseReleaseEvent(QMouseEvent *e); // 处理鼠标释放
void setbackground(int width,int height); // 初始化程序背景
void grabScreen(); // 根据选取截屏,保存并打开图片
void setLabel(); // 动态显示截图区域尺寸
void keyPressEvent(QKeyEvent *e); // 处理esc取消按键
~ScreenShoot();
void show(); // 重写 show() 每次显示都重新渲染窗体背景 单例需要
private:
QRubberBand* g_rubber;
QPoint origin; // 记录鼠标按下坐标
QPoint end; // 记录鼠标释放坐标
QLabel* label; // 显示截图区域尺寸
QImage* bg; // 记录全屏图片
int g_width; // 屏幕宽度
int g_height; // 屏幕高度
static ScreenShoot* instance;
ScreenShoot();
};
 
#endif // SCREENSHOOT_H
来自CODE的代码片
ScreenShoot.h

源文件 SreenShoot.cpp 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include <ScreenShoot.h>
ScreenShoot* ScreenShoot::instance = 0;
ScreenShoot::ScreenShoot()
{
// 获取屏幕尺寸
QDesktopWidget* desktopWidget = QApplication::desktop();
QRect deskRect = desktopWidget->screenGeometry();
// 将窗体设置为屏幕尺寸,去掉标题栏
g_width = deskRect.width();
g_height = deskRect.height();
this ->resize(g_width,g_height);
 
// 调用setbackground() 设置背景
setbackground(deskRect.width(),deskRect.height());
 
//初始化变量
g_rubber = NULL;
 
origin = end = QPoint(0,0);
//截图标签
label = new QLabel("");
label->setWindowFlags(Qt::FramelessWindowHint);
this ->setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);
 
}
ScreenShoot::~ScreenShoot()
{
 
}
void ScreenShoot::mousePressEvent(QMouseEvent *e)
{
if(!g_rubber)
{
g_rubber = new QRubberBand(QRubberBand::Rectangle,this);
}
// 将橡皮框设置可见
g_rubber->show();
// 记录点击位置
origin = e->pos();
// 设置橡皮框选区
g_rubber->setGeometry(origin.x(),origin.y(),0,0);
 
}
void ScreenShoot::mouseMoveEvent(QMouseEvent *e)
{
if(g_rubber)
{
// 记录终点
end = e->pos();
 
//调整要显示的区域
int w = abs(end.x() - origin.x());
int h = abs(end.y() - origin.y());
int x = origin.x() < end.x() ? origin.x() : end.x();
int y = origin.y() < end.y() ? origin.y() : end.y();
 
g_rubber->setGeometry(x,y,w,h);
// 动态显示选区大小
setLabel();
}
}
void ScreenShoot::mouseReleaseEvent(QMouseEvent *e)
{
if(g_rubber)
{
// 记录终点
end = e ->pos();
g_rubber->hide();
// 截屏
grabScreen();
// 截屏后关闭程序和标签栏
label->close();
 
// 如果使用close(),当主窗口隐藏时,主窗口也会close(),如果你需要将他作为一个模块,使用hide而不是close
this ->close();
 
 
}
}
void ScreenShoot::grabScreen()
{
// 调整要截取的区域
int wid = abs(origin.x() - end.x());
int height = abs(origin.y() - end.y());
int x = origin.x() < end.x() ? origin.x() : end.x();
int y = origin.y() < end.y() ? origin.y() : end.y();
 
//构造文件名
QDateTime time = QDateTime::currentDateTime();
QString str = time.toString("yyyyMMddhhmmss");
QString picName = str + ".bmp";
 
// 对全屏背景进行截图
QImage pic = bg->copy(x,y,wid,height);
pic.save(picName);
 
// 获取程序当前路径,打片截图
QString path;
QDir dir;
path=dir.currentPath();
QString picPath = "file:///" + path + "/" + picName;
QDesktopServices::openUrl(QUrl(picPath));
 
//删除背景图
QFile::remove("bg.bmp");
 
}
void ScreenShoot::setLabel()
{
// 调整标签显示位置
int wid = abs(origin.x() - end.x());
int height = abs(origin.y() - end.y());
int x = origin.x() < end.x() ? origin.x() : end.x();
int y = origin.y() < end.y() ? origin.y() : end.y();
 
// 设置标签显示内容
QString str = QString(" %1 x %2 ").arg(wid).arg(height);
label->setText(str);
// 设置标签位置
QRect rect(label->contentsRect());
label->move(QPoint(x,y - rect.height()));
label->show();
 
}
void ScreenShoot::keyPressEvent(QKeyEvent *e)
{
// 如果按下ESC键,关闭程序
if(e->key() == Qt::Key_Escape)
{
label->close();
// 如果使用close(),当主窗口隐藏时,主窗口也会close(),如果你需要将他作为一个模块,使用hide而不是close
this ->close();
QFile::remove("bg.bmp");
}
 
}
void ScreenShoot::setbackground(int width,int height)
{
//截取当前屏幕
QScreen *screen = QGuiApplication::primaryScreen();
screen->grabWindow(0).save("bg.bmp","bmp");
 
//读取背景图,等比例缩放RGB值,使背景变暗,进入截图模式
int red,green,blue;
 
bg = new QImage("bg.bmp");
QImage bg_blend(width,height,QImage::Format_RGB32);
for(int x = 0; x < width; x++)
{
for(int y = 0; y < height; y++)
{
red = qRed(bg->pixel(x,y)) * 0.6 ;
green = qGreen(bg->pixel(x,y)) * 0.6;
blue = qBlue(bg->pixel(x,y)) * 0.6;
bg_blend.setPixel( x, y, qRgb( red, green, blue ) );
}
}
// 将图片设置为背景
 
QPalette palette;
palette.setBrush(this->backgroundRole(),QBrush(bg_blend));
this->setPalette(palette);
 
}
void ScreenShoot::show()
{
QWidget::show();
setbackground(g_width,g_height);
}
来自CODE的代码片
ScreenShoot.cpp
 main函数   
1
2
3
4
5
6
7
8
9
10
11
#include "mainwindow.h"
#include <QApplication>
#include <ScreenShoot.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ScreenShoot* instance = ScreenShoot::Instance();
instance->show();
 
return a.exec();
}
来自CODE的代码片
http://blog.csdn.net/milujun/article/details/22595531

Qt写一个截屏工具(窗口透明)的更多相关文章

  1. Java开发的一个简单截屏工具

    //源代码 import java.awt.*;import java.awt.datatransfer.DataFlavor;import java.awt.datatransfer.Transfe ...

  2. Gif截屏工具 - GifCam

    如果你需要录制截屏并保存成gif图片格式,那么你一定不能错过GifCam这个神奇的小工具.它虽然只有600K,但功能不可小觑. GifCam (Gif相机) 是一款免费且非常优秀的视频录制/剪辑的GI ...

  3. 截屏工具 HyperSnap

    听说Tencent开发了1款截屏工具,叫"snip".确实字体效果不错,但是丫只有for mac的,不知道脑子里怎么想的,该不是直接买了第三方的然后冠了个名儿吧. 那么Windows有没有类似的工具呢 ...

  4. Java 截屏工具类

    PrintScreenUtils.java package javax.utils; import java.awt.AWTException; import java.awt.Dimension; ...

  5. 用 nodejs 写一个命令行工具 :创建 react 组件的命令行工具

    用 nodejs 写一个命令行工具 :创建 react 组件的命令行工具 前言 上周,同事抱怨说 react 怎么不能像 angular 那样,使用命令行工具来生成一个组件.对呀,平时工作时,想要创建 ...

  6. Linux截屏工具scrot用法详细介绍

    Scrot是Linux命令行中使用的截图工具,能够进行全屏.选取等操作,下面小编将针对Scrot截图工具的用法给大家做个详细介绍,通过操作实例来学习Scrot的使用.   在Linux中安装Scrot ...

  7. Qt编程—去掉标题栏和设置窗口透明用法

    学习Qt编程,有时候我们很想做出好看又比较炫的画面,这时就常用到qt上的一些技巧. 这里我以一个小例子来展示qt的这些技巧,此qt编程写的,如图:(去掉标题栏和设置窗口透明后) 代码实现部分: .h文 ...

  8. Snipaste多截屏工具软件

    Snipaste是一个简单的截图小工具,可以支持同时截取多张图片,添加标注等等,操作简单方便,解压即用 百度网盘链接: https://pan.baidu.com/s/1YC75DRoLzdeyli1 ...

  9. 动手写一个Remoting接口测试工具(附源码下载)

    基于.NET开发分布式系统,经常用到Remoting技术.在测试驱动开发流行的今天,如果针对分布式系统中的每个Remoting接口的每个方法都要写详细的测试脚本,无疑非常浪费时间.所以,我想写一个能自 ...

随机推荐

  1. js 中的bind函数

    bind是Function.prototype中内置函数 作用是指定函数作用域 代码参考 http://blog.csdn.net/load_life/article/details/7200381 ...

  2. include file和include virtual的区别

    1.#include file 包含文件的相对路径,#include virtual包含文件的虚拟路径. 2.在同一个虚拟目录内,<!--#include file="file.asp ...

  3. delphi 编译生成ipa文件

    找IPA文件 开发模式ipa文件和发布模式ipa文件,路径不同. http://www.itnose.net/detail/6101808.html 一.开发模式Development 不需要真机,可 ...

  4. jQuery tmpl index

    <!-- 校验失败后显示 TODO--> <script id="checkError_table_tmpl" type="text/x-handleb ...

  5. DBV-00111: OCI failure (3722) (ORA-01002: fetch out of sequence解决

    在使用DBV检测segment的时候出现 DBV-00111: OCI failure (3722) (ORA-01002: fetch out of sequence)错误: 在寻找原因过程中发现相 ...

  6. SqlServer之like、charindex、patindex(转载)

    SqlServer之like.charindex.patindex   1.环境介绍 测试环境 SQL2005 测试数据 200W条   2.环境准备 2.1建表 CREATE TABLE [dbo] ...

  7. iPhone 真机调试应用程序

    原文:http://blog.sina.com.cn/s/blog_68e753f70100r3w5.html 真机调试iphone应用程序 1.真机调试流程概述 1)       真机调试应用程序, ...

  8. c#程序添加其他网站的webservice引用。

    前言: 有A网站,B网站两个网站独立运行.某一天,需要两个网站进行合作来完成一件事,比如用A网站接收一些数据进行处理,存入中转数据库,B网站定时去取数据进入自己的系统进行处理. 可能我们会先想到在B网 ...

  9. spring和mybatis整合进行事务管理

    1.声明式实现事务管理 XML命名空间定义,定义用于事务支持的tx命名空间和AOP支持的aop命名空间: <beans xmlns="http://www.springframewor ...

  10. 转:FileReader详解与实例---读取并显示图像文件

    ~~~针对需要读取本地图像,并立即显示在浏览器的情况,由于chrome firefox出于安全限制,input file并不返回文件的真实路径,经测试IE6/7/8都会返回真实路径,所以chrome, ...