Как сделать бесконечную анимацию на фон приложения?

Есть текст, кнопки и фон окна приложения.
Нужно заставить фон постоянно спускаться вниз (бесконечно).

Идея: вставлять каждый раз один и тот же .png, который опускается вниз и исчезает за окном, снова появляется сверху пока ещё не уехал тот, чтоб не было дырок.

Проблема такая: как заставить эту анимацию крутиться бесконечно и при этом вывести всё.

main.py:

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow
from project import Ui_project
import ctypes


myappid = 'mycompany.myproduct.subproduct.version'
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)

app = QApplication(sys.argv)
window = QMainWindow()
ui = Ui_project()
ui.setupUi(window)
window.showFullScreen()
sys.exit(app.exec())

project.py:

from PyQt6 import QtCore
from PyQt6.QtGui import QIcon, QPixmap
from PyQt6.QtWidgets import QWidget, QLabel, QPushButton
from PyQt6.QtCore import QPropertyAnimation, QPoint


class Ui_project(object):
    def setupUi(self, project_):
        project_.setObjectName("Project")
        project_.resize(1920, 1080)
        project_.setMinimumSize(QtCore.QSize(1920, 1080))
        project_.setMaximumSize(QtCore.QSize(1920, 1080))
        icon = QIcon()
        icon.addPixmap(QPixmap("design/icon.png"), QIcon.Mode.Normal, QIcon.State.Off)
        project_.setWindowIcon(icon)
        project_.setAutoFillBackground(False)
        project_.setStyleSheet("")
        project_.setIconSize(QtCore.QSize(32, 32))

        self.centralwidget = QWidget(parent=project_)
        self.centralwidget.setAutoFillBackground(False)
        self.centralwidget.setStyleSheet("")
        self.centralwidget.setObjectName("centralwidget")

        self.Project_label = QLabel(parent=self.centralwidget)
        self.Project_label.setGeometry(QtCore.QRect(607, 124, 734, 422))
        self.Project_label.setText("")
        self.Project_label.setPixmap(QPixmap("design/Project_main_menu.png"))
        self.Project_label.setObjectName("Project_label")

        self.start_button = QPushButton(parent=self.centralwidget)
        self.start_button.setGeometry(QtCore.QRect(580, 618, 760, 121))
        self.start_button.setText("")
        icon1 = QIcon()
        icon1.addPixmap(QPixmap("design/start.png"), QIcon.Mode.Normal, QIcon.State.Off)
        self.start_button.setIcon(icon1)
        self.start_button.setIconSize(QtCore.QSize(760, 121))
        self.start_button.setObjectName("start_button")

        self.settings_button = QPushButton(parent=self.centralwidget)
        self.settings_button.setGeometry(QtCore.QRect(580, 790, 360, 121))
        self.settings_button.setText("")
        icon2 = QIcon()
        icon2.addPixmap(QPixmap("design/settings.png"), QIcon.Mode.Normal, QIcon.State.Off)
        self.settings_button.setIcon(icon2)
        self.settings_button.setIconSize(QtCore.QSize(360, 121))
        self.settings_button.setObjectName("settings_button")

        self.quit_button = QPushButton(parent=self.centralwidget)
        self.quit_button.setGeometry(QtCore.QRect(980, 790, 360, 121))
        self.quit_button.setText("")
        icon3 = QIcon()
        icon3.addPixmap(QPixmap("design/quit.png"), QIcon.Mode.Normal, QIcon.State.Off)
        self.quit_button.setIcon(icon3)
        self.quit_button.setIconSize(QtCore.QSize(360, 121))
        self.quit_button.setObjectName("quit_button")

        self.background_1_main_menu = QLabel(parent=self.centralwidget)
        self.background_1_main_menu.setPixmap(QPixmap("design/background_1.png"))
        self.background_1_main_menu.setGeometry(QtCore.QRect(0, -1100, 1920, 2200))

        self.anim_bg_1_mm = QPropertyAnimation(self.background_1_main_menu, b"pos")
        self.anim_bg_1_mm.setEndValue(QPoint(0, 1100))
        self.anim_bg_1_mm.setDuration(9500)
        self.anim_bg_1_mm.start()

        self.background_1_main_menu.raise_()
        self.Project_label.raise_()
        self.start_button.raise_()
        self.settings_button.raise_()
        self.quit_button.raise_()
        project_.setCentralWidget(self.centralwidget)

        self.retranslateUi(project_)
        QtCore.QMetaObject.connectSlotsByName(project_)

    def retranslateUi(self, project_):
        _translate = QtCore.QCoreApplication.translate
        project_.setWindowTitle(_translate("project_", "Project"))```

Ответы (2 шт):

Автор решения: S. Nick

Наверное, самый простой возможный вариант,
это объединить/соединить несколько PNG в один PNG.

Вот я объединил три, примерно похожих изображений, в одно newcat2.png

Замените импорты и изображения на свои и попробуйте.

И еще, НИКОГДА НЕ ИЗМЕНЯЙТЕ код, сгенерированный Qt Designer, НИКОГДА.
Создайте другой класс, который наследуется от соответствующего виджета, и используйте созданный класс для его заполнения.

import sys
'''
from PyQt6.QtWidgets import QApplication, QMainWindow
'''
from PyQt5 import QtCore
from PyQt5.Qt import *

#from project import Ui_project
class Ui_project(object):
    def setupUi(self, project_):
        project_.setObjectName("Project")
        project_.resize(1200, 620)                                   # 1920, 1080
#        project_.setMinimumSize(QtCore.QSize(1920, 1080))
#        project_.setMaximumSize(QtCore.QSize(1920, 1080))
        icon = QIcon()
        icon.addPixmap(QPixmap("Ok.png"), 
            QIcon.Mode.Normal, QIcon.State.Off)
        project_.setWindowIcon(icon)
        project_.setAutoFillBackground(False)
        project_.setStyleSheet("")
        project_.setIconSize(QtCore.QSize(32, 32))

        self.centralwidget = QWidget(parent=project_)
        self.centralwidget.setAutoFillBackground(False)
        self.centralwidget.setStyleSheet("")
        self.centralwidget.setObjectName("centralwidget")

        self.Project_label = QLabel(parent=self.centralwidget)
        self.Project_label.setGeometry(QtCore.QRect(607, 124, 734, 422))
        self.Project_label.setText("Project_label")
        self.Project_label.setPixmap(QPixmap("lena3.png"))
        self.Project_label.setObjectName("Project_label")
        self.Project_label.setStyleSheet('background-color: #D98C00;')

        self.start_button = QPushButton(parent=self.centralwidget)
        self.start_button.setGeometry(QtCore.QRect(580, 618, 760, 121))
        self.start_button.setText("Start_button")
        icon1 = QIcon()
        icon1.addPixmap(QPixmap("boy.jpg"), 
            QIcon.Mode.Normal, QIcon.State.Off)
        self.start_button.setIcon(icon1)
        self.start_button.setIconSize(QtCore.QSize(760, 121))
        self.start_button.setObjectName("start_button")

        self.settings_button = QPushButton(parent=self.centralwidget)
#        self.settings_button.setGeometry(QtCore.QRect(580, 790, 360, 121))
# у меня просто маленький экран и я не вижу виджеты с такой геометрией 
        self.settings_button.setGeometry(QtCore.QRect(5, 7, 360, 121))
        
        self.settings_button.setText("settings_button")
        icon2 = QIcon()
        icon2.addPixmap(QPixmap("im.png"), QIcon.Mode.Normal, QIcon.State.Off)
        self.settings_button.setIcon(icon2)
        self.settings_button.setIconSize(QtCore.QSize(360, 121))
        self.settings_button.setObjectName("settings_button")

        self.quit_button = QPushButton(parent=self.centralwidget)
#        self.quit_button.setGeometry(QtCore.QRect(980, 790, 360, 121))
        self.quit_button.setGeometry(QtCore.QRect(9, 190, 360, 121))
        
        self.quit_button.setText("quit_button")
        icon3 = QIcon()
        icon3.addPixmap(QPixmap("quit.png"), QIcon.Mode.Normal, QIcon.State.Off)
        self.quit_button.setIcon(icon3)
        self.quit_button.setIconSize(QtCore.QSize(360, 121))
        self.quit_button.setObjectName("quit_button")

        self.background_1_main_menu = QLabel(parent=self.centralwidget)
        self.background_1_main_menu.setPixmap(
            QPixmap("newcat.png").scaled(1200, 620 * 3))
        
#        self.background_1_main_menu.setGeometry(QtCore.QRect(0, -1100, 1920, 2200))
#        self.anim_bg_1_mm = QPropertyAnimation(self.background_1_main_menu, b"pos")
#        self.anim_bg_1_mm.setEndValue(QPoint(0, 1100))
#        self.anim_bg_1_mm.setDuration(9500)
#        self.anim_bg_1_mm.start()

        self.background_1_main_menu.raise_()
        self.Project_label.raise_()
        self.start_button.raise_()
        self.settings_button.raise_()
        self.quit_button.raise_()
        project_.setCentralWidget(self.centralwidget)

        self.retranslateUi(project_)
        QtCore.QMetaObject.connectSlotsByName(project_)

    def retranslateUi(self, project_):
        _translate = QtCore.QCoreApplication.translate
        project_.setWindowTitle(_translate("project_", "Project"))


#?import ctypes
#?myappid = 'mycompany.myproduct.subproduct.version'
#?ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)


class MainWindow(QMainWindow, Ui_project):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)
        
        self.quit_button.clicked.connect(self.close)                  # +
        self.settings_button.clicked.connect(self.anim_bg)            # +

        self.anim_bg_1_mm = QPropertyAnimation(                       
            self.background_1_main_menu, b"pos")                      # +
        self.anim_bg_1_mm.finished.connect(self.anim_bg)              # +

        QTimer.singleShot(10, self.anim_bg)                           # +
        
    def anim_bg(self):
# -------------------------------------------> v  v              v v <---- !!!   
        self.anim_bg_1_mm.setStartValue(QPoint(0, -self.height() * 2))     # +
        
        self.anim_bg_1_mm.setEndValue(QPoint(0, 0))    # (0, 1100) 
        self.anim_bg_1_mm.setDuration(9500)             
        self.anim_bg_1_mm.start()
        
    def resizeEvent(self, event):
        pixmap = QPixmap("newcat2.png").scaled(
            self.width(), self.height() * 3)
        self.background_1_main_menu.setPixmap(pixmap)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.resize(1200, 620)
#    window.show()
    window.showFullScreen()
    sys.exit(app.exec())    

введите сюда описание изображения



newcat2.png

введите сюда описание изображения

→ Ссылка
Автор решения: Vi Ctor

.setLoopCount(-2) - бесконечное повторение; (1) - повторяет 1 раз

→ Ссылка