Qt学习笔记: 实现截图效果

来源:互联网 发布:nginx https转发http 编辑:程序博客网 时间:2024/06/05 21:02

首先在这里感谢刘大师,提供的源码进行学习。如有冒犯之意,请联系我将其删除,谢谢!这是刘大师的个人主页.

目前跟随刘大师的脚步,学习了一下采用Qt实现截图的效果,具体效果如下:


这里写图片描述

废话不多说,先谈谈这个功能。
首先我们了解一下这个截图:首先,我们是点击“截图工具“,然后弹出灰色的背景,在拖动鼠标进行截图,最后在保存图片。

截屏思想:点击截屏工具的时候,截取全屏的像素,并且将全屏保存到一个全局的变量pixmap中。然后,在点击鼠标移动,截取一个相应的矩形。将其绘制出来。然后在保存。。
那么接下来就可以贴上源码进行解释了:

void frmAPI::on_btnScreenAPI_clicked(){    frmScreen::Instance()->showFullScreen();//显示全屏widget}

这个是点击截图工具以后实现的槽函数。showFllScreen() –> 将widget全屏显示(于是就有了点击以后全屏变灰色)。接着便是调用frmScreen的回调函数

frmScreen::frmScreen(QWidget *parent) : QDialog(parent){    this->initForm();}//初始化框架void frmScreen::initForm(){    this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);//隐藏标题栏,窗体出现在最顶层    menu = new QMenu(this);    menu->addAction("保存截图", this, SLOT(saveScreen()));    menu->addAction("截图另存为", this, SLOT(saveScreenOther()));    menu->addAction("全屏截图", this, SLOT(saveFullScreen()));    menu->addAction("退出截图", this, SLOT(hide()));    //取得屏幕大小    qDebug()<<QApplication::desktop()->size();    screen = new ScreenAPI(QApplication::desktop()->size());    //保存全屏图像    fullScreen = new QPixmap();}

初始化这里先创建了一个对象ScreenAPI。这个对象便是实现屏幕API的一个类。该类定义如下:这是一个纯C++定义的一个类。(没有Q_OBJECT

class ScreenAPI{public:    enum STATUS {SELECT, MOV, SET_W_H};    ScreenAPI() {}    ScreenAPI(QSize size);    void setStart(QPoint pos);//设置开启坐标    void setEnd(QPoint pos);//设置结束坐标    QPoint getStart();    QPoint getEnd();    QPoint getLeftUp();    QPoint getRightDown();    STATUS getStatus();    void setStatus(STATUS status);    int width();    int height();    bool isInArea(QPoint pos);          // 检测pos是否在截图区域内    void move(QPoint p);                // 按 p 移动截图区域private:    QPoint leftUpPos, rightDownPos;     //记录 截图区域 左上角、右下角    QPoint startPos, endPos;            //记录 鼠标开始位置、结束位置    int maxWidth, maxHeight;            //记录屏幕大小    STATUS status;                      //三个状态: 选择区域、移动区域、设置width height    void cmpPoint(QPoint &s, QPoint &e);//比较两位置,判断左上角、右下角};

具体构造函数如下。

ScreenAPI::ScreenAPI(QSize size){    maxWidth = size.width();//获得整个屏幕的大小    maxHeight = size.height();    startPos = QPoint(-1, -1);//开始坐标    endPos = startPos;//结束坐标    leftUpPos = startPos;//左上角坐标    rightDownPos = startPos;//右下角坐标    status = SELECT;}

由于在.h文件中重写了 void showEvent(QShowEvent )事件,因此在显示窗体的时候,会被调用。并且重写了void paintEvent(QPaintEvent );事件重绘函数,因此也会被调用一次。

//显示窗口Widget发出事件被调用void frmScreen::showEvent(QShowEvent *){    QPoint point(-1, -1);    screen->setStart(point);//设置开启坐标点    screen->setEnd(point);//设置结束坐标点    //全屏图像,抓取窗体    *fullScreen = QPixmap::grabWindow(QApplication::desktop()->winId(), 0, 0, screen->width(), screen->height());    //设置透明度实现模糊背景    QPixmap pix(screen->width(), screen->height());    pix.fill((QColor(160, 160, 160, 200)));//模糊颜色填充    bgScreen = new QPixmap(*fullScreen);    QPainter p(bgScreen);    p.drawPixmap(0, 0, pix);}
//重绘事件  update调用void frmScreen::paintEvent(QPaintEvent *){    int x = screen->getLeftUp().x();    int y = screen->getLeftUp().y();    int w = screen->getRightDown().x() - x;//宽度    int h = screen->getRightDown().y() - y;//高度    QPainter painter(this);    QPen pen;    pen.setColor(Qt::green);    pen.setWidth(2);    pen.setStyle(Qt::DotLine);//虚线样式    painter.setPen(pen);    QFont font;    font.setFamily("Microsoft YaHei");    font.setPointSize(10);    painter.setFont(font);    //截屏思想:点击截屏工具的时候,截取全屏的像素,并且将全屏保存到一个全局的变量pixmap中。    //然后,在点击鼠标移动,截取一个相应的矩形。将其绘制出来。    painter.drawPixmap(0, 0, *bgScreen);//    if (w != 0 && h != 0) {        painter.drawPixmap(x, y, fullScreen->copy(x, y, w, h));//绘制选择截屏的区域    }    painter.drawRect(x, y, w, h);//绘制截图矩形    pen.setColor(Qt::yellow);    painter.setPen(pen);    painter.drawText(x + 2, y - 8, tr("截图范围:( %1 x %2 ) - ( %3 x %4 )  图片大小:( %5 x %6 )")                     .arg(x).arg(y).arg(x + w).arg(y + h).arg(w).arg(h));}

接下来便是点击鼠标,移动鼠标,释放鼠标的几个重写事件了。

//鼠标按下事件void frmScreen::mousePressEvent(QMouseEvent *e){    int status = screen->getStatus();//获取状态    if (status == ScreenAPI::SELECT) {        screen->setStart(e->pos());    } else if (status == ScreenAPI::MOV) {        if (screen->isInArea(e->pos()) == false) {            screen->setStart(e->pos());            screen->setStatus(ScreenAPI::SELECT);        } else {            movPos = e->pos();            this->setCursor(Qt::SizeAllCursor);        }    }    update();}//鼠标移动事件void frmScreen::mouseMoveEvent(QMouseEvent *e){    if (screen->getStatus() == ScreenAPI::SELECT) {//选择区域        screen->setEnd(e->pos());//得到结束点坐标    } else if (screen->getStatus() == ScreenAPI::MOV) {//移动区域        QPoint p(e->x() - movPos.x(), e->y() - movPos.y());        screen->move(p);        movPos = e->pos();    }    update();}//鼠标释放事件void frmScreen::mouseReleaseEvent(QMouseEvent *){    if (screen->getStatus() == ScreenAPI::SELECT) {        screen->setStatus(ScreenAPI::MOV);    } else if (screen->getStatus() == ScreenAPI::MOV) {        this->setCursor(Qt::ArrowCursor);    }}

到此,就实现了这个功能。

原创粉丝点击