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_()
,并且还会检查玩家是否在该循环中停止播放。
我目前正在编写一个代码来执行各种操作,例如控制电机等,但有一次我需要编写代码以在 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_()
,并且还会检查玩家是否在该循环中停止播放。