QT::QLabel改造一个简单的图像显示放大缩小和平移控件

2022-12-06  本文已影响0人  寽虎非虫003

需求

就很简单要使用一个可以放大缩小的图片显示控件,很多软件都有,也当做是一个学习。
还有些体验可以优化,但是对我而言基本够用了。

效果

image.png
image.png

代码

头文件ScaleLabel.h

#pragma once
#include <QLabel>
#include <QPainter>


class ScaleLabel:public QLabel
{
Q_OBJECT
public:
    void setQImage(QImage &img);///<传入要显示的图

public:
    /////////////////////////////////////////
    //  重载鼠标事件
    /////////////////////////////////////////
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void wheelEvent(QWheelEvent *envent) override;

    /////////////////////////////////////////
    // 重载绘图
    /////////////////////////////////////////
    void paintEvent(QPaintEvent *event) override;

private:
    //
    QImage m_showImg;///<传进来要显示的图
    float m_scale;///<缩放的倍率
    QPoint m_LastPt;///<移动时候要居中的点
    QPoint m_MoveDelta;///<移动时候要居中的点

    QPainter m_paiter;///<绘制对象
public:
    ScaleLabel(QWidget *parent = nullptr);
    ~ScaleLabel();
};

源文件


#include "ScaleLabel.h"
#include <QMouseEvent>

ScaleLabel::ScaleLabel(QWidget *parent)
{
    this->setBackgroundRole(QPalette::Base);
    m_scale = 1.0f;
}

ScaleLabel::~ScaleLabel()
{
}

void ScaleLabel::mousePressEvent(QMouseEvent *event)
{
    m_LastPt = event->position().toPoint();
    // event->accept();
}

//
void ScaleLabel::mouseMoveEvent(QMouseEvent *event)
{
    int dx = event->position().toPoint().x() - m_LastPt.x();
    int dy = event->position().toPoint().y() - m_LastPt.y();

    if (event->buttons() & Qt::LeftButton) // 左键按下,平移
    {
        m_MoveDelta += QPoint(dx, dy);
    }

    update();

    // 更新点位,可能不是很必要
    m_LastPt = event->position().toPoint();
}

// 滚轮控制缩放,但是这个缩放是改变的倍数,并不是所需要的拉远或拉近镜头
void ScaleLabel::wheelEvent(QWheelEvent *event)
{
    double numDegrees = event->angleDelta().y() / 180.0;

    if (numDegrees > 0)
    {
        m_scale *= 1.1;
    }
    else
    {
        m_scale *= 0.9;
    }
#ifdef _DEBUG
    qDebug("m_scale is %.3f", m_scale);
#endif

    // m_scale = m_scale * (1.0 + numDegrees);

    this->update();
    // event->accept();
}

void ScaleLabel::setQImage(QImage &img)
{
    m_showImg = img;
    float h = this->height();
    float w = this->width();
    m_scale = std::min(h / m_showImg.height(), w / m_showImg.width());

#ifdef _DEBUG
    qDebug("h(%.1f), w(%.1f), m_scale(%.3f)",h,w, m_scale);
#endif
}

void ScaleLabel::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    m_paiter.begin(this);

    m_paiter.scale(m_scale, m_scale); // 缩放
    m_paiter.translate(m_MoveDelta);  // 平移
    

    // 绘制
    //  m_paiter.drawImage(m_MoveDelta,m_showImg);
    m_paiter.drawImage(0, 0, m_showImg);

    /// 绘制中心框
    // 设置画笔
    QPen pen;
    pen.setStyle(Qt::SolidLine);
    pen.setWidth(2);
    pen.setColor(Qt::red);
    m_paiter.setPen(pen);
    // 正式绘制
    int w_half = m_showImg.width()/2;
    int h_half = m_showImg.height()/2;
    QRect re(w_half - 50, h_half - 50, 100, 100);
    m_paiter.drawRect(re);
    m_paiter.drawLine(w_half - 50, h_half, 0, h_half);          // 左侧
    m_paiter.drawLine(w_half + 50, h_half, w_half * 2, h_half); // 右侧
    m_paiter.drawLine(w_half, h_half - 50, w_half, 0);          // 上侧
    m_paiter.drawLine(w_half, h_half + 50, w_half, h_half * 2); // 下侧

    /// 转换

    // m_paiter.resetTransform();//重置变换

    

    m_paiter.end();
    // 显示
    this->update();
}

测试文件

#include<iostream>
#include <QApplication>
#include "UI/ScaleLabel.h"

using namespace std;
int main(int argc,char ** argv)
{
    cout<<"build sucessful!"<<endl;
    
    QApplication app(argc, argv); //初始化
    QImage img("./0/phase_0.png");

    ScaleLabel w;
    w.setFixedSize(600, 500);
    w.setQImage(img);
    // GenPhaseUI w;
    w.show();
    
    app.exec(); //主事件循环
    
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读