因为本人今天还有事,时间不多,就不细说了,介绍一下程序的实现思路,在贴出代码,供大家参考。
首先,该截图程序的实现主要有一个难点,就是如何实现自定义截图,所谓“自定义”就是由用户确定截图的范围,譬如一个窗口或是一个区域。
可能很多朋友想到的都是使用橡皮筋类,来确定截图范围。但是,在此介绍另一种方法,那就是通过响应鼠标的按下、移动和释放在屏幕范围内绘图,进而确定截图的范围。
实现时有一个问题,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();
}
}
截图源代码: