Spaces:
Build error
Build error
| import os | |
| from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, | |
| QSlider, QRadioButton, QLineEdit, QPushButton, | |
| QFileDialog, QGroupBox) | |
| from PySide6.QtCore import Qt, QUrl | |
| # 正确导入QVideoWidget | |
| from PySide6.QtMultimediaWidgets import QVideoWidget | |
| from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput | |
| class CustomSlider(QWidget): | |
| """整数值滑块控件""" | |
| def __init__(self, minimum, maximum, step, label, value, parent=None): | |
| super().__init__(parent) | |
| self.layout = QVBoxLayout(self) | |
| self.label = QLabel(label) | |
| self.slider = QSlider(Qt.Horizontal) | |
| self.slider.setMinimum(minimum) | |
| self.slider.setMaximum(maximum) | |
| self.slider.setSingleStep(step) | |
| self.slider.setValue(value) | |
| self.value_label = QLabel(str(value)) | |
| self.slider.valueChanged.connect(self.update_value) | |
| self.layout.addWidget(self.label) | |
| slider_layout = QHBoxLayout() | |
| slider_layout.addWidget(self.slider) | |
| slider_layout.addWidget(self.value_label) | |
| self.layout.addLayout(slider_layout) | |
| self.setLayout(self.layout) | |
| def update_value(self, value): | |
| self.value_label.setText(str(value)) | |
| def value(self): | |
| return self.slider.value() | |
| def setValue(self, value): | |
| self.slider.setValue(value) | |
| self.value_label.setText(str(value)) | |
| class FloatSlider(QWidget): | |
| """浮点值滑块控件""" | |
| def __init__(self, minimum, maximum, step, label, value, parent=None): | |
| super().__init__(parent) | |
| self.layout = QVBoxLayout(self) | |
| self.step = step | |
| self.label = QLabel(label) | |
| self.slider = QSlider(Qt.Horizontal) | |
| self.slider.setMinimum(int(minimum / step)) | |
| self.slider.setMaximum(int(maximum / step)) | |
| self.slider.setSingleStep(1) | |
| self.slider.setValue(int(value / step)) | |
| self.value_label = QLabel(f"{value:.2f}") | |
| self.slider.valueChanged.connect(self.update_value) | |
| self.layout.addWidget(self.label) | |
| slider_layout = QHBoxLayout() | |
| slider_layout.addWidget(self.slider) | |
| slider_layout.addWidget(self.value_label) | |
| self.layout.addLayout(slider_layout) | |
| self.setLayout(self.layout) | |
| def update_value(self, value): | |
| float_value = value * self.step | |
| self.value_label.setText(f"{float_value:.2f}") | |
| def value(self): | |
| return self.slider.value() * self.step | |
| def setValue(self, value): | |
| self.slider.setValue(int(value / self.step)) | |
| self.value_label.setText(f"{value:.2f}") | |
| class RadioButtonGroup(QWidget): | |
| """单选按钮组控件""" | |
| def __init__(self, options, label, default_value, parent=None): | |
| super().__init__(parent) | |
| self.layout = QVBoxLayout(self) | |
| self.group_box = QGroupBox(label) | |
| self.button_layout = QVBoxLayout() | |
| self.buttons = [] | |
| for option in options: | |
| option_str = str(option) if option is not None else "None" | |
| radio = QRadioButton(option_str) | |
| self.buttons.append((option, radio)) | |
| if option == default_value: | |
| radio.setChecked(True) | |
| self.button_layout.addWidget(radio) | |
| self.group_box.setLayout(self.button_layout) | |
| self.layout.addWidget(self.group_box) | |
| self.setLayout(self.layout) | |
| def value(self): | |
| for option, button in self.buttons: | |
| if button.isChecked(): | |
| return option | |
| return None | |
| class AudioSelector(QWidget): | |
| """音频文件选择控件""" | |
| def __init__(self, label, parent=None): | |
| super().__init__(parent) | |
| self.layout = QVBoxLayout(self) | |
| self.label = QLabel(label) | |
| self.layout.addWidget(self.label) | |
| self.file_layout = QHBoxLayout() | |
| self.file_path = QLineEdit() | |
| self.browse_button = QPushButton("浏览...") | |
| self.browse_button.clicked.connect(self.browse_file) | |
| self.file_layout.addWidget(self.file_path) | |
| self.file_layout.addWidget(self.browse_button) | |
| self.layout.addLayout(self.file_layout) | |
| self.setLayout(self.layout) | |
| def browse_file(self): | |
| file_path, _ = QFileDialog.getOpenFileName(self, "选择音频文件", "", "音频文件 (*.mp3 *.wav *.ogg)") | |
| if file_path: | |
| self.file_path.setText(file_path) | |
| def value(self): | |
| return self.file_path.text() if self.file_path.text() else None | |
| class VideoPlayer(QWidget): | |
| """改进的视频播放控件""" | |
| def __init__(self, label, parent=None): | |
| super().__init__(parent) | |
| self.layout = QVBoxLayout(self) | |
| self.label = QLabel(label) | |
| self.layout.addWidget(self.label) | |
| # 创建视频部件 | |
| self.video_widget = QVideoWidget() | |
| self.video_widget.setMinimumHeight(200) # 设置最小高度确保可见 | |
| # 创建媒体播放器并配置音频输出 | |
| self.media_player = QMediaPlayer() | |
| self.media_player.setVideoOutput(self.video_widget) | |
| # 使用音频输出对象控制音量 | |
| self.audio_output = QAudioOutput() | |
| self.media_player.setAudioOutput(self.audio_output) # 设置音频输出 | |
| self.audio_output.setVolume(0.7) # 设置默认音量为70% | |
| # 添加音量控制滑块 | |
| self.volume_slider = QSlider(Qt.Horizontal) | |
| self.volume_slider.setRange(0, 100) | |
| self.volume_slider.setValue(70) | |
| self.volume_slider.setToolTip("音量") | |
| self.volume_slider.valueChanged.connect(self.set_volume) | |
| # 连接错误信号 | |
| self.media_player.errorOccurred.connect(self.handle_error) | |
| # 创建控制部件 | |
| self.controls_layout = QHBoxLayout() | |
| self.play_button = QPushButton("播放") | |
| self.play_button.clicked.connect(self.play_pause) | |
| # 添加暂停和停止按钮 | |
| self.stop_button = QPushButton("停止") | |
| self.stop_button.clicked.connect(self.stop_video) | |
| # 状态标签 | |
| self.status_label = QLabel("就绪") | |
| # 组装控制栏 | |
| self.controls_layout.addWidget(self.play_button) | |
| self.controls_layout.addWidget(self.stop_button) | |
| # 添加音量控制 | |
| volume_layout = QHBoxLayout() | |
| volume_layout.addWidget(QLabel("音量:")) | |
| volume_layout.addWidget(self.volume_slider) | |
| self.controls_layout.addLayout(volume_layout) | |
| self.controls_layout.addWidget(self.status_label) | |
| self.layout.addWidget(self.video_widget) | |
| self.layout.addLayout(self.controls_layout) | |
| self.setLayout(self.layout) | |
| self.video_path = None | |
| def set_volume(self, volume): | |
| # 转换音量范围从0-100到0.0-1.0 | |
| self.audio_output.setVolume(volume / 100.0) | |
| self.status_label.setText(f"音量: {volume}%") | |
| def set_video(self, path): | |
| """设置视频源""" | |
| if not os.path.exists(path): | |
| self.status_label.setText(f"错误: 文件不存在") | |
| return | |
| self.video_path = path | |
| try: | |
| # 使用QUrl构建文件路径 | |
| url = QUrl.fromLocalFile(os.path.abspath(path)) | |
| self.media_player.setSource(url) | |
| self.status_label.setText(f"已加载: {os.path.basename(path)}") | |
| self.play_button.setEnabled(True) | |
| self.stop_button.setEnabled(True) | |
| except Exception as e: | |
| self.status_label.setText(f"错误: {str(e)}") | |
| def play_pause(self): | |
| """播放或暂停视频""" | |
| if not self.video_path: | |
| self.status_label.setText("错误: 未加载视频") | |
| return | |
| if self.media_player.playbackState() == QMediaPlayer.PlayingState: | |
| self.media_player.pause() | |
| self.play_button.setText("播放") | |
| self.status_label.setText("已暂停") | |
| else: | |
| self.media_player.play() | |
| self.play_button.setText("暂停") | |
| self.status_label.setText("正在播放") | |
| def stop_video(self): | |
| """停止视频播放""" | |
| self.media_player.stop() | |
| self.play_button.setText("播放") | |
| self.status_label.setText("已停止") | |
| def handle_error(self, error, error_string): | |
| """处理媒体播放器错误""" | |
| self.status_label.setText(f"播放错误: {error_string}") | |
| print(f"Video player error ({error}): {error_string}") |