Files
HPPA/HPPA/ImageViewer.cpp
tangchao0503 af88a6a67e 1、优化QGraphicsView交互逻辑;
2、hdr文件添加byte order = 0;
2025-09-18 16:19:06 +08:00

245 lines
5.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "stdafx.h"
#include <iostream>
#include <QWheelEvent>
#include <QPoint>
#include "ImageViewer.h"
#define VIEW_CENTER viewport()->rect().center()
#define VIEW_WIDTH viewport()->rect().width()
#define VIEW_HEIGHT viewport()->rect().height()
ImageViewer::ImageViewer(QWidget* pParent) :QGraphicsView(pParent)
{
setRenderHint(QPainter::Antialiasing);
setRenderHint(QPainter::SmoothPixmapTransform);
setDragMode(QGraphicsView::ScrollHandDrag);
// 关键点:不使用 Qt 默认的 anchor而是自己控制
setTransformationAnchor(QGraphicsView::NoAnchor);
setResizeAnchor(QGraphicsView::NoAnchor);
m_qtGraphicsScene = new QGraphicsScene(this);
this->setScene(m_qtGraphicsScene);
m_qtGraphicsScene->setSceneRect(-1e6, -1e6, 2e6, 2e6);
m_framNumberLabel = new QLabel(this);
m_framNumberLabel->setAlignment(Qt::AlignHCenter);
m_framNumberLabel->setAlignment(Qt::AlignVCenter);
QFont ft;
ft.setPointSize(14);
m_framNumberLabel->setFont(ft);
m_framNumberLabel->setText("0");
m_GraphicsPixmapItemHandle = nullptr;
m_scale = 1.0;
m_zoomDelta = 0.1;
m_translateSpeed = 1.0;
m_bMouseTranslate = false;
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setFrameShape(QFrame::NoFrame);
}
ImageViewer::~ImageViewer()
{
}
void ImageViewer::DisplayFrameNumber(int frameNumber)
{
m_framNumberLabel->setText(QString::number(frameNumber));
m_framNumberLabel->adjustSize();
}
void ImageViewer::SetImage(QPixmap *image)
{
if (!HasImage())
{
m_GraphicsPixmapItemHandle = m_qtGraphicsScene->addPixmap(*image);
}
else
{
m_GraphicsPixmapItemHandle->setPixmap(*image);
}
ensureSceneVisible();
}
void ImageViewer::ensureSceneVisible()
{
resetTransform();
auto view_rect = viewport()->rect();
auto scene_rect = this->scene()->itemsBoundingRect();
double x_ratio = view_rect.width() / scene_rect.width();
double y_ratio = view_rect.height() / scene_rect.height();
double scale_factor = std::min(x_ratio, y_ratio) * 0.9;
scale(scale_factor, scale_factor);
m_scale *= scale_factor;
centerOn(scene_rect.center());
}
bool ImageViewer::HasImage()
{
if (m_GraphicsPixmapItemHandle == nullptr)
{
return false;
}
else
{
return true;
}
}
void ImageViewer::wheelEvent(QWheelEvent *event)
{
//qDebug() << "---------------+++++++++++++++++++++++++++++++++++++++++++++++++++ ";
//if (true)//HasImage()
//{
// //围绕鼠标点放大https://blog.csdn.net/GoForwardToStep/article/details/77035287?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param
// // 获取当前鼠标相对于view的位置;
// QPointF cursorPoint = event->pos();
// // 获取当前鼠标相对于scene的位置;
// QPointF scenePos = this->mapToScene(QPoint(cursorPoint.x(), cursorPoint.y()));
// // 获取view的宽高;
// qreal viewWidth = this->viewport()->width();
// qreal viewHeight = this->viewport()->height();
// // 获取当前鼠标位置相当于view大小的横纵比例;
// qreal hScale = cursorPoint.x() / viewWidth;
// qreal vScale = cursorPoint.y() / viewHeight;
// // 滚轮的滚动量
// QPoint scrollAmount = event->angleDelta();
// // 正值表示滚轮远离使用者放大负值表示朝向使用者缩小
// scrollAmount.y() > 0 ? zoomIn() : zoomOut();
// // 将scene坐标转换为放大缩小后的坐标;
// QPointF viewPoint = this->matrix().map(scenePos);
// // 通过滚动条控制view放大缩小后的展示scene的位置;
// horizontalScrollBar()->setValue(int(viewPoint.x() - viewWidth * hScale));
// verticalScrollBar()->setValue(int(viewPoint.y() - viewHeight * vScale));
//}
if (HasImage())
{
QPointF oldPos = mapToScene(event->pos());
QPoint scrollAmount = event->angleDelta();
scrollAmount.y() > 0 ? zoomIn() : zoomOut();
QPointF newPos = mapToScene(event->pos());
QPointF delta = newPos - oldPos;
translate(delta.x(), delta.y());
}
//QGraphicsView::wheelEvent(event);//
}
void ImageViewer::scaling(qreal scaleFactor)
{
//qDebug() << this->sceneRect();
scale(scaleFactor, scaleFactor);
}
void ImageViewer::mousePressEvent(QMouseEvent *event)
{
if (event->button()==Qt::LeftButton)
{
m_bMouseTranslate = true;
m_lastMousePos = event->pos();
//qDebug() << mapToScene(m_lastMousePos);
emit leftMouseButtonPressed(mapToScene(m_lastMousePos).x(), mapToScene(m_lastMousePos).y());
}
//If you do not perform all the necessary work in your implementation of the virtual function, you may need to call the base class's implementation.
QGraphicsView::mousePressEvent(event);
}
void ImageViewer::mouseMoveEvent(QMouseEvent *event)
{
if (m_bMouseTranslate){
QPointF mouseDelta = mapToScene(event->pos()) - mapToScene(m_lastMousePos);
translate(mouseDelta.x(),mouseDelta.y());
}
m_lastMousePos = event->pos();
QGraphicsView::mousePressEvent(event);
}
void ImageViewer::mouseReleaseEvent(QMouseEvent *event)
{
m_bMouseTranslate = false;
QGraphicsView::mouseReleaseEvent(event);
}
void ImageViewer::mouseDoubleClickEvent(QMouseEvent *event)
{
QGraphicsView::mouseDoubleClickEvent(event);
}
void ImageViewer::zoomIn()
{
zoom(1 + m_zoomDelta);
}
void ImageViewer::zoomOut()
{
zoom(1 - m_zoomDelta);
}
void ImageViewer::zoom(float scaleFactor)
{
// 防止过小或过大
qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
if (factor < 0.07 || factor > 100)
return;
scale(scaleFactor, scaleFactor);
m_scale *= scaleFactor;
}
void ImageViewer::setTranslateSpeed(qreal speed)
{
// 建议速度范围
Q_ASSERT_X(speed >= 0.0 && speed <= 2.0,
"InteractiveView::setTranslateSpeed", "Speed should be in range [0.0, 2.0].");
m_translateSpeed = speed;
}
qreal ImageViewer::translateSpeed() const
{
return m_translateSpeed;
}
void ImageViewer::setZoomDelta(qreal delta)
{
// 建议增量范围
Q_ASSERT_X(delta >= 0.0 && delta <= 1.0,
"InteractiveView::setZoomDelta", "Delta should be in range [0.0, 1.0].");
m_zoomDelta = delta;
}
qreal ImageViewer::zoomDelta() const
{
return m_zoomDelta;
}