QPainter+鼠标事件实现可拖动、可拉伸截屏功能
.h
#include <QWidget>
#include <QPainter>
enum CaptureState{
InitCapture = 0,
BeginCaptureImage,
FinishCaptureImage,
BeginMoveCaptureArea,
FinishMoveCaptureArea,
BeginMoveStretchRect,
FinishMoveStretchRect,
FinishCapture
};
enum StretchRectState{
NotSelect = 0,
TopLeftRect,
TopRightRect,
BottomLeftRect,
BottomRightRect,
LeftCenterRect,
TopCenterRect,
RightCenterRect,
BottomCenterRect
};
class CaptureScreen : public QWidget
{
Q_OBJECT
public:
CaptureScreen(QWidget *parent = 0);
~CaptureScreen();
void widgetInit();
void loadBackgroundPixmap();
QRect getRect(const QPoint &beginPoint, const QPoint &endPoint);
QRect getMoveRect();
QRect getStretchRect();
bool isPressPointInSelectRect(QPoint mousePressPoint);
QRect getSelectRect();
QPoint getMovePoint();
StretchRectState getStrethRectState(QPoint point);
void setStretchCursorStyle(StretchRectState stretchRectState);
void drawCaptureImage();
void drawStretchRect();
protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
void paintEvent(QPaintEvent *event);
signals:
void signalCompleteCature(QPixmap catureImage);
private:
QPainter m_painter;
QPixmap m_loadPixmap;
QPixmap m_capturePixmap;
int m_screenwidth;
int m_screenheight;
QPoint m_beginPoint;
QPoint m_endPoint;
QPoint m_beginMovePoint;
QPoint m_endMovePoint;
CaptureState m_currentCaptureState;
QRect m_currentSelectRect;
QRect m_topLeftRect;
QRect m_topRightRect;
QRect m_bottomLeftRect;
QRect m_bottomRightRect;
QRect m_leftCenterRect;
QRect m_topCenterRect;
QRect m_rightCenterRect;
QRect m_bottomCenterRect;
StretchRectState m_stretchRectState;
};
.cpp
#include "截屏头文件.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QMouseEvent>
#include <QDebug>
#define SELECT_RECT_BORDER_WIDTH 2
#define STRETCH_RECT_WIDTH 6
#define STRETCH_RECT_HEIGHT 6
CaptureScreen::CaptureScreen(QWidget *parent)
: QWidget(parent)
, m_currentCaptureState(InitCapture)
{
widgetInit();
loadBackgroundPixmap();
}
CaptureScreen::~CaptureScreen()
{
}
void CaptureScreen::widgetInit()
{
this->setMouseTracking(true);
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
setWindowState(Qt::WindowActive | Qt::WindowFullScreen);
this->setMouseTracking(true);
m_stretchRectState = NotSelect;
m_topLeftRect = QRect(0 , 0 , 0 , 0);
m_topRightRect = QRect(0, 0, 0, 0);
m_bottomLeftRect = QRect(0, 0, 0, 0);
m_bottomRightRect = QRect(0, 0, 0, 0);
m_leftCenterRect = QRect(0, 0, 0, 0);
m_topCenterRect = QRect(0, 0, 0, 0);
m_rightCenterRect = QRect(0, 0, 0, 0);
m_bottomCenterRect = QRect(0, 0, 0, 0);
}
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)
{
m_stretchRectState = getStrethRectState(event->pos());
if (event->button() == Qt::LeftButton)
{
if (m_currentCaptureState == InitCapture)
{
m_currentCaptureState = BeginCaptureImage;
m_beginPoint = event->pos();
}
else if (m_stretchRectState != NotSelect)
{
m_currentCaptureState = BeginMoveStretchRect;
setStretchCursorStyle(m_stretchRectState);
m_beginMovePoint = event->pos();
}
else if (isPressPointInSelectRect(event->pos()))
{
m_currentCaptureState = BeginMoveCaptureArea;
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();
}
else if (m_currentCaptureState == BeginMoveStretchRect)
{
m_endMovePoint = event->pos();
update();
return QWidget::mouseMoveEvent(event);
}
StretchRectState stretchRectState = getStrethRectState(event->pos());
if (stretchRectState != NotSelect)
{
setStretchCursorStyle(stretchRectState);
}
else 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();
}
else if (m_currentCaptureState == BeginMoveStretchRect)
{
m_currentCaptureState = FinishMoveStretchRect;
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, 120);
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:
case BeginMoveStretchRect:
case FinishMoveStretchRect:
m_currentSelectRect = getSelectRect();
drawCaptureImage();
case FinishCapture:
break;
default:
break;
}
m_painter.end();
}
QRect CaptureScreen::getSelectRect()
{
QRect selectRect(0, 0, 0, 0);
if (m_currentCaptureState == BeginCaptureImage || m_currentCaptureState == FinishCaptureImage)
{
selectRect = getRect(m_beginPoint, m_endPoint);
}
else if (m_currentCaptureState == BeginMoveCaptureArea || m_currentCaptureState == FinishMoveCaptureArea)
{
selectRect = getMoveRect();
}
else if (m_currentCaptureState == BeginMoveStretchRect || m_currentCaptureState == FinishMoveStretchRect)
{
selectRect = getStretchRect();
}
if (m_currentCaptureState == FinishCaptureImage || m_currentCaptureState == FinishMoveCaptureArea || m_currentCaptureState == FinishMoveStretchRect)
{
m_currentCaptureState = FinishCapture;
}
return selectRect;
}
void CaptureScreen::drawCaptureImage()
{
m_capturePixmap = m_loadPixmap.copy(m_currentSelectRect);
m_painter.drawPixmap(m_currentSelectRect.topLeft(), m_capturePixmap);
m_painter.setPen(QPen(QColor(0, 180, 255), SELECT_RECT_BORDER_WIDTH));
m_painter.drawRect(m_currentSelectRect);
drawStretchRect();
}
void CaptureScreen::drawStretchRect()
{
QColor color = QColor(0, 174, 255);
QPoint topLeft = m_currentSelectRect.topLeft();
QPoint topRight = m_currentSelectRect.topRight();
QPoint bottomLeft = m_currentSelectRect.bottomLeft();
QPoint bottomRight = m_currentSelectRect.bottomRight();
QPoint leftCenter = QPoint(topLeft.x(), (topLeft.y() + bottomLeft.y()) / 2);
QPoint topCenter = QPoint((topLeft.x() + topRight.x()) / 2, topLeft.y());
QPoint rightCenter = QPoint(topRight.x(), leftCenter.y());
QPoint bottomCenter = QPoint(topCenter.x(), bottomLeft.y());
m_topLeftRect = QRect(topLeft.x() - STRETCH_RECT_WIDTH / 2, topLeft.y() - STRETCH_RECT_HEIGHT / 2, STRETCH_RECT_WIDTH, STRETCH_RECT_HEIGHT);
m_topRightRect = QRect(topRight.x() - STRETCH_RECT_WIDTH / 2, topRight.y() - STRETCH_RECT_HEIGHT / 2, STRETCH_RECT_WIDTH, STRETCH_RECT_HEIGHT);
m_bottomLeftRect = QRect(bottomLeft.x() - STRETCH_RECT_WIDTH / 2, bottomLeft.y() - STRETCH_RECT_HEIGHT / 2, STRETCH_RECT_WIDTH, STRETCH_RECT_HEIGHT);
m_bottomRightRect = QRect(bottomRight.x() - STRETCH_RECT_WIDTH / 2, bottomRight.y() - STRETCH_RECT_HEIGHT / 2, STRETCH_RECT_WIDTH, STRETCH_RECT_HEIGHT);
m_leftCenterRect = QRect(leftCenter.x() - STRETCH_RECT_WIDTH / 2, leftCenter.y() - STRETCH_RECT_HEIGHT / 2, STRETCH_RECT_WIDTH, STRETCH_RECT_HEIGHT);
m_topCenterRect = QRect(topCenter.x() - STRETCH_RECT_WIDTH / 2, topCenter.y() - STRETCH_RECT_HEIGHT / 2, STRETCH_RECT_WIDTH, STRETCH_RECT_HEIGHT);
m_rightCenterRect = QRect(rightCenter.x() - STRETCH_RECT_WIDTH / 2, rightCenter.y() - STRETCH_RECT_HEIGHT / 2, STRETCH_RECT_WIDTH, STRETCH_RECT_HEIGHT);
m_bottomCenterRect = QRect(bottomCenter.x() - STRETCH_RECT_WIDTH / 2, bottomCenter.y() - STRETCH_RECT_HEIGHT / 2, STRETCH_RECT_WIDTH, STRETCH_RECT_HEIGHT);
m_painter.fillRect(m_topLeftRect, color);
m_painter.fillRect(m_topRightRect, color);
m_painter.fillRect(m_bottomLeftRect, color);
m_painter.fillRect(m_bottomRightRect, color);
m_painter.fillRect(m_leftCenterRect, color);
m_painter.fillRect(m_topCenterRect, color);
m_painter.fillRect(m_rightCenterRect, color);
m_painter.fillRect(m_bottomCenterRect, color);
}
void CaptureScreen::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Escape)
{
close();
}
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
{
signalCompleteCature(m_capturePixmap);
close();
}
}
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);
if (selectedRect.width() == 0)
{
selectedRect.setWidth(1);
}
if (selectedRect.height() == 0)
{
selectedRect.setHeight(1);
}
return selectedRect;
}
QRect CaptureScreen::getMoveRect()
{
QPoint movePoint = getMovePoint();
QPoint beginPoint = m_beginPoint + movePoint;
QPoint endPoint = m_endPoint + movePoint;
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;
}
StretchRectState CaptureScreen::getStrethRectState(QPoint point)
{
StretchRectState stretchRectState = NotSelect;
if (m_topLeftRect.contains(point))
{
stretchRectState = TopLeftRect;
}
else if (m_topCenterRect.contains(point))
{
stretchRectState = TopCenterRect;
}
else if (m_topRightRect.contains(point))
{
stretchRectState = TopRightRect;
}
else if (m_rightCenterRect.contains(point))
{
stretchRectState = RightCenterRect;
}
else if (m_bottomRightRect.contains(point))
{
stretchRectState = BottomRightRect;
}
else if (m_bottomCenterRect.contains(point))
{
stretchRectState = BottomCenterRect;
}
else if (m_bottomLeftRect.contains(point))
{
stretchRectState = BottomLeftRect;
}
else if (m_leftCenterRect.contains(point))
{
stretchRectState = LeftCenterRect;
}
return stretchRectState;
}
void CaptureScreen::setStretchCursorStyle(StretchRectState stretchRectState)
{
switch (stretchRectState)
{
case NotSelect:
setCursor(Qt::ArrowCursor);
break;
case TopLeftRect:
case BottomRightRect:
setCursor(Qt::SizeFDiagCursor);
break;
case TopRightRect:
case BottomLeftRect:
setCursor(Qt::SizeBDiagCursor);
break;
case LeftCenterRect:
case RightCenterRect:
setCursor(Qt::SizeHorCursor);
break;
case TopCenterRect:
case BottomCenterRect:
setCursor(Qt::SizeVerCursor);
break;
default:
break;
}
}
QRect CaptureScreen::getStretchRect()
{
QRect stretchRect;
QRect currentRect = getRect(m_beginPoint, m_endPoint);
switch (m_stretchRectState)
{
case NotSelect:
stretchRect = getRect(m_beginPoint, m_endPoint);
break;
case TopLeftRect:
{
stretchRect = getRect(currentRect.bottomRight(), m_endMovePoint);
}
break;
case TopRightRect:
{
QPoint beginPoint = QPoint(currentRect.topLeft().x(), m_endMovePoint.y());
QPoint endPoint = QPoint(m_endMovePoint.x(), currentRect.bottomRight().y());
stretchRect = getRect(beginPoint, endPoint);
}
break;
case BottomLeftRect:
{
QPoint beginPoint = QPoint(m_endMovePoint.x() , currentRect.topLeft().y());
QPoint endPoint = QPoint(currentRect.bottomRight().x(), m_endMovePoint.y());
stretchRect = getRect(beginPoint, endPoint);
}
break;
case BottomRightRect:
{
stretchRect = getRect(currentRect.topLeft(), m_endMovePoint);
}
break;
case LeftCenterRect:
{
QPoint beginPoint = QPoint(m_endMovePoint.x(), currentRect.topLeft().y());
stretchRect = getRect(beginPoint, currentRect.bottomRight());
}
break;
case TopCenterRect:
{
QPoint beginPoint = QPoint(currentRect.topLeft().x(), m_endMovePoint.y());
stretchRect = getRect(beginPoint, currentRect.bottomRight());
}
break;
case RightCenterRect:
{
QPoint endPoint = QPoint(m_endMovePoint.x(), currentRect.bottomRight().y());
stretchRect = getRect(currentRect.topLeft(), endPoint);
}
break;
case BottomCenterRect:
{
QPoint endPoint = QPoint(currentRect.bottomRight().x(), m_endMovePoint.y());
stretchRect = getRect(currentRect.topLeft(), endPoint);
}
break;
default:
{
stretchRect = getRect(m_beginPoint , m_endPoint );
}
break;
}
if (m_currentCaptureState == FinishMoveStretchRect)
{
m_beginPoint = stretchRect.topLeft();
m_endPoint = stretchRect.bottomRight();
}
return stretchRect;
}
实现效果
代码可直接运行。
有问题请留言,不忙的时候会看。若对你有帮助,点个赞吧!!