PyQt5 QtWidgets.QGraphicsViewのスムーズなズーム

スムーズなズームのためにQtWidgets.QGraphicsViewを継承した独自のクラスGraphicsViewを作成します。

class GraphicsView(QtWidgets.QGraphicsView):
    def __init__(self, *argv, **keywords):
        super(GraphicsView, self).__init__(*argv, **keywords)

GraphicsViewクラス内でwheelEventをオーバーライドしてscalingTimeとanimFinishedのメソッドを、wikiを参考にして作成します。

ソースコードは下記の通りです。



ソースコード

# -*- coding: utf-8 -*-
import sys
from PyQt5 import QtWidgets, QtCore, QtGui

class GraphicsView(QtWidgets.QGraphicsView):
    def __init__(self, *argv, **keywords):
        super(GraphicsView, self).__init__(*argv, **keywords)
        
        scene = QtWidgets.QGraphicsScene(self)
        image = QtGui.QImage('test.png')
        pixmap = QtGui.QPixmap.fromImage(image)
        scene.addPixmap(pixmap)
        self.setScene(scene)

        self._numScheduledScalings = 0

    def wheelEvent(self, event):
        numDegrees = event.angleDelta().y() / 8
        numSteps = numDegrees / 15
        self._numScheduledScalings += numSteps
        if self._numScheduledScalings * numSteps < 0:
            self._numScheduledScalings = numSteps
        anim = QtCore.QTimeLine(350, self)
        anim.setUpdateInterval(20)
        anim.valueChanged.connect(self.scalingTime)
        anim.finished.connect(self.animFinished)
        anim.start()

    def scalingTime(self, x):
        factor = 1.0 + float(self._numScheduledScalings) / 300.0
        self.scale(factor, factor)

    def animFinished(self):
        if self._numScheduledScalings > 0:
            self._numScheduledScalings -= 1
        else:
            self._numScheduledScalings += 1

def main():
    app = QtWidgets.QApplication(sys.argv)
    graphics_view = GraphicsView(None)
    graphics_view.show()
    app.exec()
 
if __name__ == '__main__':
    main()

コメント

タイトルとURLをコピーしました