Qt 之 简单截图功能(一)实现鼠标选中区域截图

一、简述

之前用Qt实现了类似于QQ的截图功能,由于代码太多,一下子不一定明白,今天就用一个简单的小例子来看一看如何用Qt实现一个简单的截图功能。此篇文章中代码很简单,功能也比较简单,在后续的文章中将会逐步完善。先看来一下简单的效果图。

在这里插入图片描述

效果图

正向截取

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DW4JkmDt-1655362248991)(https://img-blog.csdn.net/20170105230928630?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvR29Gb3J3YXJkVG9TdGVw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]

反向截取

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eT1ejRDb-1655362248992)(https://img-blog.csdn.net/20170107211341768?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvR29Gb3J3YXJkVG9TdGVw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]

上图是通过点击截图按钮,然后选择区域,按下Enter键进行截图并显示到主窗口中。

其实实现截图的原理很简单,就是事先截取整个屏幕,然后根据鼠标选择区域进行截取,主要难点在于获取选中的区域,此篇中获取选中区域代码较为简单,存在一定的问题,后续会详细讲解,并加以完善。


下面是目前已经实现的效果。

已完成效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kizldGI3-1655362248993)(https://img-blog.csdn.net/20170107212615727?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvR29Gb3J3YXJkVG9TdGVw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]


二、代码之路

capturescreen.h

#include <QWidget>
#include <QPainter>

class CaptureScreen : public QWidget
{
	Q_OBJECT

public:
	CaptureScreen(QWidget *parent = 0);
	~CaptureScreen();

Q_SIGNALS:
	void signalCompleteCature(QPixmap catureImage);

private:
	void initWindow();
	void loadBackgroundPixmap();

	void mousePressEvent(QMouseEvent *event);
	void mouseMoveEvent(QMouseEvent* event);
	void mouseReleaseEvent(QMouseEvent *event);
	void keyPressEvent(QKeyEvent *event);
	void paintEvent(QPaintEvent *event);

private:
	bool m_isMousePress;
	QPixmap m_loadPixmap, m_capturePixmap;
	int m_screenwidth;
	int m_screenheight;
	QPoint m_beginPoint, m_endPoint;
	QPainter m_painter;
};

capturescreen.cpp

#include "capturescreen.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QMouseEvent>

CaptureScreen::CaptureScreen(QWidget *parent)
	: QWidget(parent)
	, m_isMousePress(false)
{
	initWindow();
	loadBackgroundPixmap();
}

CaptureScreen::~CaptureScreen()
{

}

void CaptureScreen::initWindow()
{
	this->setMouseTracking(true);
	this->setWindowFlags(Qt::FramelessWindowHint);
	setWindowState(Qt::WindowActive | Qt::WindowFullScreen);
}

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_isMousePress = true;
		m_beginPoint = event->pos();
	}

	return QWidget::mousePressEvent(event);
}

void CaptureScreen::mouseMoveEvent(QMouseEvent* event)
{
	if (m_isMousePress)
	{
		m_endPoint = event->pos();
		update();
	}
	return QWidget::mouseMoveEvent(event);
}

void CaptureScreen::mouseReleaseEvent(QMouseEvent *event)
{
	m_endPoint = event->pos();
	m_isMousePress = false;
	return QWidget::mouseReleaseEvent(event);
}

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);			//画影罩效果;

	if (m_isMousePress)
	{
		QRect selectedRect = getRect(m_beginPoint, m_endPoint);
		m_capturePixmap = m_loadPixmap.copy(selectedRect);
		m_painter.drawPixmap(selectedRect.topLeft(), m_capturePixmap);
		m_painter.drawRect(selectedRect);
	}
	

	m_painter.end();  //重绘结束;
}

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();
	}
}

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;
}

测试代码

void TestWindow::onCatureImage()
{
	// 点击截图按钮开始截图;
	CaptureScreen* captureHelper = new CaptureScreen();
	connect(captureHelper, SIGNAL(signalCompleteCature(QPixmap)), this, SLOT(onCompleteCature(QPixmap)));
	captureHelper->show();
}

void TestWindow::onCompleteCature(QPixmap captureImage)
{
	ui.label->setPixmap(captureImage);
}

以上代码实现了一个简单的截图功能,后续会完善并增加更多的功能,争取能够实现QQ截图的效果 ,敬请期待 O(∩_∩)O!

Good Night !!!


代码下载

Qt 之 实现简单截图功能(一)

  • 36
    点赞
  • 218
    收藏
    觉得还不错? 一键收藏
  • 46
    评论
QCustomPlot是一个用于绘制交互式表的开源C++库。它允许用户对表进行多种交互操作,例如放大、缩小、平移等。要实现鼠标选中区域放大的功能,我们可以通过下述步骤来完成: 1. 为了能够接收鼠标事件,我们需要使用QCustomPlot中的信号和槽。我们可以连接plot对象的mousePress信号和mouseRelease信号到我们自定义的槽函数中。 2. 在mousePress事件中,我们可以记录鼠标的点击位置,以便在后续的mouseRelease事件中使用。 3. 在mouseRelease事件中,我们可以再次记录鼠标的位置,并计算出鼠标选中的矩形区域。 4. 使用QCustomPlot中的方法setRangeZoom函数来实现选中区域的放大。该方法的参数是一个QRectF对象,表示选中区域的坐标和大小。 下面是示例代码: ```cpp // 自定义的槽函数,处理鼠标事件 void handleMouseSelection(QMouseEvent* event) { if(event->button() == Qt::LeftButton) { if(event->type() == QEvent::MouseButtonPress) { startPoint = event->pos(); // 记录鼠标的点击位置 } else if(event->type() == QEvent::MouseButtonRelease) { endPoint = event->pos(); // 记录鼠标的释放位置 // 计算选中区域的矩形范围 int x = qMin(startPoint.x(), endPoint.x()); int y = qMin(startPoint.y(), endPoint.y()); int width = qAbs(startPoint.x() - endPoint.x()); int height = qAbs(startPoint.y() - endPoint.y()); QRectF selectionRect(x, y, width, height); plot->setRangeZoom(selectionRect); // 使用选中区域进行放大 } } } // 连接鼠标事件信号和槽函数 connect(plot, &QCustomPlot::mousePress, this, &handleMouseSelection); connect(plot, &QCustomPlot::mouseRelease, this, &handleMouseSelection); ``` 通过这样的代码,当我们在QCustomPlot上按下鼠标左键并拖动,然后释放鼠标左键时,就能够实现选中区域的放大效果。选中区域会被放大到整个绘区域,并自动调整坐标轴的范围,以使选中区域完全显示出来。
评论 46
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值