15、Qt显示图片并支持缩放、移动等操作

一、新建项目

点击“New Project”,选择“Application”“Qt Widget Application”,点击“Choose”

15、Qt显示图片并支持缩放、移动等操作_第1张图片

更改项目名称和位置

15、Qt显示图片并支持缩放、移动等操作_第2张图片

选择编译器

15、Qt显示图片并支持缩放、移动等操作_第3张图片

默认

15、Qt显示图片并支持缩放、移动等操作_第4张图片

默认

15、Qt显示图片并支持缩放、移动等操作_第5张图片

二、创建自定义类

右击项目名,选择“Add New”

15、Qt显示图片并支持缩放、移动等操作_第6张图片

选择“C++” -> "C++ Class",点击“Choose”

15、Qt显示图片并支持缩放、移动等操作_第7张图片

更改名称和基类

15、Qt显示图片并支持缩放、移动等操作_第8张图片

默认

15、Qt显示图片并支持缩放、移动等操作_第9张图片

更改photolabel.h的代码

#ifndef PHOTOLABEL_H
#define PHOTOLABEL_H

#include 
#include 
#include 

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 
#include 
#include 
#include 

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”

15、Qt显示图片并支持缩放、移动等操作_第10张图片

拖拽一个Label,并进行网格布局

15、Qt显示图片并支持缩放、移动等操作_第11张图片

右击TextLabel,选择“提升为”

15、Qt显示图片并支持缩放、移动等操作_第12张图片

 输入类名称,点击“添加”

15、Qt显示图片并支持缩放、移动等操作_第13张图片

点击“提升” 

15、Qt显示图片并支持缩放、移动等操作_第14张图片

label的基类被更改

15、Qt显示图片并支持缩放、移动等操作_第15张图片

四、运行测试

右击界面,选择“选择图片”

15、Qt显示图片并支持缩放、移动等操作_第16张图片

添加一张图片之后,可以右击选择“放大/缩小/还原”等,也可以鼠标滚轮控制缩放;

15、Qt显示图片并支持缩放、移动等操作_第17张图片

也可以鼠标点击不松开,移动鼠标,从而使图片移

15、Qt显示图片并支持缩放、移动等操作_第18张图片

你可能感兴趣的:(Qt小功能,qt)