現在、QAnimation フレームワークの助けを借りて、Qt でスライドショー ビューアを構築しようとしています。移動中にスライドショーで写真のサイズを変更すると、その軌跡に影響を与えるように見えるため、同時に移動しながら写真のサイズを変更するのに問題があります。
具体的には、一連の写真をアニメーション化して、ウィンドウの水平中心線を横切って右から左に連続的に移動させながら、同時にサイズを変更しようとしています。基本的には、一種の「魚眼」効果で、ウィンドウの中心に向かって移動すると写真が大きくなり、遠ざかるにつれて元のサイズに戻ります。
任意の時点で、ウィンドウには 3 枚の写真のみが表示されます (さらに左側のウィンドウから出てくる 1 枚の写真)。左から右に並べられた 3 つの写真に、P1、P2、P3 というラベルが付いているとします。1 枚の写真、一番右の写真 P3 を考えてみましょう。P3 がウィンドウの右側から中央に向かって移動するにつれて、そのサイズは徐々に大きくなり、ウィンドウの中央で最大サイズに達するはずです。左に向かって移動し続け、最終的にウィンドウを終了すると、サイズは元の値に戻ります。
サイズを変更せずに写真を移動するだけの場合、現在の実装は機能します。画像の移動とスケーリングを同時に行うと、写真がウィンドウの中央を横切って水平方向に移動しなくなりました。写真のサイズは正しくスケーリングされているように見えます。
私の現在の実装は、QPropertyAnimation クラスに依存してアニメーションを実行します。Python と Qt の PySide バインディングを使用してプログラムを作成していますが、C++ または PyQt コードでのソリューションは問題ありません。それらを Python と PySide に翻訳するだけです。
関連するコードは次のとおりです。
def animate(self, items):
'''@params: items The photos to animate'''
logging.debug('Creating %d animation objects', len(items))
self.animationGroup.clear()
for i, item in enumerate(items):
self.animatePosition(item, i, len(items))
self.animateScale(item, i)
QTimer.singleShot(START_DELAY, self.animationGroup.start)
def animatePosition(self, item, index, numItems):
isLastItem = (index == numItems - 1)
isFirstItem = (index == 0)
posAnimation = QPropertyAnimation(item, 'position')
posAnimation.setDuration(SLIDE_INTERVAL)
posAnimation.setStartValue(item.pos())
# I've tried changing dh depending on the scale of the current image with limited success.
dh = 0
if isLastItem:
posAnimation.setEndValue(item.pos() - QPointF(slideshow.RIGHT_MARGIN + slideshow.STANDARD_SLIDE_WIDTH, dh))
elif isFirstItem:
posAnimation.setEndValue(item.pos() - QPointF(slideshow.LEFT_MARGIN + slideshow.STANDARD_SLIDE_WIDTH, dh))
else:
posAnimation.setEndValue(item.pos() - QPointF(slideshow.IMAGE_GAP + slideshow.STANDARD_SLIDE_WIDTH, dh))
posAnimation.setEasingCurve(QEasingCurve.OutExpo)
self.animationGroup.addAnimation(posAnimation)
def animateScale(self, item, index):
if self.animatedView is not None:
scaleAnimation = QPropertyAnimation(item, 'slideScale')
scaleAnimation.setDuration(SLIDE_INTERVAL)
scaleAnimation.setStartValue(item.scale())
endScale = self.getSlideScale(index - 1)
scaleAnimation.setEndValue(endScale)
scaleAnimation.setEasingCurve(QEasingCurve.OutExpo)
self.animationGroup.addAnimation(scaleAnimation)
通常、スケーリング変換を適用する前に写真を原点に戻してから、軌道上の次の位置に戻す必要があることを私は知っています。写真のスケーリングのための QPropertyAnimation が翻訳された写真に適用されているため、その軌跡に影響を与えていると思われますが、Qt を使い始めてまだ 1 ~ 2 週間なので、間違っている可能性があります。
別のアニメーションが行われていることを QPropertyAnimation に認識させる方法を知っている人はいますか? または、上記の問題を解決するための別のアプローチ (必ずしも QPropertyAnimation を含む必要はありません) を誰かが提案できますか?
返信ありがとうございます。