diff --git a/component/widget_filter/__pycache__/audio_filter_model.cpython-313.pyc b/component/widget_filter/__pycache__/audio_filter_model.cpython-313.pyc index d21318f..6c46044 100644 Binary files a/component/widget_filter/__pycache__/audio_filter_model.cpython-313.pyc and b/component/widget_filter/__pycache__/audio_filter_model.cpython-313.pyc differ diff --git a/component/widget_filter/audio_filter_componet.py b/component/widget_filter/audio_filter_componet.py index 00a2ace..746961b 100644 --- a/component/widget_filter/audio_filter_componet.py +++ b/component/widget_filter/audio_filter_componet.py @@ -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()) \ No newline at end of file diff --git a/component/widget_filter/audio_filter_model.py b/component/widget_filter/audio_filter_model.py index 48eb001..d3ed556 100644 --- a/component/widget_filter/audio_filter_model.py +++ b/component/widget_filter/audio_filter_model.py @@ -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 \ No newline at end of file + 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() \ No newline at end of file