头文件如下:
#ifndef IMAGETRANSFORMLABEL_H
#define IMAGETRANSFORMLABEL_H
#include <QLabel>
#include <QMenu>
#include <QContextMenuEvent>
#include <QWheelEvent>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QCloseEvent>
class ImageTransformLabel : public QLabel
{
Q_OBJECT
public:
explicit ImageTransformLabel(QWidget *parent = nullptr);
void initMenu();
void setImage(QString imagePath);
protected:
void contextMenuEvent(QContextMenuEvent* event) override;
void paintEvent(QPaintEvent* event);
void wheelEvent(QWheelEvent* event) override;
void mousePressEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
private:
void slot_ActionLoadImage();
void slot_ActionZoomInImage();
void slot_ActionZoomOutImage();
void slot_ActionPresetImage();
void slot_ActionClearImage();
private:
QImage mImage;//加载的图像图像
QString mImagePath;//图像路径
float mZoomValue;//放大系数
float mOffsetX;//X方向偏移值
float mOffsetY;//Y方向偏移值
QPoint mOldPos;
bool mPressedFlag;
QMenu* mMenu;//右键菜单
QAction* mActionLoadImage;//加载图像
QAction* mActionZoomInImage;//放大图像
QAction* mActionZoomOutImage;//缩小图像
QAction* mActionPresetImage;//还原图像
QAction* mActionClearImage;//清空图像
signals:
};
#endif // IMAGETRANSFORMLABEL_H
源文件如下:
#include "imagetransformlabel.h"
#include <QFileDialog>
#include <QPainter>
#include <QMessageBox>
#pragma execution_character_set("utf-8")
ImageTransformLabel::ImageTransformLabel(QWidget *parent) : QLabel(parent)
{
initMenu();//初始化菜单
}
//初始化右键菜单
void ImageTransformLabel::initMenu()
{
mMenu = new QMenu(this);
mActionLoadImage = new QAction();
mActionLoadImage->setText("加载图像");
mMenu->addAction(mActionLoadImage);
mMenu->addSeparator();//添加分割符
mActionZoomInImage = new QAction();
mActionZoomInImage->setText("放大图像");
mMenu->addAction(mActionZoomInImage);
mMenu->addSeparator();//添加分割符
mActionZoomOutImage = new QAction();
mActionZoomOutImage->setText("缩小图像");
mMenu->addAction(mActionZoomOutImage);
mMenu->addSeparator();//添加分割符
mActionPresetImage = new QAction();
mActionPresetImage->setText("还原图像");
mMenu->addAction(mActionPresetImage);
mMenu->addSeparator();//添加分割符
mActionClearImage = new QAction();
mActionClearImage->setText("清除图像");
mMenu->addAction(mActionClearImage);
connect(mActionLoadImage,&QAction::triggered,this,&ImageTransformLabel::slot_ActionLoadImage);
connect(mActionZoomInImage,&QAction::triggered,this,&ImageTransformLabel::slot_ActionZoomInImage);
connect(mActionZoomOutImage,&QAction::triggered,this,&ImageTransformLabel::slot_ActionZoomOutImage);
connect(mActionPresetImage,&QAction::triggered,this,&ImageTransformLabel::slot_ActionPresetImage);
connect(mActionClearImage,&QAction::triggered,this,&ImageTransformLabel::slot_ActionClearImage);
}
void ImageTransformLabel::setImage(QString imagePath)
{
if(imagePath.isEmpty())
return;
mZoomValue = 1.0;
mOffsetX = 0;
mOffsetY = 0;
mImagePath = imagePath;
mImage.load(mImagePath);//加载图像
update();
}
void ImageTransformLabel::contextMenuEvent(QContextMenuEvent* event)
{
if(!mMenu)
return;
mMenu->exec(QCursor::pos());
}
void ImageTransformLabel::paintEvent(QPaintEvent *event)
{
if(mImage.isNull())//mImage是QImage类图像
return QWidget::paintEvent(event);
QPainter painter(this);
//根据窗口计算应该显示的图像大小-算法留意下
int width = qMin(mImage.width(),this->width());//qMin函数返回两个参数的最小值
int height = int(width * 1.0 /(mImage.width() * 1.0 / mImage.height()));
height = qMin(height,this->height());
width = height * 1.0 * (mImage.width() * 1.0 / mImage.height());
//平移
painter.translate(this->width()/2 + mOffsetX,this->height()/2 + mOffsetY);//mOffsetX是x方向偏移值,mOffsetY是y方向偏移值
//缩放
painter.scale(mZoomValue,mZoomValue);//mZoomValue是缩放系数
//绘制图像
QRect picRect(-width/2,-height/2,width,height);
painter.drawImage(picRect,mImage);
QWidget::paintEvent(event);
}
void ImageTransformLabel::wheelEvent(QWheelEvent *event)
{
int value = event->delta();
if(value > 0)//放大
{
slot_ActionZoomInImage();//内部已调用了update
}
else//缩小
{
slot_ActionZoomOutImage();//内部已调用了update
}
}
void ImageTransformLabel::mousePressEvent(QMouseEvent *event)
{
mOldPos = event->pos();
mPressedFlag = true;
this->setCursor(Qt::ClosedHandCursor);//设置鼠标样式
}
void ImageTransformLabel::mouseMoveEvent(QMouseEvent *event)
{
if(!mPressedFlag)
return QWidget::mouseMoveEvent(event);
QPoint pos = event->pos();
int offsetX = pos.x() - mOldPos.x();
int offsetY = pos.y() - mOldPos.y();
mOffsetX += offsetX;
mOffsetY += offsetY;
mOldPos = pos;
update();
}
void ImageTransformLabel::mouseReleaseEvent(QMouseEvent *event)
{
mPressedFlag = false;
this->setCursor(Qt::ArrowCursor);//设置鼠标样式
}
void ImageTransformLabel::slot_ActionLoadImage()
{
QString imagePath = QFileDialog::getOpenFileName(this,"选择图像","./",tr("Images (*.png *.jpg *.jpeg *.bmp)"));
if(imagePath.isEmpty())
return;
setImage(imagePath);
}
void ImageTransformLabel::slot_ActionZoomInImage()
{
mZoomValue += 0.05;
update();
}
void ImageTransformLabel::slot_ActionZoomOutImage()
{
mZoomValue -= 0.05;
if(mZoomValue < 0)
{
mZoomValue = 0.05;
}
update();
}
void ImageTransformLabel::slot_ActionPresetImage()
{
mZoomValue = 1.0;
mOffsetX = 0;
mOffsetY = 0;
update();
}
void ImageTransformLabel::slot_ActionClearImage()
{
this->clear();
mImage = QImage();
mImagePath = "";
}
备注:调用时对QLable类对象进行提升即可。