一个图片拖动、缩放、截取的图片显示窗口控件
#ifndef __IMGVIEWWIDGET_H__
#define __IMGVIEWWIDGET_H__
#if _MSC_VER >= 1600
#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;
private slots:
void onZoomInImage(void);
void onZoomOutImage(void);
void onPrintScreen();
};
#endif
#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())
{
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();
}
![效果展示](https://img-blog.csdnimg.cn/direct/55b165f91d934fa29b3f5e0d40b6e13a.gif)