Qt写一个截屏工具(窗口透明)
最近发现好多次打开QQ仅仅想用它来截屏 ⊙﹏⊙b汗
不如自己来写一个截屏工具,集成到自己的小工具箱里面
动手之前考虑一下要怎么实现,我考虑过的方案大概有下面两种 :
1. 监控全局鼠标事件 (真是“初生牛犊不怕虎“ ~~o(>_<)o ~~ )。
2. 将窗口设置为屏幕大小(去掉标题栏),设置窗口背景透明(这个时候窗口不就是我们的屏幕了么哈哈),然后用mouseEvent来获取鼠标事件(连全局鼠标监控都省了)。
最终栽在了背景透明的实现上。(透明后窗口是黑的)
最后受到第二种方法启发,想到一种简单的方法:先截取全屏,将窗口设置为屏幕大小(去掉标题栏),将窗口背景设置为刚才截取的图片,然后在上面用用mouseEvent来获取鼠标事件,完成截屏。
头文件 SreenShoot.h
1 |
#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的代码片
源文件 SreenShoot.cpp
1 |
#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的代码片
Qt写一个截屏工具(窗口透明)的更多相关文章
- Java开发的一个简单截屏工具
//源代码 import java.awt.*;import java.awt.datatransfer.DataFlavor;import java.awt.datatransfer.Transfe ...
- Gif截屏工具 - GifCam
如果你需要录制截屏并保存成gif图片格式,那么你一定不能错过GifCam这个神奇的小工具.它虽然只有600K,但功能不可小觑. GifCam (Gif相机) 是一款免费且非常优秀的视频录制/剪辑的GI ...
- 截屏工具 HyperSnap
听说Tencent开发了1款截屏工具,叫"snip".确实字体效果不错,但是丫只有for mac的,不知道脑子里怎么想的,该不是直接买了第三方的然后冠了个名儿吧. 那么Windows有没有类似的工具呢 ...
- Java 截屏工具类
PrintScreenUtils.java package javax.utils; import java.awt.AWTException; import java.awt.Dimension; ...
- 用 nodejs 写一个命令行工具 :创建 react 组件的命令行工具
用 nodejs 写一个命令行工具 :创建 react 组件的命令行工具 前言 上周,同事抱怨说 react 怎么不能像 angular 那样,使用命令行工具来生成一个组件.对呀,平时工作时,想要创建 ...
- Linux截屏工具scrot用法详细介绍
Scrot是Linux命令行中使用的截图工具,能够进行全屏.选取等操作,下面小编将针对Scrot截图工具的用法给大家做个详细介绍,通过操作实例来学习Scrot的使用. 在Linux中安装Scrot ...
- Qt编程—去掉标题栏和设置窗口透明用法
学习Qt编程,有时候我们很想做出好看又比较炫的画面,这时就常用到qt上的一些技巧. 这里我以一个小例子来展示qt的这些技巧,此qt编程写的,如图:(去掉标题栏和设置窗口透明后) 代码实现部分: .h文 ...
- Snipaste多截屏工具软件
Snipaste是一个简单的截图小工具,可以支持同时截取多张图片,添加标注等等,操作简单方便,解压即用 百度网盘链接: https://pan.baidu.com/s/1YC75DRoLzdeyli1 ...
- 动手写一个Remoting接口测试工具(附源码下载)
基于.NET开发分布式系统,经常用到Remoting技术.在测试驱动开发流行的今天,如果针对分布式系统中的每个Remoting接口的每个方法都要写详细的测试脚本,无疑非常浪费时间.所以,我想写一个能自 ...
随机推荐
- ASP.Net MVC3 - The easier to run Unit Tests by moq #Reprinted#
From: http://www.cnblogs.com/techborther/archive/2012/01/10/2317998.html 前几天调查完了unity.现在给我的任务是让我调查Mo ...
- 高质量程序设计指南C/C++语言——有了malloc/free为什么还要new/delete?
- 修改LVDS支持1024*600分辨率
一.在boot中增加LVDS设置分辨率1024*600选项 1.修改文件TQIMX6_android-4.2.2\bootable\bootloader\uboot-imx\common\cmd_me ...
- Oracle 11g透明网关连接Sqlserver 2000
一.环境 公司网站系统使用的是IIS + Oracle 但公司某系统使用的是Sqlserver 2000, 但其数据需要做成报表放到网站上,为简化编程,使用Oracle做透明网关,定期从Sqlserv ...
- Protel99SE制作拼板的方法
制作步骤: 1.在PCB编辑里按快捷键 S/A全选复制源PCB全部内容,再按Ctrl+C看到十字光标.点击左键. 2.打开目标PCB文件,点击Edit菜单,在下拉菜单中点击Paste special( ...
- 阻止系统自动睡眠的小软件,附C#制作过程
原文 http://www.cnblogs.com/h46incon/p/SleepPreventer.html 因为有时下载东西的时候,不想让电脑自动深入睡眠,所以就开启了离开模式.这样不但不节能环 ...
- c#读写共享内存操作函数封装
原文 c#读写共享内存操作函数封装 c#共享内存操作相对c++共享内存操作来说原理是一样,但是c#会显得有点复杂. 现把昨天封装的读写共享内存封装的函数记录下来,一方面希望给需要这块的有点帮助,另一方 ...
- hql中不能写count(1)能够写count(a.id)
hql中不能写count(1)能够写count(a.id)里面写详细的属性 String hql="select new com.haiyisoft.vo.entity.cc.repo.Bu ...
- [LeetCode]题解(python):011-Container With Most Water
题目来源: https://leetcode.com/problems/container-with-most-water/ 题意分析: 给出一个n长度的非0数组,a1,a2,……,an,ai代表在坐 ...
- 2013 南京邀请赛 A play the dice 求概率
/** 大意:给定一个色子,有n个面,每一个面上有一个数字,在其中的m个面上有特殊的颜色,当掷出的色子出现这m个颜色之一时,可以再掷一次..求其最后的期望 思路:假设 期望为ans 4 ans = 1 ...