Qt写一个截屏工具(窗口透明)
2016-01-18 03:43
519 查看
最近发现好多次打开QQ仅仅想用它来截屏 ⊙﹏⊙b汗
不如自己来写一个截屏工具,集成到自己的小工具箱里面
动手之前考虑一下要怎么实现,我考虑过的方案大概有下面两种 :
1. 监控全局鼠标事件 (真是“初生牛犊不怕虎“ ~~o(>_<)o ~~ )。
2. 将窗口设置为屏幕大小(去掉标题栏),设置窗口背景透明(这个时候窗口不就是我们的屏幕了么哈哈),然后用mouseEvent来获取鼠标事件(连全局鼠标监控都省了)。
最终栽在了背景透明的实现上。(透明后窗口是黑的)
最后受到第二种方法启发,想到一种简单的方法:先截取全屏,将窗口设置为屏幕大小(去掉标题栏),将窗口背景设置为刚才截取的图片,然后在上面用用mouseEvent来获取鼠标事件,完成截屏。
头文件 SreenShoot.h
来自CODE的代码片
ScreenShoot.h
源文件 SreenShoot.cpp
来自CODE的代码片
ScreenShoot.cpp
main函数
来自CODE的代码片 http://blog.csdn.net/milujun/article/details/22595531
不如自己来写一个截屏工具,集成到自己的小工具箱里面
动手之前考虑一下要怎么实现,我考虑过的方案大概有下面两种 :
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 |
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); } |
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(); } |
相关文章推荐
- 自学QT之图片操作(缩放、平移、扭曲和旋转等)
- 自学QT之图片报错Paint device returned engine == 0, type: 1
- 关于Qt信号与槽的小结
- 如何在Qt工程中正确地引用用户自定义控件
- QT无边框可移动可改变大小窗体
- Qt5 取消了QTextCodec::setCodecForTr()和QTextCodec::setCodecForCString()这两个函数。
- QT中PRO文件写法
- Qt之JSON生成与解析
- qtchooser
- QT5.5或QT5.6与echarts实现动态图表
- qt发布
- Qt、GTK 和KDE、GNOME的关系-转
- Qt中截图功能的实现
- 通过qss实现Qt按钮的默认效果——qconicalgradient
- Ubuntu安装QT出现权限不够的错误
- Qt 插件综合编程-基于插件的OpenStreetMap瓦片查看器客户端(0)-引子
- qt嵌入式版本源码编译的各种问题
- Qt creater设置成黑色主题
- Qt 和 Boost关于信号和槽的对比说明
- Qt5中使用lambda表达式