PyQt5: Как удалить виджет после того, как видео закончится, и поставить картинку на место видеоплеера - PullRequest
1 голос
/ 03 ноября 2019

Я новичок в Pyqt5. Я разработал пользовательский интерфейс с использованием конструктора Pyqt5, в котором есть QmainWindow, внутри которого я разместил QWidget. В QWidget я поместил QHBoxlayout, который содержит QFrame. Этот QFrame я использовал, чтобы содержать QVideoWidget. QVideoWidget используется для воспроизведения видеофайла. То, что я пытаюсь достичь, это 1.) Приостановить видео, когда оно достигает последнего кадра видео во время воспроизведения. Или 1.) Как только видео закончится, я заменяю плеер изображением в том же кадре, которое использовалось для удержания видеоплеера.

Чтобы добиться вышеописанного, я написал следующий код -

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'video_1.ui'
#
# Created by: PyQt5 UI code generator 5.13.1
#
# WARNING! All changes made in this file will be lost!



from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication, QPushButton, QSizePolicy
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
import sys
import time
import sip


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1119, 891)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth())
        self.centralwidget.setSizePolicy(sizePolicy)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(400, 10, 711, 841))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.frame = QtWidgets.QFrame(self.horizontalLayoutWidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
        self.frame.setSizePolicy(sizePolicy)
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.widget_2 = QVideoWidget(self.frame)
        self.widget_2.setGeometry(QtCore.QRect(20, 40, 681, 771))
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widget_2.sizePolicy().hasHeightForWidth())
        self.widget_2.setSizePolicy(sizePolicy)
        self.widget_2.setObjectName("widget_2")
        self.horizontalLayout.addWidget(self.frame)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1119, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

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

    def run(self, fileName):
        self.player = QMediaPlayer()
        self.player.setVideoOutput(self.widget_2)
        self.player.setMedia(QMediaContent(QUrl.fromLocalFile(fileName)))
        self.player.play()

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.run("/home/shantanu/UI/intro.mp4")




if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Что я подумал, если смогу узнать общую продолжительность видео, прежде чем оно начнет воспроизводиться, используяКомбинация цикла while и if позволяет приостановить видео, когда оно достигнет общей продолжительности. Код для этого был -

def run(self, fileName):
    self.player = QMediaPlayer()
    self.player.setVideoOutput(self.widget_2)
    self.player.setMedia(QMediaContent(QUrl.fromLocalFile(fileName)))

    from moviepy.editor import VideoFileClip
    clip = VideoFileClip("/home/shantanu/UI/intro.mp4")
    print( int(clip.duration) )

    # Assume the clip = 6

    i = 0
    while i < 6:
        self.player.play()
        i = i+1
        if i == 5 :
            self.video.pause()

Но вышеуказанный подход не сработал. Потому что, как только я запускаю файл, все выполняется, и я не могу достичь того, что хотел.

Код работает без ошибок, но я не могу получить то, что пытаюсь получить.

Я пытался использовать функцию deleteLater (), предоставляемую Pyqt5, но это также не сработало. Ниже представлен лучший способ, который можно сделать, но я не могу этого сделать. Я прошел через аналогичные вопросы по Stackoveflow, но не смог достичь желаемых результатов.

Может кто-нибудь подсказать мне, как использовать удаленный виджет после его использования, а затем заменить его на изображение.

1 Ответ

1 голос
/ 03 ноября 2019

[signal] void QMediaPlayer :: mediaStatusChanged (QMediaPlayer :: MediaStatus status)

Сигнализирует об изменении статуса текущего носителя.

Примечание. Сигнал уведомителя для свойства mediaStatus.

См. Также mediaStatus ().

import sys
import time
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication, QPushButton, QSizePolicy
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
#import sip


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1119, 891)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth())
        self.centralwidget.setSizePolicy(sizePolicy)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(400, 10, 711, 841))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")

        self.frame = QtWidgets.QFrame(self.horizontalLayoutWidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
        self.frame.setSizePolicy(sizePolicy)
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.widget_2 = QVideoWidget(self.frame)
        self.widget_2.setGeometry(QtCore.QRect(20, 40, 381, 371))  # 20, 40, 681, 771
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widget_2.sizePolicy().hasHeightForWidth())
        self.widget_2.setSizePolicy(sizePolicy)
        self.widget_2.setObjectName("widget_2")

        self.horizontalLayout.addWidget(self.frame)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1119, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

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

    def run(self, fileName):
        self.player = QMediaPlayer()
        self.player.setVideoOutput(self.widget_2)
        self.player.setMedia(QMediaContent(QUrl.fromLocalFile(fileName)))

        self.player.mediaStatusChanged.connect(self.media_status)         # <---

        self.player.play()

    def media_status(self, status):                                       # <---
        if status == 7:
            print("The End!")
            self.label = QtWidgets.QLabel("The End!", self.centralwidget, 
                                          alignment=QtCore.Qt.AlignCenter)
            self.label.setStyleSheet("""
                QLabel { 
                    background-color : blue; 
                    color : #fff; 
                    font-weight: bold;
                    font-size: 32px;
                }
            """)
            self.label.setGeometry(QtCore.QRect(420, 50, 381, 371))
            self.label.show()

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.run("D:/_Qt/Python-Examples/_PyQt5/Test/video5.avi")


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

enter image description here

...