最近发现好多次打开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. Primavera 6.0

    Primavera 6.0(原p3e/c)荟萃了P3软件20年的项目管理精髓和经验,采用最新的IT技术,在大型关系数据库Oracle和MS SQL Server上构架起企业级的.包涵现代项目管理知识体 ...

  2. Tomcat embed

    http://www.iflym.com/index.php/code/use-embeded-tomcat-to-javaee-start-tomcat.html http://java.dzone ...

  3. 在TreeWidget中增加右键菜单功能 以及TreeWidget的基本用法

    TreeWidget 与 TreeView 中实现右键菜单稍有不同, TreeView 中是靠信号与槽 connect(ui->treeView,SIGNAL(customContextMenu ...

  4. C++ 用libcurl库进行http 网络通讯编程

      一.LibCurl基本编程框架libcurl是一个跨平台的网络协议库,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议.libcur ...

  5. hpu校赛--雪人的高度(离散化线段树)

    1721: 感恩节KK专场——雪人的高度 时间限制: 1 Sec  内存限制: 128 MB 提交: 81  解决: 35 [提交][状态][讨论版] 题目描述 大雪过后,KK决定在春秋大道的某些区间 ...

  6. js动画学习(一)

    一.运动框架实现思路 1.匀速运动(属性值匀速变化)(改变 left, right, width, height, opacity 等): 2.缓冲运动(属性值的变化速度与当前值与目标值的差成正比): ...

  7. MySQL的字段设计

    1.尽量使用数字,因为文本占空间,不利于查询(针对有限种类文本)

  8. Tableau Server 8.0 升级到 8.3 过程记录

    一.使用账号(管理员权限),安装文件复制到服务器 二.检查维护状态 如果维护状态过期,更新到新版本会变成未授权. 先进Manage Product Keys刷新一下维护日期(其实不刷新也无所谓.到时候 ...

  9. BZOJ 1567: [JSOI2008]Blue Mary的战役地图( 二分答案 + hash )

    二分答案, 然后用哈希去判断... ------------------------------------------------------------------------- #include ...

  10. linux下出现java.net.UnknownHostException

    项目部署在win环境下没问题,但是在迁移生产环境的时候出现Java.net.UnknowHostException 原因在于etc/hosts 文件没有配置域名映射,使用vi编辑器加上服务器ip 以及 ...