[feature] 新增filter model中get/set接口

This commit is contained in:
Sam 2025-02-20 09:58:01 +08:00
parent aede544740
commit 6aed85c3c9
3 changed files with 204 additions and 72 deletions

View File

@ -10,6 +10,7 @@ from Ui_widget import Ui_Widget
# from component.widget_filter.checkbox_header import SCheckBoxHeaderView
from audio_filter_model import AudioFilterModel
from checkbox_header import SCheckBoxHeaderView
# from component.widget_filter.checkbox_header import SCheckBoxHeaderView
@ -371,16 +372,16 @@ class AudioFilterWidget(QWidget):
# 参数输入框变化
self.ui.lineEdit_11.textChanged.connect(
lambda v: self._on_param_changed('delay_data1', v)
lambda v: self._on_param_changed('delay', v)
)
self.ui.lineEdit_10.textChanged.connect(
lambda v: self._on_param_changed('ENC_volume_data1', v)
lambda v: self._on_param_changed('volume', v)
)
self.ui.lineEdit_13.textChanged.connect(
lambda v: self._on_param_changed('ENT_mx_right_data', v)
lambda v: self._on_param_changed('mix_right', v)
)
self.ui.lineEdit_12.textChanged.connect(
lambda v: self._on_param_changed('ENT_mix_left_data', v)
lambda v: self._on_param_changed('mix_left', v)
)
# 按钮点击
@ -409,8 +410,8 @@ class AudioFilterWidget(QWidget):
"""设置参数数据"""
if 'delay_data1' in params:
self.ui.lineEdit_11.setText(str(params['delay_data1']))
if 'ENT_volume_data1' in params:
self.ui.lineEdit_10.setText(str(params['ENT_volume_data1']))
if 'ENC_volume_data1' in params:
self.ui.lineEdit_10.setText(str(params['ENC_volume_data1']))
if 'ENT_mx_right_data' in params:
self.ui.lineEdit_13.setText(str(params['ENT_mx_right_data']))
if 'ENT_mix_left_data' in params:
@ -431,7 +432,7 @@ class AudioFilterWidget(QWidget):
# 私有方法
def _on_slider_changed(self, param: str, value: float):
"""处理滑块值变化"""
if self.current_filter_index >= 0:
if self.current_filter_index >= 0 and hasattr(self, 'model'):
# 更新表格中的值
column = {'freq': 3, 'q': 4, 'gain': 5, 'slope': 6}.get(param)
if column is not None:
@ -442,16 +443,39 @@ class AudioFilterWidget(QWidget):
column,
item
)
# 发送信号
self.filter_changed.emit(self.current_filter_index, param, value)
# 更新model中的滤波器参数
filter_params = self.model.filters[self.current_filter_index]
if param == 'freq':
filter_params.frequency = value
elif param == 'q':
filter_params.q_value = value
elif param == 'gain':
filter_params.gain = value
elif param == 'slope':
filter_params.slope = value
self.model.update_filter(self.current_filter_index, filter_params)
def _on_param_changed(self, param: str, value: str):
"""处理参数值变化"""
try:
float_value = float(value)
self.param_changed.emit(param, float_value)
except ValueError:
pass
if hasattr(self, 'model'):
try:
float_value = float(value)
# 更新model中的通道参数
channel_params = self.model.channel_params
if param == 'delay':
channel_params.delay = float_value
elif param == 'volume':
channel_params.volume = float_value
elif param == 'mix_right':
channel_params.mix_right = float_value
elif param == 'mix_left':
channel_params.mix_left = float_value
self.model.set_channel_params(channel_params)
except ValueError:
pass
def _on_selection_changed(self):
"""处理表格选择变化"""
@ -518,13 +542,14 @@ class AudioFilterWidget(QWidget):
def _on_filter_type_changed(self, row: int, filter_type: str):
"""处理滤波器类型变化"""
# 更新表格中的滤波器名称
# name_item = QTableWidgetItem(filter_type)
# name_item.setTextAlignment(Qt.AlignCenter)
# self.ui.tableWidget.setItem(row, 1, name_item)
# 发送信号通知类型变化
self.filter_added.emit(filter_type)
if hasattr(self, 'model'):
# 更新model中的滤波器类型
filter_params = self.model.filters[row]
filter_params.filter_type = FilterType[filter_type]
self.model.update_filter(row, filter_params)
# 发送信号通知类型变化
self.filter_added.emit(filter_type)
def _on_delete_filter_clicked(self):
"""处理删除滤波器按钮点击"""
@ -591,6 +616,12 @@ class AudioFilterWidget(QWidget):
def _on_checkbox_clicked(self, row: int, checked: bool):
"""处理单个复选框点击事件"""
if hasattr(self, 'model'):
# 更新model中的滤波器启用状态
filter_params = self.model.filters[row]
filter_params.enabled = checked
self.model.update_filter(row, filter_params)
self.filter_enabled_changed.emit(row, checked)
# 更新表头复选框状态
@ -674,6 +705,57 @@ class AudioFilterWidget(QWidget):
self.ui.verticalSlider_3.setValue(int(data.get('gain', 0)))
self.ui.verticalSlider_4.setValue(int(data.get('slope', 0)))
def setModel(self, model: AudioFilterModel):
"""设置数据模型并建立连接"""
self.model = model
# 连接模型信号到视图更新方法
self.model.dataChanged.connect(self._updateFromModel)
self.model.filterAdded.connect(self._handleFilterAdded)
self.model.filterRemoved.connect(self._handleFilterRemoved)
self.model.filterUpdated.connect(self._handleFilterUpdated)
self.model.channelParamsChanged.connect(self._handleChannelParamsChanged)
# 设置初始数据
self.set_channel_id(model.channel_id)
self.set_channel_name(model.channel_name)
self._updateFromModel()
def _updateFromModel(self):
"""从模型更新整个UI"""
if not hasattr(self, 'model'):
return
# 更新UI参数
self.set_all_params(self.model.to_widget_params())
def _handleFilterAdded(self, index: int):
"""处理滤波器添加事件"""
self._updateFromModel()
def _handleFilterRemoved(self, index: int):
"""处理滤波器删除事件"""
self._updateFromModel()
def _handleFilterUpdated(self, index: int):
"""处理滤波器更新事件"""
if index == self.current_filter_index:
filter_params = self.model.filters[index]
self._update_sliders({
'freq': filter_params.frequency,
'q': filter_params.q_value,
'gain': filter_params.gain,
'slope': filter_params.slope
})
def _handleChannelParamsChanged(self):
"""处理通道参数更新事件"""
params = self.model.channel_params
self.ui.lineEdit_11.setText(str(params.delay))
self.ui.lineEdit_10.setText(str(params.volume))
self.ui.lineEdit_13.setText(str(params.mix_right))
self.ui.lineEdit_12.setText(str(params.mix_left))
if __name__ == "__main__":
import sys
from PySide6.QtWidgets import QApplication
@ -681,50 +763,17 @@ if __name__ == "__main__":
app = QApplication(sys.argv)
# Create and show widget
# widget = AudioFilterWidget()
# widget.setWindowTitle("Audio Filter Widget")
# widget.resize(800, 600)
# widget.set_channel_id(2)
# widget.set_channel("channel_2")
# test_case_3 = {
# 'delay_data2': 100.0, # 最大延迟
# 'vol_data2': -80.0, # 最小音量
# 'mix_right_data2': 100.0, # 最大混音
# 'mix_left_data2': 0.0, # 最小混音
# 'filterType2_1': 2, # 低架滤波器
# 'fc2_1': 20000.0, # 最大频率
# 'q2_1': 10.0, # 最大Q值
# 'gain2_1': 12.0, # 最大增益
# 'slope2_1': 4.0, # 最大斜率
# 'filterType2_2': 3, # 高架滤波器
# 'fc2_2': 20.0, # 最小频率
# 'q2_2': 0.1, # 最小Q值
# 'gain2_2': -12.0, # 最小增益
# 'slope2_2': 1.0 # 最小斜率
# }
# widget.set_all_params(test_case_3)
# # 获取所有参数
# params = widget.get_all_params()
# print("params:", params)
# widget.show()
# 创建模型实例
# 创建模型
model = AudioFilterModel(channel_id=2, channel_name="channel_2")
# 设置通道参数
model.channel_params = ChannelParams(
model.set_channel_params(ChannelParams(
delay=100.0,
volume=-80.0,
mix_right=100.0,
mix_left=0.0
)
))
# 添加滤波器
model.add_filter(FilterParams(
filter_type=FilterType.HIGHPASS,
@ -741,17 +790,27 @@ if __name__ == "__main__":
gain=-12.0,
slope=1.0
))
widget_params = model.to_widget_params()
print("widget_params:", widget_params)
# 创建视图并设置模型
widget = AudioFilterWidget()
widget.set_channel_id(model.channel_id)
widget.set_channel_name(model.channel_name)
widget.set_all_params(widget_params)
params = widget.get_all_params()
print("params:", params)
widget.setModel(model)
widget.show()
# 测试模型更新
def test_update():
# model.set_channel_params(ChannelParams(
# delay=50.0,
# volume=-40.0,
# mix_right=50.0,
# mix_left=50.0
# ))
widget_params = model.get_all_data()
print("widget_params:", widget_params)
# 可以添加一个按钮来触发测试更新
from PySide6.QtWidgets import QPushButton
test_button = QPushButton("Test Update")
test_button.clicked.connect(test_update)
test_button.show()
sys.exit(app.exec())

View File

@ -1,6 +1,7 @@
from dataclasses import dataclass, asdict
from typing import List, Dict, Any, Optional
from enum import Enum
from PySide6.QtCore import QObject, Signal
class FilterType(Enum):
PEAK = 0
@ -65,26 +66,50 @@ class ChannelParams:
mix_left=data.get(f'mix_left_data{channel_id}', 0.0)
)
class AudioFilterModel:
class AudioFilterModel(QObject):
# 定义信号
dataChanged = Signal() # 数据更新信号
filterAdded = Signal(int) # 新增滤波器信号,参数为索引
filterRemoved = Signal(int) # 删除滤波器信号,参数为索引
filterUpdated = Signal(int) # 滤波器更新信号,参数为索引
channelParamsChanged = Signal() # 通道参数更新信号
def __init__(self, channel_id: int, channel_name: str):
super().__init__()
self.channel_id = channel_id
self.channel_name = channel_name
self.channel_params = ChannelParams(0.0, 0.0, 0.0, 0.0)
self.filters: List[FilterParams] = []
def updateData(self):
"""触发数据更新信号"""
self.dataChanged.emit()
def add_filter(self, filter_params: FilterParams):
"""添加新的滤波器"""
self.filters.append(filter_params)
self.filterAdded.emit(len(self.filters) - 1)
self.updateData()
def remove_filter(self, index: int):
"""移除指定索引的滤波器"""
if 0 <= index < len(self.filters):
self.filters.pop(index)
self.filterRemoved.emit(index)
self.updateData()
def update_filter(self, index: int, filter_params: FilterParams):
"""更新指定索引的滤波器参数"""
if 0 <= index < len(self.filters):
self.filters[index] = filter_params
self.filterUpdated.emit(index)
self.updateData()
def set_channel_params(self, params: ChannelParams):
"""设置通道参数"""
self.channel_params = params
self.channelParamsChanged.emit()
self.updateData()
def to_widget_params(self) -> Dict[str, Any]:
"""转换为AudioFilterWidget兼容的参数格式"""
@ -131,4 +156,52 @@ class AudioFilterModel:
model = cls(data['channel_id'], data['channel_name'])
model.channel_params = ChannelParams(**data['channel_params'])
model.filters = [FilterParams(**f) for f in data['filters']]
return model
return model
def get_channel_params(self) -> ChannelParams:
"""获取通道参数"""
return self.channel_params
def get_filter(self, index: int) -> Optional[FilterParams]:
"""获取指定索引的滤波器参数"""
if 0 <= index < len(self.filters):
return self.filters[index]
return None
def get_all_filters(self) -> List[FilterParams]:
"""获取所有滤波器参数"""
return self.filters.copy()
def get_filter_count(self) -> int:
"""获取滤波器数量"""
return len(self.filters)
def get_channel_info(self) -> Dict[str, Any]:
"""获取通道基本信息"""
return {
'channel_id': self.channel_id,
'channel_name': self.channel_name
}
def get_all_data(self) -> Dict[str, Any]:
"""获取所有数据的完整快照"""
return {
'channel_id': self.channel_id,
'channel_name': self.channel_name,
'channel_params': asdict(self.channel_params),
'filters': [asdict(f) for f in self.filters]
}
def is_filter_enabled(self, index: int) -> bool:
"""检查指定滤波器是否启用"""
if 0 <= index < len(self.filters):
return self.filters[index].enabled
return False
def get_enabled_filters(self) -> List[FilterParams]:
"""获取所有启用的滤波器"""
return [f for f in self.filters if f.enabled]
def get_widget_params(self) -> Dict[str, Any]:
"""获取用于widget的参数格式与to_widget_params相同"""
return self.to_widget_params()