В настоящее время масштабирование выход сразу после увеличения масштаба работает как положено: изображение возвращается в исходное положение. Однако когда я увеличиваю масштаб, перемещаю изображение в другое положение, а затем уменьшаю его, изображение не возвращается в исходное центральное положение.
Демонстрационное видео:
https ://i.imgur.com/xgt9V2H.gif
Демонстрационный GIF:

Черная область — это фон вида, она не должна быть видна.Мне нужна помощь с расчетами, необходимыми для правильного изменения положения изображения при уменьшении масштаба, особенно в этой части кода: if (коэффициент < 1,0) // Уменьшение масштаба { ... .
Минимальный воспроизводимый пример:
#include
#include
#include
#include
class ZoomGraphicsView : public QGraphicsView
{
Q_OBJECT
public:
ZoomGraphicsView()
{
scene = new QGraphicsScene(this);
setScene(scene);
// Basic setup - explicitly disable scrollbars
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setRenderHint(QPainter::SmoothPixmapTransform);
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
setFrameShape(QFrame::NoFrame);
setTransformationAnchor(QGraphicsView::NoAnchor);
setResizeAnchor(QGraphicsView::NoAnchor);
setBackgroundBrush(Qt::black);
setAlignment(Qt::AlignCenter);
setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing);
// Initialize pixmap item
pixmapItem = new QGraphicsPixmapItem();
scene->addItem(pixmapItem);
// Initialize base scale
baseScale = 1.0;
currentScale = 1.0;
isZooming = false;
}
void setImage(const QImage& image)
{
QPixmap newPixmap = QPixmap::fromImage(image);
if (newPixmap.isNull())
return;
// Update pixmap
pixmapItem->setPixmap(newPixmap);
if (firstImage)
{
resetView();
firstImage = false;
}
// Update scene rect to match the viewport
scene->setSceneRect(viewport()->rect());
}
protected:
void wheelEvent(QWheelEvent* event) override
{
if (pixmapItem->pixmap().isNull())
return;
isZooming = true;
// Store cursor position relative to scene
QPointF mousePosScene = mapToScene(event->position().toPoint());
QPointF mousePosCurrent = event->position();
// Calculate zoom factor
double factor = pow(1.5, event->angleDelta().y() / 240.0);
double newScale = currentScale * factor;
// Handle zoom out specifically
if (factor < 1.0) // Zooming out
{
if (newScale < baseScale)
{
resetView();
isZooming = false;
event->accept();
return;
}
// 1. Get the current positions before any transformation
QRectF viewRect = viewport()->rect();
QPointF mousePos = event->position();
QPointF mousePosScene = mapToScene(mousePos.toPoint());
// 2. Calculate the view center and the distance from mouse to center
QPointF viewCenter = mapToScene(viewRect.center().x(), viewRect.center().y());
QPointF mouseOffset = mousePosScene - viewCenter;
// 3. Apply the new scale
QTransform newTransform;
newTransform.scale(newScale, newScale);
setTransform(newTransform);
// 4. Calculate how much the mouse point moved after scaling
QPointF newMousePosScene = mapToScene(mousePos.toPoint());
QPointF deltaPos = newMousePosScene - mousePosScene;
// 5. Adjust the view to maintain the mouse position
translate(deltaPos.x(), deltaPos.y());
// 6. Calculate the scaled image bounds
QRectF imageRect = pixmapItem->boundingRect();
QRectF scaledImageRect = QRectF(imageRect.topLeft() * newScale, imageRect.size() * newScale);
// 7. Ensure the view stays within bounds
QPointF currentCenter = mapToScene(viewRect.center().x(), viewRect.center().y());
QPointF newCenter = currentCenter;
// 8. Apply bounds to keep image filling the view
if (scaledImageRect.width() < viewRect.width())
newCenter.setX(scaledImageRect.center().x());
else
{
qreal minX = viewRect.width() / 2.0;
qreal maxX = scaledImageRect.width() - minX;
newCenter.setX(qBound(minX, currentCenter.x(), maxX));
}
if (scaledImageRect.height() < viewRect.height())
newCenter.setY(scaledImageRect.center().y());
else
{
qreal minY = viewRect.height() / 2.0;
qreal maxY = scaledImageRect.height() - minY;
newCenter.setY(qBound(minY, currentCenter.y(), maxY));
}
// 9. Update to the bounded position
centerOn(newCenter);
currentScale = newScale;
qDebug()
Подробнее здесь: https://stackoverflow.com/questions/791 ... er-zooming