这是一个QVGraphicsView显示图片的例子

#ifndef CGRAPHICSVIEW_H
#define CGRAPHICSVIEW_H

#include <QObject>
#include <QtOpenGL>
#include <QGraphicsView>
#include <QFuture>
#include <QImage>
#include <QPixmap>

class CGraphicsView : public QGraphicsView
{
    Q_OBJECT
public:
    explicit CGraphicsView(QWidget *parate = nullptr);
    ~CGraphicsView();
public:
    void setQImage(QImage m);
    void setPixmap(QPixmap m);
    void resetImage();
    QImage getQImage();
    QPixmap getPixmap();

    void drawMouseCross(QPainter* painter);
    void drawAxisCross(QPainter* painter);
protected:
    void keyPressEvent(QKeyEvent* event) override;
    void keyReleaseEvent(QKeyEvent* event) override;
    void drawBackground(QPainter* painter, const QRectF& r) override;
    void drawForeground(QPainter* painter, const QRectF& r) override;
    void wheelEvent(QWheelEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;
    void mouseDoubleClickEvent(QMouseEvent* e) override;

private:
    void zoomIn();  // 放大
    void zoomOut();  // 缩小
    void zoom(float scaleFactor); // 缩放 - scaleFactor:缩放的比例因子
    void mTranslate(QPointF delta); // 平移

    void initShow();
    void drawGrid(QPainter* painter, double gridStep);
private:
    QPixmap m_image;

    QGraphicsScene* m_scene;

    QPointF m_start_scene_pos;
    QPointF m_cur_scene_pos;
    QPoint m_cur_view_pos;

    bool m_isMousePressed;

    QColor m_cross_color = QColor(255, 0, 0);
    QColor m_axis_color;
    QRectF m_rectf;

    const Qt::MouseButton m_translateButton;  // 平移按钮
    qreal m_translateSpeed = 1;  // 平移速度
    qreal m_zoomDelta = 0.1;  // 缩放的增量
    bool m_bMouseTranslate= false;  // 平移标识

    QPoint m_axis_view_pos;

    QPointF m_startCenterPoint;  //平移鼠标第一次按下时场景的中心点
    QPoint m_startMousePos;  // 鼠标按下的位置
    QPoint m_lastMousePos;  // 鼠标最后按下的位置
    qreal m_scale=1;  // 缩放值

};

#endif // CGRAPHICSVIEW_H
#include "CGraphicsView.h"

CGraphicsView::CGraphicsView(QWidget* parate)
    :QGraphicsView{ parate },
    m_scene(nullptr),
    m_isMousePressed(false),
    m_translateButton(Qt::MiddleButton)
{
    m_scene = new QGraphicsScene(this);
    this->setScene(m_scene);
    //setViewportUpdateMode(QGraphicsView::FullViewportUpdate);

    setDragMode(QGraphicsView::DragMode::NoDrag);
    setMouseTracking(true);
    //setInteractive(false);
    //setEnabled(false);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setCursor(Qt::ArrowCursor);
    setRenderHint(QPainter::Antialiasing);
    //设置在箭头位置放大缩小
    setTransformationAnchor(ViewportAnchor::AnchorUnderMouse);
    setResizeAnchor(QGraphicsView::AnchorUnderMouse);

    setSceneRect(INT_MIN / 2, INT_MIN / 2, INT_MAX, INT_MAX);
    centerOn(0, 0);
}

CGraphicsView::~CGraphicsView()
{
    delete m_scene;
    m_scene = nullptr;
}

void CGraphicsView::setQImage(QImage m)
{
    if (m.isNull())
        return;
    m_image = QPixmap::fromImage(m);
    initShow();
}

void CGraphicsView::setPixmap(QPixmap m)
{
    m_image = m.copy();
    initShow();
}

void CGraphicsView::resetImage()
{
    if (m_image.isNull())
        return;
    m_scene->clear();
    setEnabled(false);
}

QImage CGraphicsView::getQImage()
{
    return m_image.toImage();
}

QPixmap CGraphicsView::getPixmap()
{
    return m_image;
}

void CGraphicsView::drawMouseCross(QPainter* painter)
{
    QPainter painter_cross(viewport());
    painter_cross.setRenderHint(QPainter::Antialiasing);
    painter_cross.setPen(m_cross_color);
    painter_cross.drawLine(0, m_cur_view_pos.y(), viewport()->width(), m_cur_view_pos.y());
    painter_cross.drawLine(m_cur_view_pos.x(), 0, m_cur_view_pos.x(), viewport()->height());

}

void CGraphicsView::drawAxisCross(QPainter* painter)
{
    QPainter painter_axis(viewport());
    painter_axis.setRenderHint(QPainter::Antialiasing);
    painter_axis.setPen(m_axis_color);
    painter_axis.drawLine(0, m_axis_view_pos.y(), viewport()->width(), m_axis_view_pos.y());
    painter_axis.drawLine(m_axis_view_pos.x(), 0, m_axis_view_pos.x(), viewport()->height());

    painter_axis.drawRect(m_rectf);
}

void CGraphicsView::drawBackground(QPainter* painter, const QRectF& r)
{
    QGraphicsView::drawBackground(painter, r);
    QTransform t_scene = this->transform();
    qreal ratio = t_scene.m11();
    //drawLogoBackground(painter, rect, ratio);
}

void CGraphicsView::drawForeground(QPainter* painter, const QRectF& r)
{
    //在viewport 上画标尺,可以显示实时的坐标
 //    QPainter painter1(viewport());
 //    if (m_scene->getSceneState() == ImageScene::E_Create)
 //    {
 //        //绘制鼠标位置的横线和竖线
 //        painter1.setPen(m_dot_pen);
 //    }
 //    else
 //    {
 //        if (!m_disp_mouse_cross)
 //        {
 //            return;
 //        }
 //        painter1.setPen(m_solid_pen);
 //    }
 //    painter1.drawLine(ruler_width, m_cur_mouse_pos.y(), viewport()->width(), m_cur_mouse_pos.y());
 //    painter1.drawLine(m_cur_mouse_pos.x(), ruler_width, m_cur_mouse_pos.x(), viewport()->height());

}

void CGraphicsView::wheelEvent(QWheelEvent* event)
{
    if (m_image.isNull())
        return;
    // 滚轮的滚动量
    QPoint scrollAmount = event->angleDelta();
    setCursor(Qt::CrossCursor);
    //setCursor(Qt::DragMoveCursor);
    // 正值表示滚轮远离使用者(放大),负值表示朝向使用者(缩小)
    scrollAmount.y() > 0 ? zoomIn() : zoomOut();
    setCursor(Qt::ArrowCursor);
}

void CGraphicsView::keyPressEvent(QKeyEvent* event)
{
    QGraphicsView::keyPressEvent(event);
    //m_scene->keyPressEvent(event);
    return;
    if (event->key() == Qt::Key_O)
    {
        this->resetTransform();
        this->setSceneRect(m_image.rect());
        this->fitInView(QRect(0, 0, m_image.width(), m_image.height()), Qt::KeepAspectRatio);
    }
}

void CGraphicsView::keyReleaseEvent(QKeyEvent* event)
{
    QGraphicsView::keyReleaseEvent(event);
}

void CGraphicsView::mousePressEvent(QMouseEvent* event)
{
    if (event->button() == m_translateButton && m_bMouseTranslate == false) {
        // 当光标底下没有 item 时,才能移动
        m_bMouseTranslate = true;
        m_startCenterPoint = mapToScene(rect().center());
        m_startMousePos = event->pos();
        setCursor(Qt::DragMoveCursor);
    }
    else
    {
        //set
        setCursor(Qt::PointingHandCursor);
    }
    QGraphicsView::mousePressEvent(event);

    m_isMousePressed = true;
    m_startMousePos = event->pos();
    m_start_scene_pos = mapToScene(event->pos());
}

void CGraphicsView::mouseMoveEvent(QMouseEvent* event)
{
    if (m_bMouseTranslate) {
        //get the delta of mouse in scene
        m_scale = this->transform().m11();
        QPointF mouseDelta = (m_startMousePos - event->pos()) / fabs(m_scale);
        mTranslate(mouseDelta);
    }

    QGraphicsView::mouseMoveEvent(event);
    m_cur_view_pos = event->pos();
    m_cur_scene_pos = mapToScene(m_cur_view_pos);
}

void CGraphicsView::mouseReleaseEvent(QMouseEvent* event)
{
    if (event->button() == m_translateButton) {

        m_bMouseTranslate = false;
    }
    setCursor(Qt::ArrowCursor);

    QGraphicsView::mouseReleaseEvent(event);
    m_isMousePressed = false;
    m_cur_view_pos = event->pos();
    m_cur_scene_pos = mapToScene(m_cur_view_pos);
}

void CGraphicsView::mouseDoubleClickEvent(QMouseEvent* e)
{
    m_cur_view_pos = e->pos();
    m_cur_scene_pos = mapToScene(m_cur_view_pos);
}

void CGraphicsView::zoomIn()
{
    zoom(1 + m_zoomDelta);
}

void CGraphicsView::zoomOut()
{
    zoom(1 - m_zoomDelta);
}

void CGraphicsView::zoom(float scaleFactor)
{
    // 防止过小或过大
    qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
    if (factor < 0.01 || factor > 500)
        return;

    scale(scaleFactor, scaleFactor);
    m_scale *= scaleFactor;

}

void CGraphicsView::mTranslate(QPointF delta)
{
    // 根据当前 zoom 缩放平移数
    centerOn(m_startCenterPoint + delta);
}

void CGraphicsView::initShow()
{
    setEnabled(true);
    setMouseTracking(true);
    m_scene->clear();
    m_scene->addPixmap(m_image);
    m_scene->update();
    this->resetTransform();
    this->setSceneRect(m_image.rect());
    this->fitInView(QRect(0, 0, m_image.width(), m_image.height()), Qt::KeepAspectRatio);
}

void CGraphicsView::drawGrid(QPainter* painter, double gridStep)
{
    QRect   windowRect = rect();
    QPointF tl = mapToScene(windowRect.topLeft());
    QPointF br = mapToScene(windowRect.bottomRight());

    double left = qFloor(tl.x() / gridStep - 0.5);
    double right = qFloor(br.x() / gridStep + 1.0);
    double bottom = qFloor(tl.y() / gridStep - 0.5);
    double top = qFloor(br.y() / gridStep + 1.0);

    for (int xi = int(left); xi <= int(right); ++xi)
    {
        QLineF line(xi * gridStep, bottom * gridStep,
            xi * gridStep, top * gridStep);

        painter->drawLine(line);
    }

    for (int yi = int(bottom); yi <= int(top); ++yi)
    {
        QLineF line(left * gridStep, yi * gridStep,
            right * gridStep, yi * gridStep);
        painter->drawLine(line);
    }
}

 

posted on 2025-04-16 10:37  七星落地  阅读(69)  评论(0)    收藏  举报