最近发现好多次打开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. IOS本地化。

    1,项目名本地化 点击项目,蓝色图标->info 最下面+号,添加chinese本地化. Supporting Files->infoPlist.strings 下会有两个文件,有一个是设 ...

  2. android application 的使用

    参考http://oyeal.iteye.com/blog/941183 由于intent能够传送的对象类型非常有限  因此有些很多类都要用到的变量我们放在Application中  很像web中的s ...

  3. .net mvc RazorEngine 字符串razor参数替换

    在.net中有一个比较好的字符串参数替换的方案RazorEngine推荐大家看看原网站,然后做个小联系然后你就懂啦 首先呢得下载一个吧, vs中tools-> Library Paging Ma ...

  4. 别忘记给你博客的windows live writer配置 ping服务

    写好一篇博客,想要实现秒收.就必须要为文章添加ping服务. 这里介绍一下给wlw添加ping服务的办法. 点击工具---选项--ping服务器. 在右侧栏中加入以下地址 http://rpc.pin ...

  5. 64位linux下安装oracle10 64位 遇到 :ins_ctx.mk ;ins_emdb.mk

    http://blog.csdn.net/bamuta/article/details/10523835 http://www.cnblogs.com/kerrycode/p/3519446.html ...

  6. Windows 8.1 IIS 8.5 远程管理 Windows 2008 R2 IIS 7.0

    案例: Windows 8.1 x64 IIS 8.5 inetmgr_amd64_v1.1_en-US.msi Windows 2008 R2  x64 IIS  7.0 在Win8.1 通过IIS ...

  7. zookeeper 数据存储特点

    zookeeper 和elasticseaarch 数据存储特点: 1.zookeeper; [Zookeeper提供的一致性是弱一致性,首先数据的复制有如下规则:zookeeper确保对znode树 ...

  8. Pascal向C++的跨越

    最近从pas转向了C++,觉得需要在语言上总结对比一下,以及记录一些注意点,关于STL,还需要之后好好地学习.同时,希望这篇文章对从pas转C++的同学有所帮助. 基本类型 首先是基本类型的比较: P ...

  9. debian安装vld来查看Opcode,PHP调优。

    一: 我的环境: Debian 7 (wheezy)  x64 PHP 5.4.4-14 (apt-get 而来) Apache/2.2.22 (同上,非源码编译) 二 :安装vld. (# 代表是r ...

  10. ajax 基础

    <html><head><script type="text/javascript">function showHint(str){var xm ...