I made a stupid thing. But it was fun and I learned some stuff about QPropertyAnimations along the way.

dodgeButton_v004.gif

  • Here’s the code

    import sys
    from random import randint
    try:
        from PySide import QtCore, QtGui, QtGui as QtWidgets
    except:
        from PySide2 import QtCore, QtGui, QtWidgets
    
    class DodgeButton(QtWidgets.QPushButton):
        def __init__(self, parent=None):
            super(DodgeButton, self).__init__(parent=parent)
    
            # PROPERTIES
            self.origSize = [self.size().width(), self.size().height()]
            self.aniSpeed = 120
            self.aniPosition = QtCore.QPropertyAnimation(self, b"pos")
            self.aniPosition.setDuration(self.aniSpeed)
            self.aniScale = QtCore.QPropertyAnimation(self, b"size")
            self.aniScale.setDuration(self.aniSpeed)
    
            # EVENTS
            self.clicked.connect(self.win)
    
            # INIT
            xPos = parent.width()/2-self.width()/2
            yPos = parent.height()/2-self.height()/2
            self.move(xPos, yPos)
    
        def win(self):
            print("ALRIGHTY!")
    
        def enterEvent(self, event):
            self.randomScale()
            self.randomMove()
    
        def randomMove(self):
            """
            move to a random position
            """
            randX = randint(0+self.width(), self.parent().width()-self.width())
            randY = randint(0+self.height(), self.parent().height()-self.height())
            # Move
            self.aniPosition.setStartValue(self.pos())
            self.aniPosition.setEndValue(QtCore.QPoint(randX, randY))
            self.aniPosition.start()
    
        def randomScale(self):
            """
            scale to random size
            """
            randMult = float(randint(50,200))/100.0
    
            # Scale
            self.aniScale.setStartValue(self.size())
            newSize = scalePropo([self.origSize[0], self.origSize[1]], self.origSize[0]*randMult)
            sizeX = newSize[0]
            sizeY = newSize[1]
            self.aniScale.setEndValue(QtCore.QSize(sizeX, sizeY))
            self.aniScale.start()
    
    class MainWindow(QtWidgets.QDialog):
        def __init__(self, buttonName="Analyze", parent=None):
            super(MainWindow, self).__init__(parent)
            layout = QtWidgets.QVBoxLayout()
            self.setLayout(layout)
            self.setFixedSize(500, 500)
    
            # INIT
            self.button = DodgeButton(self)
            self.button.setText(buttonName)
    
    def scalePropo(oldSize=None,newWidth=None):
        '''
        Scales an input size proportionally to the new desired width.
        :param oldsize : : The current size [x,y]
        :param newsize : : The new desired width
        '''
        oldWidth = float(oldSize[0])
        oldHeight = float(oldSize[1])
        newHeight = (oldHeight/oldWidth)*float(newWidth)
        newSize = [newWidth,newHeight]
        return newSize
    
    def setup():
        app = QtWidgets.QApplication(sys.argv)
        win1 = MainWindow("Analyze")
        win2 = MainWindow("Are you sure?")
        win3 = MainWindow("Are you really sure?")
    
        win1.button.clicked.connect(win2.exec_)
        win2.button.clicked.connect(win3.exec_)
        win1.exec_()
    
        # app.exec_()
        sys.exit(0)
    
    if __name__ == '__main__':
        setup()