PyQt5 QMediaPlayer停止播放后窗口缩放出现画面残留问题求助
PyQt5 QMediaPlayer视频停止后窗口缩放出现画面残留的解决方法
在PyQt5中使用QMediaPlayer时,视频播放结束或调用stop()方法后,缩放窗口会导致视频部件位置出现画面残留现象。
最小复现代码
import sys from PyQt5.QtCore import Qt, QUrl from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton, QFileDialog, QSlider from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent from PyQt5.QtMultimediaWidgets import QVideoWidget class Player(QMainWindow): def __init__(self, parent=None): super(Player, self).__init__(parent) self.media_player = QMediaPlayer(self) self.video_widget = QVideoWidget(self) self.slider = QSlider(Qt.Horizontal) self.open_button = QPushButton("Open Media File") self.open_button.clicked.connect(self.open_file) layout = QVBoxLayout() layout.addWidget(self.video_widget) layout.addWidget(self.open_button) layout.addWidget(self.slider) widget = QWidget(self) widget.setLayout(layout) self.setCentralWidget(widget) self.media_player.setVideoOutput(self.video_widget) self.media_player.positionChanged.connect(self.update_slider) self.slider.sliderMoved.connect(self.set_position) def open_file(self): file_dialog = QFileDialog.getOpenFileName(self, "Open Media File") if file_dialog[0]: self.set_and_play_file(file_dialog[0]) def set_and_play_file(self, selected_file): self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(selected_file))) self.media_player.play() def update_slider(self, position): self.slider.setMaximum(int(self.media_player.duration() / 1000)) self.slider.setValue(int(position / 1000)) def set_position(self, position): self.media_player.setPosition(int(position * 1000)) if __name__ == "__main__": app = QApplication(sys.argv) player = Player() player.show() sys.exit(app.exec_())
已尝试的无效方法
- 监听
QMediaPlayer.EndOfMedia状态,用pause()替代stop()并将播放位置设为0,仅部分改善,仍有残留 - 设置以下部件属性无效果:
self.video_widget.setAttribute(Qt.WA_OpaquePaintEvent, False) self.video_widget.setAutoFillBackground() self.video_widget.setAttribute(Qt.WA_NoSystemBackground, True) - 尝试重写
video widget的paintEvent()绘制红线,因QPainter使用经验不足未成功
彻底解决方法
方法1:自定义QVideoWidget重写resizeEvent强制刷新
问题核心是视频停止后,QVideoWidget在窗口缩放时未正确刷新区域。自定义视频部件,在大小变化时主动触发刷新:
from PyQt5.QtWidgets import QVideoWidget from PyQt5.QtCore import QResizeEvent class CustomVideoWidget(QVideoWidget): def resizeEvent(self, event: QResizeEvent) -> None: super().resizeEvent(event) self.update() # 强制刷新整个部件区域
替换原代码中的QVideoWidget为自定义类:
self.video_widget = CustomVideoWidget(self)
方法2:监听播放状态,重置视频输出并刷新
当视频停止时,先清除再重新设置视频输出,触发部件刷新:
# 在Player类的__init__方法中添加信号连接 self.media_player.stateChanged.connect(self.on_state_changed) self.media_player.mediaStatusChanged.connect(self.on_media_status_changed) def on_state_changed(self, state): if state == QMediaPlayer.StoppedState: # 清除并重新绑定视频输出 self.media_player.setVideoOutput(None) self.media_player.setVideoOutput(self.video_widget) self.video_widget.update() # 强制刷新 def on_media_status_changed(self, status): if status == QMediaPlayer.EndOfMedia: self.media_player.stop() # 触发停止状态处理逻辑
环境说明:Windows 10 x64 1809、PyQt5 5.15.10
内容的提问来源于stack exchange,提问作者deeffest
相关产品推荐
相关产品推荐

