Ashika Umanga Umagiliya
Ashika Umanga Umagiliya

Reputation: 9178

Zooming in/out on a mouser point ?

As seen in the pictures. alt text

alt text

I have QWidget inside a QScrollArea. QWidget act as a render widget for cell image and some vector based contour data. User can performe zoom in/out and what simply happens is, it changes the QPainters scale and change the size of QWidget size accordinly.

Now I want to perform the zooming in/out on the point under the mouse. (like zooming action in GIMP). How to calculate the new positions of the scrollbars according to the zoom level ? Is it better to implement this using transformations without using a scrollarea?

Upvotes: 3

Views: 4190

Answers (3)

bkausbk
bkausbk

Reputation: 2790

One solution could be to derive a new class from QScrollArea and reimplementing wheelEvent for example so that zooming is performed with the mouse wheel and at the current mouse cursor position.

This method works by adjusting scroll bar positions accordingly to reflect the new zoom level. This means as long as there is no visible scroll bar, zooming does not take place under mouse cursor position. This is the behavior of most image viewer applications.

void wheelEvent(QWheelEvent* e) {
    double OldScale = ... // Get old scale factor
    double NewScale = ... // Set new scale, use QWheelEvent...

    QPointF ScrollbarPos = QPointF(horizontalScrollBar()->value(), verticalScrollBar()->value());
    QPointF DeltaToPos = e->posF() / OldScale - widget()->pos() / OldScale;
    QPointF Delta = DeltaToPos * NewScale - DeltaToPos * OldScale;

    widget()->resize(/* Resize according to new scale factor */);

    horizontalScrollBar()->setValue(ScrollbarPos.x() + Delta.x());
    verticalScrollBar()->setValue(ScrollbarPos.y() + Delta.y());
}

Upvotes: 5

neydroydrec
neydroydrec

Reputation: 7323

You need to pick up the wheelEvent() on the QWidget, get the event.pos() and pass it into the QscrollArea.ensureVisible(), right after scaling your QWidget.

def wheelEvent(self, event):
    self.setFixedSize(newWidth, newHeight)
    self.parent().ensureVisible(event.pos())

That should more or less produce what you want.

Upvotes: 0

Arnold Spence
Arnold Spence

Reputation: 22292

Will void QScrollArea::ensureVisible(int x, int y, int xmargin = 50, int ymargin = 50) do what you need?

Upvotes: 0

Related Questions