Qt作品集

一个图片拖动、缩放、截取的图片显示窗口控件

// 头文件
#ifndef __IMGVIEWWIDGET_H__
#define __IMGVIEWWIDGET_H__

#if _MSC_VER >= 1600 //VS2015>VS>VS2010, MSVC VER= 10.0 -14.0
#pragma execution_character_set("utf-8")
#endif

#include <QWidget>
#include <QImage>

class ImageViewWidget : public QWidget
{
	Q_OBJECT

public:
	ImageViewWidget(QWidget* parent = nullptr);
	~ImageViewWidget();

	void loadImage(const QImage &img);

public slots:
	void onPresetImage(void);

signals:
	void toEimtPrintRect(QRect rect);

protected:
	void contextMenuEvent(QContextMenuEvent* event) override;
	void paintEvent(QPaintEvent* event) override;
	void wheelEvent(QWheelEvent* event) override;
	void mousePressEvent(QMouseEvent* event) override;
	void mouseMoveEvent(QMouseEvent* event) override;
	void mouseReleaseEvent(QMouseEvent* event) override;

private:
	QImage m_Image;
	qreal m_ZoomValue = 1.0;
	int m_XPtInterval = 0;
	int m_YPtInterval = 0;
	QPoint m_OldPos;
	QPoint m_startPos;
	QPoint m_currentPos;
	bool m_Pressed = false;
	bool m_printScreen = false;
	QRect m_imgPrintRect; // 图像截取的图像坐标系下的rect

private slots:
	void onZoomInImage(void);
	void onZoomOutImage(void);
	void onPrintScreen();
};

#endif // __IMGVIEWWIDGET_H__

// cpp文件
#include "image_view_widget.h"
#include <QMenu>
#include <QContextMenuEvent>
#include <QStyleOption>
#include <QPainter>
#include <QFileDialog>
#include <iostream>

ImageViewWidget::ImageViewWidget(QWidget* parent)
{
}

ImageViewWidget::~ImageViewWidget()
{

}

void ImageViewWidget::loadImage(const QImage& img)
{
	m_Image = img;
	this->update();
}

void ImageViewWidget::contextMenuEvent(QContextMenuEvent* event)
{
	QPoint pos = event->pos();
	pos = this->mapToGlobal(pos);
	QMenu* menu = new QMenu(this);

	QAction* zoomInAction = new QAction(tr("放大"));
	QObject::connect(zoomInAction, &QAction::triggered, this, &ImageViewWidget::onZoomInImage);
	menu->addAction(zoomInAction);

	QAction* zoomOutAction = new QAction(tr("缩小"));
	QObject::connect(zoomOutAction, &QAction::triggered, this, &ImageViewWidget::onZoomOutImage);
	menu->addAction(zoomOutAction);

	QAction* presetAction = new QAction(tr("还原"));
	QObject::connect(presetAction, &QAction::triggered, this, &ImageViewWidget::onPresetImage);
	menu->addAction(presetAction);

	QAction* printScreenAction = new QAction(tr("截取"));
	QObject::connect(printScreenAction, &QAction::triggered, this, &ImageViewWidget::onPrintScreen);
	menu->addAction(printScreenAction);

	menu->exec(pos);
}

void ImageViewWidget::paintEvent(QPaintEvent* event)
{
	// 绘制样式
	QStyleOption opt;
	opt.init(this);
	QPainter painter(this);
	style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);

	if (m_Image.isNull())
	{
		//painter.drawText(this->width() / 3, this->height() / 2, tr("鼠标双击导入图片,右键打开菜单"));
		return QWidget::paintEvent(event);
	}

	if (m_printScreen)
	{
		// 绘制图像
		QImage img = m_Image;
		img = img.scaled(this->width(), this->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
		QRect imgRect(0, 0, img.width(), img.height());
		painter.drawImage(imgRect, img);

		// 绘制框选的矩形
		painter.setPen(Qt::red);
		painter.drawRect(QRect(m_startPos, m_currentPos));
		
		int startX = (m_startPos.x() * m_Image.width()) / (img.width());
		int startY = (m_startPos.y() * m_Image.height()) / (img.height());
		int endX = (m_currentPos.x() * m_Image.width()) / (img.width());
		int endY = (m_currentPos.y() * m_Image.height()) / (img.height());

		m_imgPrintRect = QRect(QPoint(startX, startY), QPoint(endX, endY));
	}
	else
	{
		// 根据窗口计算应该显示的图片的大小
		QImage img = m_Image;
		img = img.scaled(this->width(), this->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
		QRect imgRect(0, 0, img.width(), img.height());

		// 平移
		painter.translate(m_XPtInterval, m_YPtInterval);

		// 缩放
		painter.scale(m_ZoomValue, m_ZoomValue);

		// 绘制图像
		painter.drawImage(imgRect, img);
	}
}

void ImageViewWidget::wheelEvent(QWheelEvent* event)
{
	int value = event->delta();
	if (value > 0)
		onZoomInImage();
	else
		onZoomOutImage();

	this->update();
}

void ImageViewWidget::mousePressEvent(QMouseEvent* event)
{
	m_OldPos = event->pos();
	m_startPos = event->pos();
	m_Pressed = true;
}

void ImageViewWidget::mouseMoveEvent(QMouseEvent* event)
{
	if (m_printScreen)
	{
		m_currentPos = event->pos();
	}
	else if (m_Pressed)
	{
		this->setCursor(Qt::SizeAllCursor);
		QPoint pos = event->pos();
		int xPtInterval = pos.x() - m_OldPos.x();
		int yPtInterval = pos.y() - m_OldPos.y();

		m_XPtInterval += xPtInterval;
		m_YPtInterval += yPtInterval;

		m_OldPos = pos;
	}
	else
	{
		return QWidget::mouseMoveEvent(event);
	}
	this->update();
}

void ImageViewWidget::mouseReleaseEvent(QMouseEvent* event)
{	
	if (m_printScreen)
	{
		m_printScreen = false;
		m_Pressed = false;
		emit toEimtPrintRect(m_imgPrintRect);
	}
	else if (m_Pressed)
	{
		m_Pressed = false;
		this->setCursor(Qt::ArrowCursor);
	}
	else
	{
		return QWidget::mouseReleaseEvent(event);
	}
}

void ImageViewWidget::onZoomInImage(void)
{
	m_ZoomValue += 0.2;
	if (m_ZoomValue >= 2.0)
	{
		m_ZoomValue -= 0.2;
		return;
	}
	this->update();
}

void ImageViewWidget::onZoomOutImage(void)
{
	m_ZoomValue -= 0.2;
	if (m_ZoomValue <= 0.2)
	{
		m_ZoomValue += 0.2;
		return;
	}

	this->update();
}

void ImageViewWidget::onPrintScreen()
{
	m_printScreen = true;
	this->update();
}

void ImageViewWidget::onPresetImage(void)
{
	m_ZoomValue = 1.0;
	m_XPtInterval = 0;
	m_YPtInterval = 0;
	this->update();
}

效果展示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值