QT 实现简单截图功能

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;
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值