QT 实现简单截图功能
代码内容完善、有详细的代码注释所以不在赘述。
- 头文件CaptureScreen.h
#ifndef CAPTURESCREEN_H
#define CAPTURESCREEN_H
#include <QWidget>
#include <QPainter>
enum CaptureState{
initCapture,
beginCaptureImage,
finishCaptureImage,
beginMoveCaptureArea,
finishMoveCaptureArea,
}; //进行截屏的状态;
class CaptureScreen : public QWidget
{
Q_OBJECT
public:
CaptureScreen(QWidget *parent = 0);
~CaptureScreen();
Q_SIGNALS:
// 通知截图完毕,并将截取图片传递给调用类;
void signalCompleteCature(QPixmap catureImage);
private:
void initWindow();
void loadBackgroundPixmap();
QRect getRect(const QPoint &beginPoint, const QPoint &endPoint);
QRect getMoveRect();
bool isPressPointInSelectRect(QPoint mousePressPoint);
QRect getSelectRect();
void drawCaptureImage();
QPoint getMovePoint();
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
void paintEvent(QPaintEvent *event);
private:
QPixmap m_loadPixmap, m_capturePixmap;
int m_screenwidth;
int m_screenheight;
// 保存确定选区的坐标点;
QPoint m_beginPoint, m_endPoint , m_beginMovePoint , m_endMovePoint;
QPainter m_painter;
// 保存当前截图状态;
CaptureState m_currentCaptureState;
// 当前选择区域矩形;
QRect m_currentSelectRect;
};
#endif // CAPTURESCREEN_H
- 源文件 CaptureScreen.cpp
#include "capturescreen.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QMouseEvent>
CaptureScreen::CaptureScreen(QWidget *parent)
: QWidget(parent)
, m_currentCaptureState(initCapture)
{
initWindow();
loadBackgroundPixmap();
}
CaptureScreen::~CaptureScreen()
{
}
void CaptureScreen::initWindow()
{
this->setMouseTracking(true);
// 由于存在类似QQ这样界面始终显示在最顶层,设置属性 Qt::WindowStaysOnTopHint;
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
setWindowState(Qt::WindowActive | Qt::WindowFullScreen);
this->setMouseTracking(true);
}
void CaptureScreen::loadBackgroundPixmap()
{
m_loadPixmap = QPixmap::grabWindow(QApplication::desktop()->winId()); //抓取当前屏幕的图片;
m_screenwidth = m_loadPixmap.width();
m_screenheight = m_loadPixmap.height();
}
void CaptureScreen::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton && m_currentCaptureState == initCapture)
{
m_currentCaptureState = beginCaptureImage;
m_beginPoint = event->pos();
}
else if (event->button() == Qt::LeftButton && isPressPointInSelectRect(event->pos()))
{
m_currentCaptureState = beginMoveCaptureArea;
setCursor(Qt::SizeAllCursor);
m_beginMovePoint = event->pos();
}
return QWidget::mousePressEvent(event);
}
void CaptureScreen::mouseMoveEvent(QMouseEvent* event)
{
if (m_currentCaptureState == beginCaptureImage)
{
m_endPoint = event->pos();
update();
}
else if (m_currentCaptureState == beginMoveCaptureArea)
{
m_endMovePoint = event->pos();
update();
}
// 根据鼠标是否在选中区域内设置鼠标样式;
if (isPressPointInSelectRect(event->pos()))
{
setCursor(Qt::SizeAllCursor);
}
else if (!isPressPointInSelectRect(event->pos()) && m_currentCaptureState != beginMoveCaptureArea)
{
setCursor(Qt::ArrowCursor);
}
return QWidget::mouseMoveEvent(event);
}
void CaptureScreen::mouseReleaseEvent(QMouseEvent *event)
{
if (m_currentCaptureState == beginCaptureImage)
{
m_currentCaptureState = finishCaptureImage;
m_endPoint = event->pos();
update();
}
else if (m_currentCaptureState == beginMoveCaptureArea)
{
m_currentCaptureState = finishMoveCaptureArea;
m_endMovePoint = event->pos();
update();
}
return QWidget::mouseReleaseEvent(event);
}
// 当前鼠标坐标是否在选取的矩形区域内;
bool CaptureScreen::isPressPointInSelectRect(QPoint mousePressPoint)
{
QRect selectRect = getRect(m_beginPoint, m_endPoint);
if (selectRect.contains(mousePressPoint))
{
return true;
}
return false;
}
void CaptureScreen::paintEvent(QPaintEvent *event)
{
m_painter.begin(this); //进行重绘;
QColor shadowColor = QColor(0, 0, 0, 100); //阴影颜色设置;
m_painter.setPen(QPen(Qt::blue, 1, Qt::SolidLine, Qt::FlatCap)); //设置画笔;
m_painter.drawPixmap(0, 0, m_loadPixmap); //将背景图片画到窗体上;
m_painter.fillRect(m_loadPixmap.rect(), shadowColor); //画影罩效果;
switch (m_currentCaptureState)
{
case initCapture:
break;
case beginCaptureImage:
case finishCaptureImage:
case beginMoveCaptureArea:
case finishMoveCaptureArea:
m_currentSelectRect = getSelectRect();
drawCaptureImage();
default:
break;
}
m_painter.end(); //重绘结束;
}
// 根据当前截取状态获取当前选中的截图区域;
QRect CaptureScreen::getSelectRect()
{
if (m_currentCaptureState == beginCaptureImage || m_currentCaptureState == finishCaptureImage)
{
return getRect(m_beginPoint, m_endPoint);
}
else if (m_currentCaptureState == beginMoveCaptureArea || m_currentCaptureState == finishMoveCaptureArea)
{
return getMoveRect();
}
return QRect(0, 0, 0, 0);
}
// 绘制当前选中的截图区域;
void CaptureScreen::drawCaptureImage()
{
m_capturePixmap = m_loadPixmap.copy(m_currentSelectRect);
m_painter.drawPixmap(m_currentSelectRect.topLeft(), m_capturePixmap);
m_painter.drawRect(m_currentSelectRect);
}
void CaptureScreen::keyPressEvent(QKeyEvent *event)
{
// Esc 键退出截图;
if (event->key() == Qt::Key_Escape)
{
close();
}
// Eeter键完成截图;
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
{
signalCompleteCature(m_capturePixmap);
close();
}
}
// 根据beginPoint , endPoint 获取当前选中的矩形
QRect CaptureScreen::getRect(const QPoint &beginPoint, const QPoint &endPoint)
{
int x, y, width, height;
width = qAbs(beginPoint.x() - endPoint.x());
height = qAbs(beginPoint.y() - endPoint.y());
x = beginPoint.x() < endPoint.x() ? beginPoint.x() : endPoint.x();
y = beginPoint.y() < endPoint.y() ? beginPoint.y() : endPoint.y();
QRect selectedRect = QRect(x, y, width, height);
// 避免宽或高为零时拷贝截图有误;
// 可以看QQ截图,当选取截图宽或高为零时默认为2;
if (selectedRect.width() == 0)
{
selectedRect.setWidth(1);
}
if (selectedRect.height() == 0)
{
selectedRect.setHeight(1);
}
return selectedRect;
}
// 获取移动后,当前选中的矩形;
QRect CaptureScreen::getMoveRect()
{
// 通过getMovePoint方法先检查当前是否移动超出屏幕;
QPoint movePoint = getMovePoint();
QPoint beginPoint = m_beginPoint + movePoint;
QPoint endPoint = m_endPoint + movePoint;
// 结束移动选区时更新当前m_beginPoint , m_endPoint,防止下一次操作时截取的图片有问题;
if (m_currentCaptureState == finishMoveCaptureArea)
{
m_beginPoint = beginPoint;
m_endPoint = endPoint;
m_beginMovePoint = QPoint(0, 0);
m_endMovePoint = QPoint(0, 0);
}
return getRect(beginPoint, endPoint);
}
QPoint CaptureScreen::getMovePoint()
{
QPoint movePoint = m_endMovePoint - m_beginMovePoint;
QRect currentRect = getRect(m_beginPoint, m_endPoint);
// 检查当前是否移动超出屏幕;
//移动选区是否超出屏幕左边界;
if (currentRect.topLeft().x() + movePoint.x() < 0)
{
movePoint.setX(0 - currentRect.topLeft().x());
}
//移动选区是否超出屏幕上边界;
if (currentRect.topLeft().y() + movePoint.y() < 0)
{
movePoint.setY(0 - currentRect.topLeft().y());
}
//移动选区是否超出屏幕右边界;
if (currentRect.bottomRight().x() + movePoint.x() > m_screenwidth)
{
movePoint.setX(m_screenwidth - currentRect.bottomRight().x());
}
//移动选区是否超出屏幕下边界;
if (currentRect.bottomRight().y() + movePoint.y() > m_screenheight)
{
movePoint.setY(m_screenheight - currentRect.bottomRight().y());
}
return movePoint;
}