Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PyQt5动画行为作为类属性_Python_Python 3.x_Pyqt_Pyqt5 - Fatal编程技术网

Python PyQt5动画行为作为类属性

Python PyQt5动画行为作为类属性,python,python-3.x,pyqt,pyqt5,Python,Python 3.x,Pyqt,Pyqt5,我用python和pyqt5制作了一个小游戏,pyqt5是一个可以用箭头键移动的移动框,但动画只有在定义为类属性时才起作用 代码如下: class Game(QMainWindow): # some code def move(self, direction): animation = QPropertyAnimation(self.box, b'geometry') x, y = self.box.x(),

我用python和pyqt5制作了一个小游戏,pyqt5是一个可以用箭头键移动的移动框,但动画只有在定义为类属性时才起作用

代码如下:

    class Game(QMainWindow):
        # some code
        def move(self, direction):
            animation = QPropertyAnimation(self.box, b'geometry')
            x, y = self.box.x(), self.box.y()
            if(direction=='right'):
                x+=10
            # directions left, up and down
            animation.setEndValue(QRect(x, y, 20, 20))
            box.move(x, y)
            animation.setDuration(20)
            animation.start()
            animation.finished.connect(lambda: self.move(direction)
        # capture keypress to move the box
当我用self.animation替换动画时,效果很好。 我使用self.animation没有问题,但我花了一些时间才意识到我的代码不起作用的原因是因为它不是一个属性,为什么动画只在它是一个属性时才起作用?

问题是“animation”是一个局部变量,所以当创建它的函数完成执行时,它将被消除,在您的情况下,当它完成执行“移动”时,即启动动画后的一瞬间

为了理解这一点,我们可以使用以下示例,因为QPropertyAnimation是一个QObject,所以它具有指示QObject何时被销毁的销毁信号

import sys

from PyQt5 import QtCore, QtGui, QtWidgets


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.box = QtWidgets.QPushButton("QPushButton", self)

    def move(self, pos):
        animation = QtCore.QPropertyAnimation(self.box, b"pos")
        animation.setStartValue(self.box.pos())
        animation.setEndValue(pos)
        animation.setDuration(20)
        animation.start()
        animation.destroyed.connect(lambda obj: print("destroyed", obj))


if __name__ == "__main__":

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    w.move(QtCore.QPoint(40, 40))
    sys.exit(app.exec_())
输出:

destroyed <PyQt5.QtCore.QObject object at 0x7f412abffd70>
已销毁

因此,通常的解决方案是,至少在动画结束之前,它不会被消除,为此,有几个选项:

  • 使它成为类的一个属性,因为它与类具有相同的生命周期,这就是您使用的方法

  • 由于QPropertyAnimation是QObject,因此延长生命周期的一种方法是将其传递给父对象,但在这种情况下,最好在动画完成后立即销毁它:

  • def移动(自身,方向):
    动画=QPropertyAnimation(self.box,b'geometry',父对象=self)
    # ...
    animation.start(QPropertyAnimation.DeleteWhen停止)
    animation.finished.connect(lambda:self.move(direction))
    问题在于“animation”是一个局部变量,因此当创建它的函数完成执行时,它将被消除,在您的情况下,当它完成执行“move”时,即启动动画后的一瞬间

    为了理解这一点,我们可以使用以下示例,因为QPropertyAnimation是一个QObject,所以它具有指示QObject何时被销毁的销毁信号

    import sys
    
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super().__init__(parent)
    
            self.box = QtWidgets.QPushButton("QPushButton", self)
    
        def move(self, pos):
            animation = QtCore.QPropertyAnimation(self.box, b"pos")
            animation.setStartValue(self.box.pos())
            animation.setEndValue(pos)
            animation.setDuration(20)
            animation.start()
            animation.destroyed.connect(lambda obj: print("destroyed", obj))
    
    
    if __name__ == "__main__":
    
        app = QtWidgets.QApplication(sys.argv)
        w = MainWindow()
        w.show()
        w.move(QtCore.QPoint(40, 40))
        sys.exit(app.exec_())
    
    输出:

    destroyed <PyQt5.QtCore.QObject object at 0x7f412abffd70>
    
    已销毁
    

    因此,通常的解决方案是,至少在动画结束之前,它不会被消除,为此,有几个选项:

  • 使它成为类的一个属性,因为它与类具有相同的生命周期,这就是您使用的方法

  • 由于QPropertyAnimation是QObject,因此延长生命周期的一种方法是将其传递给父对象,但在这种情况下,最好在动画完成后立即销毁它:

  • def移动(自身,方向):
    动画=QPropertyAnimation(self.box,b'geometry',父对象=self)
    # ...
    animation.start(QPropertyAnimation.DeleteWhen停止)
    动画.finished.connect(lambda:self.move(direction))