245 lines
5.9 KiB
C++
245 lines
5.9 KiB
C++
#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;
|
||
}
|