用Qt写一个截屏工具

最近发现好多次打开QQ仅仅想用它来截屏 ⊙﹏⊙b汗

不如自己来写一个截屏工具,集成到自己的小工具箱里面

动手之前考虑一下要怎么实现,我考虑过的方案大概有下面两种  :

1. 监控全局鼠标事件 (真是“初生牛犊不怕虎“    ~~o(>_<)o ~~  )。

2. 将窗口设置为屏幕大小(去掉标题栏),设置窗口背景透明(这个时候窗口不就是我们的屏幕了么哈哈),然后用mouseEvent来获取鼠标事件(连全局鼠标监控都省了)。

 最终栽在了背景透明的实现上。(透明后窗口是黑的)

最后受到第二种方法启发,想到一种简单的方法:先截取全屏,将窗口设置为屏幕大小(去掉标题栏),将窗口背景设置为刚才截取的图片,然后在上面用用mouseEvent来获取鼠标事件,完成截屏。

 

头文件 SreenShoot.h

#ifndef SCREENSHOOT_H
#define SCREENSHOOT_H

#include 
#include     // 用于创建一个橡皮筋选框
#include          // 动态显示截图区域尺寸
#include       // 用当前系统时间动态生成截图的文件名
#include         // 用来截取全屏
#include  // 用于获取屏幕尺寸
#include 
#include        // 对话框的调色板,用于将图片设置为窗体背景
#include     // 重载用于获取鼠标事件
#include         // 配合上面的 用于存储文件名
#include       // 调用win32API
#include          // 用于储存图片对象
#include            // 用于获取当前程序目录,得到截图的路径
#include   //配合   用系统浏览器打开图片
#include            // 删除文件

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



源文件 SreenShoot.cpp 

#include 
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);
}


 main函数   
#include "mainwindow.h"
#include 
#include 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    ScreenShoot* instance = ScreenShoot::Instance();
    instance->show();

    return a.exec();
}


效果图

用Qt写一个截屏工具_第1张图片


完整例子下载

你可能感兴趣的:(QT)