Я строю виджет зрителя изображений с возможностями масштабирования и масштабирования, включая поддержку панорамирования (Click-Drag для перемещения изображения вокруг). < /p>
В настоящее время увеличение Выйти сразу после увеличения работ, как и ожидалось, с изображением возвращается в ее исходную позицию. Однако, когда я увеличиваю масштаб, поднимите изображение в другую позицию, а затем увеличивает масштаб, изображение не возвращается к своему исходному центру. : //i.imgur.com/xgt9v2h.gif
Demancation Gif:
< /p>
Черная область - это фон просмотра, она не должна быть видно. < /p>
Я ищу помощь с вычислениями, необходимыми для правильной перемещения изображения при увеличении, особенно в этой части кода: if (фактор
#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
Как я могу сделать изображение вернуться в свое исходное центрированное положение после увеличения, панорамирования, а з ⇐ C++
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение