• Qt写一个截屏工具(窗口透明)


    最近发现好多次打开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
  • 相关阅读:
    计算机基础知识
    测试用例设计
    Windows MySql增量备份、完整备份采坑之路
    GOF 的23种JAVA常用设计模式总结 02 UML中的类图与类图之间的关系
    GOF 的23种JAVA常用设计模式总结 01 设计模式的概念分类和功能
    Springboot 整合ApachShiro完成登录验证和权限管理
    玩转Spring全家桶笔记 04 Spring的事务抽象、事务传播特性、编程式事务、申明式事务
    玩转Spring全家桶笔记 03 Spring的JDBC操作以及SQL批处理的实现
    玩转Spring全家桶笔记 02 那些好用的连接池HikariCP
    Springboot token令牌验证解决方案 在SpringBoot实现基于Token的用户身份验证
  • 原文地址:https://www.cnblogs.com/findumars/p/5138194.html
Copyright © 2020-2023  润新知