Qt 6.11 is out! See what's new in the release
blog
QGraphicsItem Scroll to Scale Unexpected Behavior
-
I'm making a custom
QGraphicsItemclass which allows the user to resize it by scrolling. To do this, I override the class'swheelEventmethod and change the item's scale by the scroll delta. I also set the scale origin to be at the mouse position so that the item is always under the mouse as the user scrolls.This works only some of the time. There is often jumping due to the scale origin not being correctly set. The scale origin is set using the mouse's position from the
QWheelEvent. Is there a more reliable way to implement this functionality?Here's the full example:
#!/usr/bin/env python3 import sys from PyQt5 import QtWidgets, QtGui class DragAndScaleGraphicsItem(QtWidgets.QGraphicsRectItem): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setFlags(QtWidgets.QGraphicsItem.ItemIsMovable) self.setAcceptHoverEvents(True) self._scale = 1.0 self._minimum_scale = 0.1 self._maximum_scale = 4.0 def wheelEvent(self, ev): steps = ev.delta() / 8.0 / 15.0 if steps == 0: return self._scale = min(self._maximum_scale, max(self._minimum_scale, self._scale + steps)) xform = QtGui.QTransform() dx = ev.pos().x() dy = ev.pos().y() xform\ .translate(dx, dy)\ .scale(self._scale, self._scale)\ .translate(-dx, -dy) self.setTransform(xform) def main(args): app = QtWidgets.QApplication(args) window = QtWidgets.QMainWindow() window.resize(800, 600) window.setFocus() window.show() scene = QtWidgets.QGraphicsScene() view = QtWidgets.QGraphicsView(scene) window.setCentralWidget(view) item = DragAndScaleGraphicsItem(0, 0, 100, 200) item.setX(0) item.setY(0) item.setScale(1) view.scene().addItem(item) sys.exit(app.exec_()) if __name__ == '__main__': main(sys.argv)