(7) Rewrite QLabel to zoom the picture at the mouse point

A little test, let’s not say much, first look at the picture:
Insert picture description here
Principle: the initial point (0,0) draws the picture, the picture is scaled, the mouse point x (1+zoom multiple) = the coordinate in the picture, the initial drawing point moves in the opposite direction (mouse Point x the distance of the zoom factor), you can see the zoom effect at the mouse point.

MyLabel.h

#ifndef MYLABEL_H
#define MYLABEL_H

#include <QObject>
#include <QLabel>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QPainter>
#include <QDebug>

class MyLabel:public QLabel
{
    
    
public:
    MyLabel(QWidget *parent=nullptr);

protected:
    void paintEvent(QPaintEvent *) override;
    void mouseMoveEvent(QMouseEvent *ev) override;
    void mousePressEvent(QMouseEvent *ev) override;
    void mouseReleaseEvent(QMouseEvent *ev) override;
    void wheelEvent(QWheelEvent *event) override;
    void resizeEvent(QResizeEvent *event) override;
    void changeWheelValue(QPoint event,int value);
private:
    double m_scaleValue;      // 图片缩放倍数
    QPointF m_drawPoint;      // 绘图起点
    QPointF m_mousePoint;     // 鼠标当前位置点
    QRect m_rectPixmap;       // 被绘图片的矩形范围
    bool m_isMousePress;      // 鼠标是否按下

    const double EPS = 1e-6;  // 双精度浮点数比较
    const double SCALE_VALUE=0.02;
    const double SCALE_MAX_VALUE=2.0;
    const double SCALE_MIN_VALUE=0.5;
};

#endif // MYLABEL_H

MyLabel.cpp

#include "mylabel.h"

MyLabel::MyLabel(QWidget *parent):QLabel(parent)
  ,m_scaleValue(1.0)
  ,m_mousePoint(0,0)
  ,m_drawPoint(0,0)
  ,m_rectPixmap(0,0,0,0)
  ,m_isMousePress(0)
{
    
    

}

void MyLabel::paintEvent(QPaintEvent *)
{
    
    
    QPainter painter(this);

    QPixmap pixmap(":/image/1.jpg");
    double width=this->width()*m_scaleValue;
    double height=this->height()*m_scaleValue;
    QPixmap scalePixmap=pixmap.scaled(width,height,Qt::IgnoreAspectRatio, Qt::SmoothTransformation); // 饱满缩放
    m_rectPixmap=QRect(m_drawPoint.x(),m_drawPoint.y(),width,height);  // 图片区域
    painter.drawPixmap(m_rectPixmap,scalePixmap);
}

void MyLabel::mouseMoveEvent(QMouseEvent *event)
{
    
    
    if(m_isMousePress)
    {
    
    
        int x=event->pos().x()-m_mousePoint.x();
        int y=event->pos().y()-m_mousePoint.y();
        m_mousePoint=event->pos();
        m_drawPoint=QPointF(m_drawPoint.x()+x,m_drawPoint.y()+y);
        update();
    }
}

void MyLabel::mousePressEvent(QMouseEvent *event)
{
    
    
    if(event->button()==Qt::LeftButton)
    {
    
    
        m_isMousePress=true;
        m_mousePoint=event->pos();
    }
}

void MyLabel::mouseReleaseEvent(QMouseEvent *event)
{
    
    
    if(event->button() == Qt::RightButton)
    {
    
    
        m_drawPoint=QPointF(0,0);
        m_scaleValue=1.0;
        update();
    }
    if(event->button() == Qt::LeftButton) m_isMousePress=false;
}

void MyLabel::wheelEvent(QWheelEvent *event)
{
    
    
    int numDegrees = event->delta()/ 8; // 滚动角度 - *8就是鼠标滚动的距离
    int numSteps = numDegrees / 15;     // 滚动步数 - *15就是鼠标滚动的角度
    changeWheelValue(event->pos(),numSteps);
    event->accept();
}

void MyLabel::resizeEvent(QResizeEvent *event)
{
    
    
    m_drawPoint=QPointF(0,0);
    m_scaleValue=1.0;
    update();
}

void MyLabel::changeWheelValue(QPoint event, int numSteps)
{
    
    
    m_scaleValue+=numSteps*SCALE_VALUE;
    if(m_scaleValue>(SCALE_MAX_VALUE+EPS))
    {
    
    
        m_scaleValue=SCALE_MAX_VALUE;
        return ;
    }
    if(m_scaleValue<(SCALE_MIN_VALUE-EPS))
    {
    
    
        m_scaleValue=SCALE_MIN_VALUE;
        return ;
    }

    if(m_rectPixmap.contains(event))
    {
    
    
        double x=m_drawPoint.x()-(event.x()-m_drawPoint.x())/m_rectPixmap.width()*(this->width()*SCALE_VALUE)*numSteps;
        double y=m_drawPoint.y()-(event.y()-m_drawPoint.y())/m_rectPixmap.height()*(this->height()*SCALE_VALUE)*numSteps;
        m_drawPoint=QPointF(x,y);
    }
    else
    {
    
    
        double x=m_drawPoint.x()-(this->width()*SCALE_VALUE)*numSteps/2;
        double y=m_drawPoint.y()-(this->height()*SCALE_VALUE)*numSteps/2;
        m_drawPoint=QPointF(x,y);
    }
    update();
}

Guess you like

Origin blog.csdn.net/qq_40329851/article/details/115291762