Python window 视频结束后不关闭

Python window doesn't close after video ended

我目前正在编写一个代码来执行各种操作,例如控制电机等,但有一次我需要编写代码以在 vlc 上弹出视频并在视频结束时退出 window,问题是 window 目前在视频结束后仍然存在,整个代码都冻结了,我无法在视频后做任何事情

我尝试了各种方法,例如计算视频长度,并在计时器响起时调用 self.close(),但还是一样

我也试过在 vlc 参数中添加 "--play-and-exit" 但它仍然不会让步...

如果有人知道如何正确执行,请查看代码!

import PySimpleGUI as sg

import os
import sys
import platform
import time
from time import sleep
from PyQt5.QtCore import (QCoreApplication, QObject, QRunnable, QThread,
                          QThreadPool, pyqtSignal)
from PyQt5 import QtCore, QtGui, QtWidgets
import vlc

class Player(QtWidgets.QMainWindow):

    def __init__(self, master=None):
        QtWidgets.QMainWindow.__init__(self, master)

        self.media_files = [
            "Toxic.mp4",
        ]
        self.current_index = 0
        self.showFullScreen()
        self.init_ui()
        vlc_options = [
            "--embedded-video",
            "--play-and-exit",
            "--autoscale",
            "--fullscreen",
            "--video-on-top",
            "--verbose -1",
            "--canvas-aspect 3:4",
            "--no-canvas-padd"
        ]

        self.instance = vlc.Instance(" ".join(vlc_options))
        self.media = None
        self.player = self.instance.media_player_new()
        
        if platform.system() == "Linux":
            self.player.set_xwindow(int(self.videoframe.winId()))
        elif platform.system() == "Windows":  # for Windows
            self.player.set_hwnd(int(self.videoframe.winId()))

        self.open_file(self.media_files[self.current_index])
        
    def init_ui(self):
        
      
        self.videoframe = QtWidgets.QFrame()
       
        self.palette = self.videoframe.palette()
        self.palette.setColor(QtGui.QPalette.Window, QtGui.QColor(0, 0, 0))
        self.videoframe.setPalette(self.palette)
        self.videoframe.setAutoFillBackground(True)
        self.setCentralWidget(self.videoframe)
        
    def with_opencv(filename):
        
        import cv2
        video = cv2.VideoCapture(filename)
    
        duration = video.get(cv2.CAP_PROP_POS_MSEC)
        frame_count = video.get(cv2.CAP_PROP_FRAME_COUNT)
    
        return duration, frame_count

    def open_file(self, filename):
       
        if not filename:
            return
        
        self.media = self.instance.media_new(filename)
      
        self.player.set_media(self.media)
       
        self.media.parse()
     
        self.player.play()
        
        
    
def main():
    
    layout = [[sg.Text('Test', font=("Helvetica", 30))],
              [sg.Text('Clique sur le boutton <<Lancer>>', font=("Calibri", 20))],
              [sg.Button('Lancer'), sg.Button('Sortie')]
              ]
    
    window = sg.Window('02.05.2022', layout, size = (800, 480), element_justification="Center", finalize=True)
    
    
   
        
    while True:
        event, values = window.Read()
        print(event, values)
        if event in (sg.WINDOW_CLOSED, 'Sortie'):
            break
        if event in (sg.WINDOW_CLOSED, 'Lancer'):
            
            app = QtWidgets.QApplication(sys.argv)
        
            player = Player()
            player.show()
            
            sys.exit(app.exec_())           
            break
    
    window.close()

if __name__ == '__main__':
   main()

谢谢!

我找到了解决办法。这是新的主循环:

while True:
    event, values = window.Read()
    print(event, values)
    if event in (sg.WINDOW_CLOSED, 'Sortie'):
        break
    if event in (sg.WINDOW_CLOSED, 'Lancer'):
        
        app = QtWidgets.QApplication(sys.argv)
    
        player = Player()
        player.show()
        # Wait for is_playing to register the fact that it is playing 
        time.sleep(0.1)
        while True:
            app.processEvents()

            if not player.player.is_playing():
                break        
        break

它在循环中调用 app.processEvents() 而不是 app.exec_(),并且还会检查玩家是否在该循环中停止播放。