因为本人今天还有事,时间不多,就不细说了,介绍一下程序的实现思路,在贴出代码,供大家参考。


首先,该截图程序的实现主要有一个难点,就是如何实现自定义截图,所谓“自定义”就是由用户确定截图的范围,譬如一个窗口或是一个区域。


可能很多朋友想到的都是使用橡皮筋类,来确定截图范围。但是,在此介绍另一种方法,那就是通过响应鼠标的按下、移动和释放在屏幕范围内绘图,进而确定截图的范围


实现时有一个问题,qt无法实现在非程序窗口中绘图,即使能捕获鼠标。因为一开始我就是怎么做的,当用户按下自定义截图按钮时,捕获鼠标,这样鼠标的所有操作都能有截图程序接收,然后通过保存鼠标按下和弹起时的屏幕坐标,确定截图范围。这样做能够实现自定义截图,但是用户体验很不好,因为截图区域通常不会是截图程序的窗口,这样在其他窗口截图时无法绘制类似橡皮经类的提示矩形。


所以,为了能够在屏幕范围内绘制矩形,我需要一个载体,而这个载体即是由截图程序创建一个半透明的窗体,这样我可以在这个窗体上绘制图像,并且能够看到窗口后的实际图像。显然这个半透明的窗口应该是无边框、最大化的。并且这个窗口,在用户点击“自定义截图”时显示,在用户绘制完矩形鼠标释放后隐藏。当然,这个过程中会保存鼠标按下和释放时的坐标。窗口隐藏后发送一个信号,至主窗口的保存函数。完成一次自定义截图。


总之,半透明最大化窗口是为了改善用户体验。


下面贴出透明窗口类的代码:

为了防止绘制的矩形重影,采用双缓冲绘图:


#ifndef TRANSPARENTWINDOW_H
#define TRANSPARENTWINDOW_H

#include <QMainWindow>


namespace Ui {
class TransparentWindow;
}

class TransparentWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit TransparentWindow(QWidget *parent = 0);
    ~TransparentWindow();

private:
    Ui::TransparentWindow *ui;

protected:
    // 鼠标按下事件
    void mousePressEvent(QMouseEvent *);
    // 鼠标移动事件
    void mouseMoveEvent(QMouseEvent *);
    // 鼠标弹起事件
    void mouseReleaseEvent(QMouseEvent *);
    // 绘制事件
    void paintEvent(QPaintEvent *);

protected:
    QPixmap pix;
    // 辅助画布
    QPixmap auxiliatyPix;
    QPoint lastPoint;
    QPoint endPoint;
    // 标志是否正在绘图
    bool isDrawing;

signals:
    void WindowClosed();

};

#endif // TRANSPARENTWINDOW_H



#include "transparentwindow.h"
#include "ui_transparentwindow.h"
#include "globalvariable.h"

TransparentWindow::TransparentWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::TransparentWindow)
{
    ui->setupUi(this);

    // 获取屏幕大小
    QDesktopWidget * deskTop = QApplication::desktop();
    QRect screenRect = deskTop->screenGeometry();
    // 指定画布大小
    pix = QPixmap(screenRect.width(), screenRect.height());
    pix.fill(Qt::white);
    // 画图标志
    isDrawing = false;
}

TransparentWindow::~TransparentWindow()
{
    delete ui;
}


// 绘制函数
void TransparentWindow::paintEvent(QPaintEvent *)
{
    if(!isDrawing)
    {
        return;
    }

    int x,y,w,h;
    x = lastPoint.x();
    y = lastPoint.y();
    w = endPoint.x() - x;
    h = endPoint.y() - y;

    QPainter painter(this);

    // 如果鼠标左键未释放,就画在辅助画布上
    if(isDrawing)
    {
        auxiliatyPix = pix;

        QPainter tempPainter(&auxiliatyPix);
        QPen pen;
        pen.setColor(Qt::red);
        pen.setWidth(4);
        tempPainter.setPen(pen);
        tempPainter.drawRect(x,y,w,h);

        tempPainter.setCompositionMode(QPainter::CompositionMode_Clear);
        tempPainter.fillRect(x,y,w,h,Qt::SolidPattern);

        painter.drawPixmap(0,0,auxiliatyPix);
    }
    else
    {
        QPainter tempPainter(&auxiliatyPix);
        QPen pen;
        pen.setColor(Qt::red);
        pen.setWidth(4);
        tempPainter.setPen(pen);
        tempPainter.drawRect(x,y,w,h);

        painter.drawPixmap(0,0,pix);
    }
}

// 鼠标左键按下
void TransparentWindow::mousePressEvent(QMouseEvent *event)
{
    // 鼠标左键按下
    if(event->button() == Qt::LeftButton)
    {
        lastPoint = event->pos();
        // 保存开始坐标
        GlobalVariable::m_startPoint = event->pos();
        // 开始画图
        isDrawing = true;
    }
}

// 鼠标移动
void TransparentWindow::mouseMoveEvent(QMouseEvent *event)
{
    // 鼠标左键按下时移动鼠标
    if(isDrawing)
    {
        endPoint = event->pos();
        // 画图
        update();
    }
}

// 鼠标左键释放
void TransparentWindow::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        endPoint = event->pos();
        // 保存结束坐标
        GlobalVariable::m_endPoint = event->pos();
        // 画图
        update();
        // 停止画图
        isDrawing = false;
        // 关闭窗口
        this->hide();
        // 发送信号
        emit WindowClosed();
    }
}




截图源代码: