chore: import R0nY3n/LTE_manager main snapshot

This commit is contained in:
2026-07-20 16:35:15 +00:00
commit b8438bba61
48 changed files with 15676 additions and 0 deletions
+723
View File
@@ -0,0 +1,723 @@
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
QLineEdit, QTextEdit, QGroupBox, QFormLayout, QComboBox,
QGridLayout, QMessageBox, QSpinBox, QCheckBox, QFileDialog)
from PyQt5.QtCore import Qt, pyqtSlot
import serial.tools.list_ports
import os
import json
class SettingsTab(QWidget):
def __init__(self, lte_manager, audio_features=None):
super().__init__()
self.lte_manager = lte_manager
self.audio_features = audio_features
# Settings file path
self.settings_file = "lte_settings.json"
# Default settings
self.settings = {
"at_port": "",
"at_baudrate": "115200",
"nmea_port": "None",
"nmea_baudrate": "9600",
"auto_connect": False,
"audio_enabled": True,
"ringtone_file": "",
"recording_path": "",
"auto_record_calls": True, # 自动录制通话
"auto_play_after_call": False, # 通话结束后自动播放录音
"auto_play_on_answer": False, # 接听电话时自动播放声音
"answer_play_audio_file": "", # 接听时播放的音频文件
}
# 从文件加载设置
try:
if os.path.exists(self.settings_file):
with open(self.settings_file, 'r') as f:
saved_settings = json.load(f)
for key, value in saved_settings.items():
self.settings[key] = value
except Exception as e:
print(f"加载设置失败: {str(e)}")
# Connect signals
self.lte_manager.status_changed.connect(self.on_status_changed)
if self.audio_features:
self.audio_features.status_changed.connect(self.on_status_changed)
# Create UI components first
self._create_ui_components()
# Then setup the UI layout
self.setup_ui()
# Finally refresh the ports
self.refresh_ports()
# 应用设置到UI
self._apply_settings_to_ui()
# 如果初始化时有音频特性模块,立即应用相关设置
if self.audio_features:
# 设置录音路径
if self.settings.get("recording_path") and os.path.exists(self.settings.get("recording_path")):
self.audio_features.set_storage_path(self.settings.get("recording_path"))
# 设置自动录音选项
self.audio_features.set_auto_record_calls(self.settings.get("auto_record_calls", True))
# 设置自动播放选项
self.audio_features.set_auto_play_after_call(self.settings.get("auto_play_after_call", False))
def _apply_settings_to_ui(self):
"""将加载的设置应用到UI组件"""
# 加载设置
self.auto_record_cb.setChecked(self.settings.get('auto_record_calls', True))
self.auto_play_cb.setChecked(self.settings.get('auto_play_after_call', False))
self.auto_play_on_answer_cb.setChecked(self.settings.get('auto_play_on_answer', False))
recording_path = self.settings.get('recording_path', '')
self.recording_path_edit.setText(recording_path)
answer_play_file = self.settings.get('answer_play_audio_file', '')
self.answer_play_edit.setText(answer_play_file)
# 如果音频特性实例存在,应用设置
if self.audio_features:
self.audio_features.set_auto_record_calls(self.auto_record_cb.isChecked())
self.audio_features.set_auto_play_after_call(self.auto_play_cb.isChecked())
answer_audio_file = self.answer_play_edit.text()
if answer_audio_file and os.path.exists(answer_audio_file):
self.audio_features.set_auto_play_on_answer(
self.auto_play_on_answer_cb.isChecked(),
answer_audio_file
)
def _create_ui_components(self):
"""创建所有UI组件"""
# 创建串口选择下拉框
self.at_port_combo = QComboBox()
self.at_port_combo.setMinimumWidth(120)
self.at_baud_combo = QComboBox()
self.at_baud_combo.setMinimumWidth(100)
self.at_baud_combo.addItems(['115200', '9600', '38400', '57600'])
self.nmea_port_combo = QComboBox()
self.nmea_port_combo.setMinimumWidth(120)
self.nmea_port_combo.addItem("None")
self.nmea_baud_combo = QComboBox()
self.nmea_baud_combo.setMinimumWidth(100)
self.nmea_baud_combo.addItems(['9600', '38400', '57600', '115200'])
# 创建按钮
self.connect_btn = QPushButton("连接")
self.connect_btn.clicked.connect(self.toggle_connection)
# 创建AT命令输入框和发送按钮
self.at_command_input = QLineEdit()
self.at_command_input.setPlaceholderText("输入AT命令")
self.send_btn = QPushButton("发送")
self.send_btn.clicked.connect(self.send_at_command)
# 创建文本显示区域
self.at_response_text = QTextEdit()
self.at_response_text.setMaximumHeight(150)
self.at_response_text.setReadOnly(True)
self.status_text = QTextEdit()
self.status_text.setMinimumHeight(200)
self.status_text.setReadOnly(True)
# 创建复选框
self.auto_connect_check = QCheckBox("启动时自动连接")
self.auto_connect_check.setChecked(self.settings.get("auto_connect", False))
# 音频功能组件
self.audio_enabled_check = QCheckBox("启用音频功能")
self.audio_enabled_check.setChecked(self.settings.get("audio_enabled", True))
# 自动录音选项
self.auto_record_calls_check = QCheckBox("自动录制通话")
self.auto_record_calls_check.setChecked(self.settings.get("auto_record_calls", True))
self.auto_record_calls_check.setToolTip("接听电话时自动开始录音,通话结束时自动停止")
self.auto_record_calls_check.stateChanged.connect(self.on_auto_record_changed)
# 自动播放录音选项
self.auto_play_after_call_check = QCheckBox("通话结束后自动播放录音")
self.auto_play_after_call_check.setChecked(self.settings.get("auto_play_after_call", False))
self.auto_play_after_call_check.setToolTip("通话结束后自动播放刚录制的通话录音")
self.auto_play_after_call_check.stateChanged.connect(self.on_auto_play_changed)
# 录音路径
self.recording_path_input = QLineEdit()
# 如果没有设置过录音路径,使用音频特性模块的默认路径
if self.audio_features and not self.settings.get("recording_path"):
self.settings["recording_path"] = self.audio_features.storage_path
self.recording_path_input.setText(self.settings.get("recording_path", ""))
self.recording_path_btn = QPushButton("浏览...")
self.recording_path_btn.clicked.connect(self.browse_recording_path)
self.recording_path_reset_btn = QPushButton("重置")
self.recording_path_reset_btn.setToolTip("重置为默认路径")
self.recording_path_reset_btn.clicked.connect(self.reset_recording_path)
# 铃声设置
self.ringtone_path_input = QLineEdit()
self.ringtone_path_input.setText(self.settings.get("ringtone_file", ""))
self.ringtone_path_btn = QPushButton("浏览...")
self.ringtone_path_btn.clicked.connect(self.browse_ringtone_file)
self.set_ringtone_btn = QPushButton("设置铃声")
self.set_ringtone_btn.clicked.connect(self.set_ringtone)
# 录音控制
self.start_recording_btn = QPushButton("开始录音")
self.start_recording_btn.clicked.connect(self.start_recording)
self.stop_recording_btn = QPushButton("停止录音")
self.stop_recording_btn.clicked.connect(self.stop_recording)
# 录音类型选择
self.recording_type_combo = QComboBox()
self.recording_type_combo.addItems(["本地麦克风", "通话对方声音", "双方声音混合"])
# 播放音频
self.play_audio_input = QLineEdit()
self.play_audio_input.setPlaceholderText("输入音频文件名或路径")
self.play_audio_btn = QPushButton("播放")
self.play_audio_btn.clicked.connect(self.play_audio)
self.stop_audio_btn = QPushButton("停止")
self.stop_audio_btn.clicked.connect(self.stop_audio)
self.browse_audio_btn = QPushButton("浏览...")
self.browse_audio_btn.clicked.connect(self.browse_audio_file)
# 播放类型选择
self.play_type_combo = QComboBox()
self.play_type_combo.addItems(["本地播放", "远程播放(对方听)", "双方都播放"])
# 创建音频控制部分
self.audio_group = QGroupBox("音频控制")
self.audio_layout = QVBoxLayout()
# 通话录音部分
self.recording_section = QGroupBox("通话录音")
recording_layout = QVBoxLayout()
# 自动录制选项
self.auto_record_cb = QCheckBox("自动录制通话")
self.auto_record_cb.setToolTip("接听电话时自动开始录音,挂断时自动停止")
self.auto_record_cb.stateChanged.connect(self.on_auto_record_changed)
recording_layout.addWidget(self.auto_record_cb)
# 录音后自动播放选项
self.auto_play_cb = QCheckBox("录音后自动播放")
self.auto_play_cb.setToolTip("通话结束后自动播放录音")
self.auto_play_cb.stateChanged.connect(self.on_auto_play_changed)
recording_layout.addWidget(self.auto_play_cb)
# 录音路径选择
recording_path_layout = QHBoxLayout()
self.recording_path_label = QLabel("录音存储路径:")
self.recording_path_edit = QLineEdit()
self.recording_path_edit.setReadOnly(True)
self.browse_recording_btn = QPushButton("浏览...")
self.browse_recording_btn.clicked.connect(self.browse_recording_path)
self.reset_recording_btn = QPushButton("重置")
self.reset_recording_btn.clicked.connect(self.reset_recording_path)
recording_path_layout.addWidget(self.recording_path_label)
recording_path_layout.addWidget(self.recording_path_edit)
recording_path_layout.addWidget(self.browse_recording_btn)
recording_path_layout.addWidget(self.reset_recording_btn)
recording_layout.addLayout(recording_path_layout)
# 录音控制按钮
recording_control_layout = QHBoxLayout()
self.start_recording_btn = QPushButton("开始录音")
self.start_recording_btn.clicked.connect(self.start_recording)
self.stop_recording_btn = QPushButton("停止录音")
self.stop_recording_btn.clicked.connect(self.stop_recording)
recording_control_layout.addWidget(self.start_recording_btn)
recording_control_layout.addWidget(self.stop_recording_btn)
recording_layout.addLayout(recording_control_layout)
self.recording_section.setLayout(recording_layout)
self.audio_layout.addWidget(self.recording_section)
# 音频播放部分
self.playback_section = QGroupBox("音频播放")
playback_layout = QVBoxLayout()
# 自动接听播放选项
self.auto_play_on_answer_cb = QCheckBox("接听电话时自动播放音频")
self.auto_play_on_answer_cb.setToolTip("接听电话时自动向对方播放指定音频文件")
self.auto_play_on_answer_cb.stateChanged.connect(self.on_auto_play_on_answer_changed)
playback_layout.addWidget(self.auto_play_on_answer_cb)
# 接听播放音频选择
answer_play_layout = QHBoxLayout()
self.answer_play_label = QLabel("接听播放音频:")
self.answer_play_edit = QLineEdit()
self.answer_play_edit.setReadOnly(True)
self.browse_answer_play_btn = QPushButton("浏览...")
self.browse_answer_play_btn.clicked.connect(self.browse_answer_play_file)
answer_play_layout.addWidget(self.answer_play_label)
answer_play_layout.addWidget(self.answer_play_edit)
answer_play_layout.addWidget(self.browse_answer_play_btn)
playback_layout.addLayout(answer_play_layout)
# 音频文件选择
audio_file_layout = QHBoxLayout()
self.audio_file_label = QLabel("音频文件:")
self.audio_file_edit = QLineEdit()
self.audio_file_edit.setReadOnly(True)
self.browse_audio_btn = QPushButton("浏览...")
self.browse_audio_btn.clicked.connect(self.browse_audio_file)
audio_file_layout.addWidget(self.audio_file_label)
audio_file_layout.addWidget(self.audio_file_edit)
audio_file_layout.addWidget(self.browse_audio_btn)
playback_layout.addLayout(audio_file_layout)
# 播放控制按钮
playback_control_layout = QHBoxLayout()
self.play_audio_btn = QPushButton("播放音频")
self.play_audio_btn.clicked.connect(self.play_audio)
self.stop_audio_btn = QPushButton("停止播放")
self.stop_audio_btn.clicked.connect(self.stop_audio)
playback_control_layout.addWidget(self.play_audio_btn)
playback_control_layout.addWidget(self.stop_audio_btn)
playback_layout.addLayout(playback_control_layout)
self.playback_section.setLayout(playback_layout)
self.audio_layout.addWidget(self.playback_section)
# 铃声设置部分
self.ringtone_section = QGroupBox("铃声设置")
ringtone_layout = QVBoxLayout()
# 铃声文件选择
ringtone_file_layout = QHBoxLayout()
self.ringtone_file_label = QLabel("铃声文件:")
self.ringtone_file_edit = QLineEdit()
self.ringtone_file_edit.setReadOnly(True)
self.browse_ringtone_btn = QPushButton("浏览...")
self.browse_ringtone_btn.clicked.connect(self.browse_ringtone_file)
ringtone_file_layout.addWidget(self.ringtone_file_label)
ringtone_file_layout.addWidget(self.ringtone_file_edit)
ringtone_file_layout.addWidget(self.browse_ringtone_btn)
ringtone_layout.addLayout(ringtone_file_layout)
# 铃声设置按钮
self.set_ringtone_btn = QPushButton("设置铃声")
self.set_ringtone_btn.clicked.connect(self.set_ringtone)
ringtone_layout.addWidget(self.set_ringtone_btn)
self.ringtone_section.setLayout(ringtone_layout)
self.audio_layout.addWidget(self.ringtone_section)
self.audio_group.setLayout(self.audio_layout)
def setup_ui(self):
"""设置UI布局"""
layout = QVBoxLayout(self)
# 串口设置组
serial_group = QGroupBox("串口设置")
serial_layout = QGridLayout()
# 第一行:AT串口和波特率
serial_layout.addWidget(QLabel("AT串口:"), 0, 0)
serial_layout.addWidget(self.at_port_combo, 0, 1)
serial_layout.addWidget(QLabel("AT波特率:"), 0, 2)
serial_layout.addWidget(self.at_baud_combo, 0, 3)
# 第二行:NMEA串口和波特率
serial_layout.addWidget(QLabel("NMEA串口:"), 1, 0)
serial_layout.addWidget(self.nmea_port_combo, 1, 1)
serial_layout.addWidget(QLabel("NMEA波特率:"), 1, 2)
serial_layout.addWidget(self.nmea_baud_combo, 1, 3)
# 第三行:刷新按钮和自动连接选项
refresh_btn = QPushButton("刷新串口")
refresh_btn.clicked.connect(self.refresh_ports)
serial_layout.addWidget(refresh_btn, 2, 0, 1, 2)
serial_layout.addWidget(self.auto_connect_check, 2, 2, 1, 2)
serial_group.setLayout(serial_layout)
layout.addWidget(serial_group)
# 连接按钮
layout.addWidget(self.connect_btn)
# 添加音频控制组
layout.addWidget(self.audio_group)
# AT命令区域
at_group = QGroupBox("AT命令")
at_layout = QVBoxLayout()
# AT命令输入区域
at_input_layout = QHBoxLayout()
at_input_layout.addWidget(self.at_command_input)
at_input_layout.addWidget(self.send_btn)
at_layout.addLayout(at_input_layout)
# AT响应显示区域
at_layout.addWidget(self.at_response_text)
at_group.setLayout(at_layout)
layout.addWidget(at_group)
# 状态信息区域
status_group = QGroupBox("状态信息")
status_layout = QVBoxLayout()
status_layout.addWidget(self.status_text)
status_group.setLayout(status_layout)
layout.addWidget(status_group)
def on_auto_record_changed(self, state):
"""处理自动录制通话选项变更"""
is_checked = state == Qt.Checked
if self.audio_features:
self.audio_features.set_auto_record_calls(is_checked)
self.settings["auto_record_calls"] = is_checked
self.save_settings()
def on_auto_play_changed(self, state):
"""处理自动播放录音选项变更"""
is_checked = state == Qt.Checked
if self.audio_features:
self.audio_features.set_auto_play_after_call(is_checked)
self.settings["auto_play_after_call"] = is_checked
self.save_settings()
def reset_recording_path(self):
"""重置录音路径为默认值"""
if self.audio_features:
# 重置为音频模块的默认路径
default_path = self.audio_features.storage_path
self.recording_path_edit.setText(default_path)
self.audio_features.set_storage_path(default_path)
self.settings["recording_path"] = default_path
self.save_settings()
self.add_status_message(f"录音路径已重置为: {default_path}")
def get_available_ports(self):
"""Get list of available serial ports"""
ports = []
for port in serial.tools.list_ports.comports():
ports.append(port.device)
return ports
def refresh_ports(self):
"""Refresh available serial ports"""
self.at_port_combo.clear()
self.nmea_port_combo.clear()
self.nmea_port_combo.addItem("None")
ports = self.get_available_ports()
for port in ports:
self.at_port_combo.addItem(port)
self.nmea_port_combo.addItem(port)
# Set saved ports if available
if self.settings["at_port"] in ports:
self.at_port_combo.setCurrentText(self.settings["at_port"])
if self.settings["nmea_port"] in ports or self.settings["nmea_port"] == "None":
self.nmea_port_combo.setCurrentText(self.settings["nmea_port"])
def toggle_connection(self):
"""切换连接状态"""
if not self.lte_manager.is_connected():
self.connect()
else:
self.disconnect()
def connect(self):
"""连接到LTE模块"""
at_port = self.at_port_combo.currentText()
at_baud = int(self.at_baud_combo.currentText())
# 旧代码保留在注释中,以便后续可能的恢复
# nmea_port = self.nmea_port_combo.currentText()
# nmea_baud = int(self.nmea_baud_combo.currentText())
# if nmea_port == "None":
# nmea_port = ""
# 使用新的连接方法,只传递AT端口和波特率
if self.lte_manager.connect(port=at_port, baudrate=at_baud):
self.connect_btn.setText("断开")
self.save_settings()
# 更新音频控件状态
if self.audio_features:
self.update_audio_controls_state()
# 如果有设置铃声,自动应用
if self.settings.get("ringtone_file") and os.path.exists(self.settings.get("ringtone_file")):
self.set_ringtone()
# 如果有设置录音路径,自动应用
if self.settings.get("recording_path") and os.path.exists(self.settings.get("recording_path")):
self.audio_features.set_storage_path(self.settings.get("recording_path"))
# 应用自动录音和自动播放设置
self.audio_features.set_auto_record_calls(self.auto_record_cb.isChecked())
self.audio_features.set_auto_play_after_call(self.auto_play_cb.isChecked())
else:
QMessageBox.warning(self, "连接错误", "无法连接到LTE模块")
def disconnect(self):
"""断开LTE模块连接"""
self.lte_manager.disconnect()
self.connect_btn.setText("连接")
# 更新音频控件状态
if self.audio_features:
self.update_audio_controls_state()
def send_at_command(self):
"""发送AT命令"""
if not self.lte_manager.is_connected():
QMessageBox.warning(self, "错误", "未连接到LTE模块")
return
command = self.at_command_input.text().strip()
if not command:
return
self.at_response_text.append(f">>> {command}")
response = self.lte_manager.send_at_command(command)
if response:
self.at_response_text.append(response)
self.at_command_input.clear()
def on_status_changed(self, status):
"""Handle status change"""
self.add_status_message(status)
def add_status_message(self, message):
"""Add message to status display"""
self.status_text.append(message)
self.status_text.ensureCursorVisible()
def save_settings(self):
"""保存设置到文件"""
try:
# 更新设置字典
self.settings["at_port"] = self.at_port_combo.currentText()
self.settings["at_baudrate"] = self.at_baud_combo.currentText()
self.settings["nmea_port"] = self.nmea_port_combo.currentText()
self.settings["nmea_baudrate"] = self.nmea_baud_combo.currentText()
self.settings["auto_connect"] = self.auto_connect_check.isChecked()
self.settings["recording_path"] = self.recording_path_edit.text()
self.settings["auto_record_calls"] = self.auto_record_cb.isChecked()
self.settings["auto_play_after_call"] = self.auto_play_cb.isChecked()
self.settings["auto_play_on_answer"] = self.auto_play_on_answer_cb.isChecked()
self.settings["answer_play_audio_file"] = self.answer_play_edit.text()
with open(self.settings_file, 'w') as f:
json.dump(self.settings, f, indent=4)
print("设置已保存到", self.settings_file)
except Exception as e:
print(f"保存设置失败: {str(e)}")
def try_auto_connect(self):
"""尝试自动连接"""
if self.auto_connect_check.isChecked():
self.connect()
# 音频功能相关方法
def update_audio_controls_state(self):
"""更新音频控制按钮的状态"""
if not hasattr(self, 'audio_features') or not self.audio_features:
return
connected = self.lte_manager.is_connected()
recording = self.audio_features.is_recording() if connected else False
playing = self.audio_features.playing if connected else False
# 启用/禁用录音控制按钮
self.start_recording_btn.setEnabled(connected and not recording)
self.stop_recording_btn.setEnabled(connected and recording)
# 启用/禁用播放控制按钮
self.play_audio_btn.setEnabled(connected and not playing)
self.stop_audio_btn.setEnabled(connected and playing)
# 铃声设置按钮
self.set_ringtone_btn.setEnabled(connected)
# 自动功能控制
self.auto_record_cb.setEnabled(connected)
self.auto_play_cb.setEnabled(connected)
self.auto_play_on_answer_cb.setEnabled(connected)
# 路径设置按钮
self.browse_recording_btn.setEnabled(True) # 这个不依赖连接状态
self.reset_recording_btn.setEnabled(True) # 这个不依赖连接状态
self.browse_audio_btn.setEnabled(connected)
self.browse_ringtone_btn.setEnabled(connected)
self.browse_answer_play_btn.setEnabled(connected)
def browse_recording_path(self):
"""浏览并选择录音存储路径"""
current_path = self.recording_path_edit.text() or os.path.expanduser("~")
dir_path = QFileDialog.getExistingDirectory(
self, "选择录音存储路径", current_path
)
if dir_path:
self.recording_path_edit.setText(dir_path)
if self.audio_features:
self.audio_features.set_storage_path(dir_path)
self.save_settings()
self.add_status_message(f"录音存储路径已设置为: {dir_path}")
def browse_ringtone_file(self):
"""浏览并选择铃声文件"""
home_dir = os.path.expanduser("~")
file_dialog = QFileDialog()
file_path, _ = file_dialog.getOpenFileName(
self, "选择铃声文件", home_dir,
"音频文件 (*.mp3 *.wav *.amr);;所有文件 (*)"
)
if file_path:
self.ringtone_file_edit.setText(file_path)
self.save_settings()
def set_ringtone(self):
"""设置铃声"""
if not self.audio_features or not self.lte_manager.is_connected():
return
ringtone_file = self.ringtone_file_edit.text()
if not ringtone_file:
QMessageBox.warning(self, "设置铃声", "请先选择铃声文件")
return
if self.audio_features.set_ringtone(ringtone_file):
QMessageBox.information(self, "设置铃声", "铃声设置成功")
else:
QMessageBox.warning(self, "设置铃声", "铃声设置失败")
def start_recording(self):
"""开始录音"""
if not self.audio_features or not self.lte_manager.is_connected():
return
record_type = self.recording_type_combo.currentIndex() + 1 # 1=本地, 2=远程, 3=混合
if self.audio_features.start_recording(record_path=record_type):
self.update_audio_controls_state()
self.add_status_message("录音已开始")
else:
QMessageBox.warning(self, "录音", "开始录音失败")
def stop_recording(self):
"""停止录音"""
if not self.audio_features or not self.lte_manager.is_connected():
return
if self.audio_features.stop_recording():
self.update_audio_controls_state()
self.add_status_message("录音已停止")
else:
QMessageBox.warning(self, "录音", "停止录音失败")
def browse_audio_file(self):
"""浏览并选择音频文件"""
home_dir = os.path.expanduser("~")
file_path, _ = QFileDialog.getOpenFileName(
self, "选择音频文件", home_dir,
"音频文件 (*.mp3 *.wav *.amr *.pcm);;所有文件 (*)"
)
if file_path:
self.audio_file_edit.setText(file_path)
def play_audio(self):
"""播放选择的音频文件"""
if not self.lte_manager.is_connected() or not self.audio_features:
QMessageBox.warning(self, "播放音频", "未连接到LTE模块或音频功能未启用")
return
audio_file = self.audio_file_edit.text()
if not audio_file:
# 如果未选择文件,提示用户
self.browse_audio_file()
audio_file = self.audio_file_edit.text()
if not audio_file:
return
play_type = self.play_type_combo.currentIndex()
success = self.audio_features.play_audio(audio_file, play_type)
if success:
self.add_status_message(f"开始播放: {os.path.basename(audio_file)}")
else:
QMessageBox.warning(self, "播放音频", "播放音频失败")
def stop_audio(self):
"""停止播放音频"""
if not self.audio_features or not self.lte_manager.is_connected():
return
if self.audio_features.stop_audio():
self.update_audio_controls_state()
self.add_status_message("音频播放已停止")
else:
QMessageBox.warning(self, "播放音频", "停止播放失败")
def on_auto_play_on_answer_changed(self, state):
"""处理接听电话自动播放音频选项变更"""
enabled = state == Qt.Checked
if self.audio_features:
# 如果启用但未设置音频文件,提示用户选择
if enabled and not self.answer_play_edit.text():
self.browse_answer_play_file()
# 如果用户取消了选择,则取消勾选
if not self.answer_play_edit.text():
self.auto_play_on_answer_cb.setChecked(False)
return
audio_file = self.answer_play_edit.text() if self.answer_play_edit.text() else None
self.audio_features.set_auto_play_on_answer(enabled, audio_file)
self.save_settings()
def browse_answer_play_file(self):
"""浏览并选择接听时要播放的音频文件"""
home_dir = os.path.expanduser("~")
file_dialog = QFileDialog()
file_path, _ = file_dialog.getOpenFileName(
self, "选择音频文件", home_dir,
"音频文件 (*.amr *.wav *.mp3 *.pcm);;所有文件 (*)"
)
if file_path:
self.answer_play_edit.setText(file_path)
# 如果音频特性实例存在,更新设置
if self.audio_features:
self.audio_features.set_auto_play_on_answer(
self.auto_play_on_answer_cb.isChecked(),
file_path
)
self.save_settings()