一、新建项目
点击“New Project”,选择“Application”“Qt Widget Application”,点击“Choose”
更改项目名称和位置
选择编译器
默认
默认
二、创建自定义类
右击项目名,选择“Add New”
选择“C++” -> "C++ Class",点击“Choose”
更改名称和基类
默认
更改photolabel.h的代码
#ifndef PHOTOLABEL_H
#define PHOTOLABEL_H
#include <QObject>
#include <QLabel>
#include <QMenu>
class PhotoLabel : public QLabel
{
public:
explicit PhotoLabel(QWidget *parent = nullptr);
void setPhoto(QString); //设置图片
void clearShow(); //清空显示
protected:
void contextMenuEvent(QContextMenuEvent *event) override; //右键菜单
void paintEvent(QPaintEvent *event); //QPaint画图
void wheelEvent(QWheelEvent *event) override; //鼠标滚轮滚动
void mousePressEvent(QMouseEvent *event) override; //鼠标摁下
void mouseMoveEvent(QMouseEvent *event) override; //鼠标松开
void mouseReleaseEvent(QMouseEvent *event) override; //鼠标发射事件
private slots:
void initWidget(); //初始化
void onSelectImage(); //选择打开图片
void onZoomInImage(); //图片放大
void onZoomOutImage(); //图片缩小
void onPresetImage(); //图片还原
private:
QImage m_image; //显示的图片
qreal m_zoomValue = 1.0; //鼠标缩放值
int m_xPtInterval = 0; //平移X轴的值
int m_yPtInterval = 0; //平移Y轴的值
QPoint m_oldPos; //旧的鼠标位置
bool m_pressed = false; //鼠标是否被摁压
QString m_localFileName; //文件名称
QMenu *m_menu; //右键菜单
};
#endif // PHOTOLABEL_H
更改photolabel.cpp的代码
#include "photolabel.h"
#include <QPainter>
#include <QDebug>
#include <QWheelEvent>
#include <QFileDialog>
PhotoLabel::PhotoLabel(QWidget *parent):QLabel(parent)
{
initWidget();
}
/**
* @brief PhotoLabel::initWidget 初始化
*/
void PhotoLabel::initWidget()
{
//初始化右键菜单
m_menu = new QMenu(this);
QAction *loadImage = new QAction;
loadImage->setText("选择图片");
connect(loadImage, &QAction::triggered, this, &PhotoLabel::onSelectImage);
m_menu->addAction(loadImage);
m_menu->addSeparator();
QAction *zoomInAction = new QAction;
zoomInAction->setText("放大");
connect(zoomInAction, &QAction::triggered, this, &PhotoLabel::onZoomInImage);
m_menu->addAction(zoomInAction);
QAction *zoomOutAction = new QAction;
zoomOutAction->setText("缩小");
connect(zoomOutAction, &QAction::triggered, this, &PhotoLabel::onZoomOutImage);
m_menu->addAction(zoomOutAction);
QAction *presetAction = new QAction;
presetAction->setText("还原");
connect(presetAction, &QAction::triggered, this, &PhotoLabel::onPresetImage);
m_menu->addAction(presetAction);
m_menu->addSeparator();
QAction *clearAction = new QAction;
clearAction->setText("清空");
connect(clearAction, &QAction::triggered, this, &PhotoLabel::clearShow);
m_menu->addAction(clearAction);
}
/**
* @brief PhotoLabel::setPhoto 设置要显示的图片
* @param path 图片路径
*/
void PhotoLabel::setPhoto(QString path)
{
if(path.isEmpty())
{
return;
}
m_zoomValue = 1.0;
m_xPtInterval = 0;
m_yPtInterval = 0;
m_localFileName = path;
m_image.load(m_localFileName);
update();
}
/**
* @brief PhotoLabel::clearShow 清空
*/
void PhotoLabel::clearShow()
{
m_localFileName = "";
m_image = QImage();
this->clear();
}
/**
* @brief PhotoLabel::paintEvent 绘图事件
* @param event
*/
void PhotoLabel::paintEvent(QPaintEvent *event)
{
if(m_image.isNull())
return QWidget::paintEvent(event);
QPainter painter(this);
// 根据窗口计算应该显示的图片的大小
int width = qMin(m_image.width(), this->width());
int height = int(width * 1.0 / (m_image.width() * 1.0 / m_image.height()));
height = qMin(height, this->height());
width = int(height * 1.0 * (m_image.width() * 1.0 / m_image.height()));
// 平移
painter.translate(this->width() / 2 + m_xPtInterval, this->height() / 2 + m_yPtInterval);
// 缩放
painter.scale(m_zoomValue, m_zoomValue);
// 绘制图像
QRect picRect(-width / 2, -height / 2, width, height);
painter.drawImage(picRect, m_image);
QWidget::paintEvent(event);
}
/**
* @brief PhotoLabel::wheelEvent 滚轮滚动缩放图片
* @param event
*/
void PhotoLabel::wheelEvent(QWheelEvent *event)
{
int value = event->delta();
if (value > 0) //放大
onZoomInImage();
else //缩小
onZoomOutImage();
update();
}
/**
* @brief PhotoLabel::mousePressEvent 鼠标按下,为移动图片做准备
* @param event
*/
void PhotoLabel::mousePressEvent(QMouseEvent *event)
{
m_oldPos = event->pos();
m_pressed = true;
this->setCursor(Qt::ClosedHandCursor); //设置鼠标样式
}
/**
* @brief PhotoLabel::mouseMoveEvent 鼠标按下后,再移动鼠标,图片随之移动
* @param event
*/
void PhotoLabel::mouseMoveEvent(QMouseEvent *event)
{
if (!m_pressed)
return QWidget::mouseMoveEvent(event);
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;
update();
}
/**
* @brief PhotoLabel::mouseReleaseEvent 鼠标抬起,图片移动结束
*/
void PhotoLabel::mouseReleaseEvent(QMouseEvent */*event*/)
{
m_pressed = false;
this->setCursor(Qt::ArrowCursor); //设置鼠标样式
}
/**
* @brief PhotoLabel::contextMenuEvent 右键显示菜单栏
* @param event
*/
void PhotoLabel::contextMenuEvent(QContextMenuEvent *event)
{
QPoint pos = event->pos();
pos = this->mapToGlobal(pos);
m_menu->exec(pos);
}
/**
* @brief PhotoLabel::onSelectImage 选择图片
*/
void PhotoLabel::onSelectImage()
{
QString path = QFileDialog::getOpenFileName(this, "选择 要显示的图片", "./", tr("Images (*.png *.jpg *.jpeg)"));
if (path.isEmpty())
return;
setPhoto(path);
}
/**
* @brief PhotoLabel::onZoomInImage 图片放大
*/
void PhotoLabel::onZoomInImage()
{
m_zoomValue += 0.05;
update();
}
/**
* @brief PhotoLabel::onZoomOutImage 图片缩小
*/
void PhotoLabel::onZoomOutImage()
{
m_zoomValue -= 0.05;
if (m_zoomValue <= 0)
{
m_zoomValue = 0.05;
return;
}
update();
}
/**
* @brief PhotoLabel::onPresetImage 图片还原
*/
void PhotoLabel::onPresetImage()
{
m_zoomValue = 1.0;
m_xPtInterval = 0;
m_yPtInterval = 0;
update();
}
三、自定义类的使用
双击“mainwindow.ui”
拖拽一个Label,并进行网格布局
右击TextLabel,选择“提升为”
输入类名称,点击“添加”
点击“提升”
label的基类被更改
四、运行测试
右击界面,选择“选择图片”
添加一张图片之后,可以右击选择“放大/缩小/还原”等,也可以鼠标滚轮控制缩放;
也可以鼠标点击不松开,移动鼠标,从而使图片移