[feature] 新增通信server 新增通信部分修改

This commit is contained in:
Sam 2025-02-20 22:52:03 +08:00
parent 54adc36d97
commit 4dcfeac86d
25 changed files with 548 additions and 36 deletions

70
app.py
View File

@ -3,33 +3,62 @@ from component.widget_channel.widget_channel import Widget_Channel
from component.widget_card.widget_card import Widget_Card
from component.widget_card.widget_card import CardData
from component.widget_filter.audio_filter_componet import AudioFilterWidget
from component.widget_filter.audio_filter_model import AudioFilterModel
from component.widget_filter.audio_filter_controller import AudioFilterController
from param_struct_test.service_manager import ServiceManager
from application.application_controller import ApplicationController
from datetime import date
from PySide6.QtWidgets import QMainWindow
from PySide6.QtWidgets import QMainWindow, QPushButton, QVBoxLayout
from PySide6.QtWidgets import QWidget
from PySide6.QtCore import QObject
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# 初始化服务
ServiceManager.instance().init_services("127.0.0.1", 1234)
# 初始化应用控制器
self.app_controller = ApplicationController.instance()
self.widget_main = Widget_Main()
self.widget_channel = Widget_Channel()
self.widget_card = Widget_Card()
self.widget_main.ui.ListWidget_vLayout.addWidget(self.widget_card)
# self.widget_main.ui.ListWidget_vLayout.addWidget(self.widget_card)
self.widget_main.ui.Channel_hLayout.addWidget(self.widget_channel)
self.widget_filter_list = []
self.filter_controllers = [] # 存储控制器实例
# 添加测试按钮
self.test_button = QPushButton("Test Communication")
self.test_button.clicked.connect(self.test_communication)
self.widget_main.ui.ListWidget_vLayout.addWidget(self.test_button)
self.create_filter_widget()
self.setup_connections()
def create_filter_widget(self):
for i in range(24):
# 创建widget
filter_widget = AudioFilterWidget()
filter_widget.set_channel_id(i)
filter_widget.set_channel_name(f"Channel {i+1}")
# 创建model和controller
model = AudioFilterModel(channel_id=i, channel_name=f"Channel {i+1}")
controller = AudioFilterController(model)
controller.set_widget(filter_widget)
# 连接控制器信号
controller.error_occurred.connect(lambda msg: print(f"Error: {msg}"))
controller.state_changed.connect(lambda state: print(f"State changed: {state}"))
controller.params_synced.connect(lambda: print("Params synced"))
# 存储实例
self.widget_filter_list.append(filter_widget)
self.filter_controllers.append(controller)
def setup_connections(self):
print("setup_connections")
@ -39,20 +68,37 @@ class MainWindow(QWidget):
print(f"channel_id: {channel_id}")
self.widget_filter_list[channel_id].show()
def test_communication(self):
"""测试通信功能"""
print("Testing communication...")
# 测试第一个控制器的通信
if self.filter_controllers:
controller = self.filter_controllers[0]
# 测试从服务器加载数据
print("Testing load from server...")
controller.load_from_server()
# 测试同步数据到服务器
print("Testing sync to server...")
# controller.sync_to_server()
if __name__ == '__main__':
import sys
from PySide6.QtWidgets import QApplication
app = QApplication(sys.argv)
main_window = MainWindow()
for i in range(1, 11):
data = CardData(
name=f"项目 {i}",
date=date.today().strftime("%Y-%m-%d"),
description=f"这是项目 {i} 的详细描述信息,可以包含多行文本内容。这是一个较长的描述,用于测试换行效果。"
)
main_window.widget_card.add_card_item(data)
# # 添加测试卡片
# for i in range(1, 11):
# data = CardData(
# name=f"项目 {i}",
# date=date.today().strftime("%Y-%m-%d"),
# description=f"这是项目 {i} 的详细描述信息,可以包含多行文本内容。这是一个较长的描述,用于测试换行效果。"
# )
# main_window.widget_card.add_card_item(data)
main_window.widget_main.show()
sys.exit(app.exec())
sys.exit(app.exec())

58
app_origin.py Normal file
View File

@ -0,0 +1,58 @@
from component.widget_main.widget_main import Widget_Main
from component.widget_channel.widget_channel import Widget_Channel
from component.widget_card.widget_card import Widget_Card
from component.widget_card.widget_card import CardData
from component.widget_filter.audio_filter_componet import AudioFilterWidget
from datetime import date
from PySide6.QtWidgets import QMainWindow
from PySide6.QtWidgets import QWidget
from PySide6.QtCore import QObject
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.widget_main = Widget_Main()
self.widget_channel = Widget_Channel()
self.widget_card = Widget_Card()
self.widget_main.ui.ListWidget_vLayout.addWidget(self.widget_card)
self.widget_main.ui.Channel_hLayout.addWidget(self.widget_channel)
self.widget_filter_list = []
self.create_filter_widget()
self.setup_connections()
def create_filter_widget(self):
for i in range(24):
filter_widget = AudioFilterWidget()
filter_widget.set_channel_id(i)
filter_widget.set_channel_name(f"Channel {i+1}")
self.widget_filter_list.append(filter_widget)
def setup_connections(self):
print("setup_connections")
self.widget_channel.channel_btn_clicked.connect(self.on_channel_btn_clicked)
def on_channel_btn_clicked(self, channel_id: int):
print(f"channel_id: {channel_id}")
self.widget_filter_list[channel_id].show()
if __name__ == '__main__':
import sys
from PySide6.QtWidgets import QApplication
app = QApplication(sys.argv)
main_window = MainWindow()
for i in range(1, 11):
data = CardData(
name=f"项目 {i}",
date=date.today().strftime("%Y-%m-%d"),
description=f"这是项目 {i} 的详细描述信息,可以包含多行文本内容。这是一个较长的描述,用于测试换行效果。"
)
main_window.widget_card.add_card_item(data)
main_window.widget_main.show()
sys.exit(app.exec())

View File

@ -1,28 +1,104 @@
from component.widget_main.widget_main import Widget_Main
from component.widget_channel.widget_channel import Widget_Channel
from component.widget_card.widget_card import Widget_Card
from component.widget_card.widget_card import CardData
from component.widget_filter.audio_filter_componet import AudioFilterWidget
from component.widget_filter.audio_filter_model import AudioFilterModel
from component.widget_filter.audio_filter_controller import AudioFilterController
from param_struct_test.service_manager import ServiceManager
from application.application_controller import ApplicationController
from datetime import date
from PySide6.QtWidgets import QMainWindow, QPushButton, QVBoxLayout
from PySide6.QtWidgets import QWidget
from PySide6.QtCore import QObject
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# 初始化服务
ServiceManager.instance().init_services("127.0.0.1", 1234)
# 初始化应用控制器
self.app_controller = ApplicationController.instance()
self.widget_main = Widget_Main()
self.widget_channel = Widget_Channel()
self.widget_card = Widget_Card()
self.widget_main.ui.ListWidget_vLayout.addWidget(self.Widget_Card)
self.widget_main.ui.ListWidget_vLayout.addWidget(self.Widget_Channel)
# self.widget_main.ui.ListWidget_vLayout.addWidget(self.widget_card)
self.widget_main.ui.Channel_hLayout.addWidget(self.widget_channel)
self.widget_filter_list = []
self.filter_controllers = [] # 存储控制器实例
# 添加测试按钮
self.test_button = QPushButton("Test Communication")
self.test_button.clicked.connect(self.test_communication)
self.widget_main.ui.ListWidget_vLayout.addWidget(self.test_button)
self.create_filter_widget()
self.setup_connections()
def create_filter_widget(self):
for i in range(24):
# 创建widget
filter_widget = AudioFilterWidget()
filter_widget.set_channel_id(i)
filter_widget.set_channel_name(f"Channel {i+1}")
# 创建model和controller
model = AudioFilterModel(channel_id=i, channel_name=f"Channel {i+1}")
controller = AudioFilterController(model)
controller.set_widget(filter_widget)
# 连接控制器信号
controller.error_occurred.connect(lambda msg: print(f"Error: {msg}"))
controller.state_changed.connect(lambda state: print(f"State changed: {state}"))
controller.params_synced.connect(lambda: print("Params synced"))
# 存储实例
self.widget_filter_list.append(filter_widget)
self.filter_controllers.append(controller)
def setup_connections(self):
print("setup_connections")
self.widget_channel.channel_btn_clicked.connect(self.on_channel_btn_clicked)
def on_channel_btn_clicked(self, channel_id: int):
print(f"channel_id: {channel_id}")
self.widget_filter_list[channel_id].show()
def test_communication(self):
"""测试通信功能"""
print("Testing communication...")
# 测试第一个控制器的通信
if self.filter_controllers:
controller = self.filter_controllers[0]
# 测试从服务器加载数据
print("Testing load from server...")
controller.load_from_server()
# 测试同步数据到服务器
print("Testing sync to server...")
controller.sync_to_server()
if __name__ == '__main__':
import sys
from PySide6.QtWidgets import QApplication
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec())
# # 添加测试卡片
# for i in range(1, 11):
# data = CardData(
# name=f"项目 {i}",
# date=date.today().strftime("%Y-%m-%d"),
# description=f"这是项目 {i} 的详细描述信息,可以包含多行文本内容。这是一个较长的描述,用于测试换行效果。"
# )
# main_window.widget_card.add_card_item(data)
main_window.widget_main.show()
sys.exit(app.exec())

View File

@ -0,0 +1,75 @@
from PySide6.QtCore import QObject, Signal, Slot
from typing import Dict, Any, Optional
from dataclasses import dataclass
from param_struct_test.params_service import ParamsService
from param_struct_test.service_manager import ServiceManager
from param_struct_test.message_proxy import SignalProxy
@dataclass
class ControllerSignalData:
controller_id: str
widget: QObject
data: Dict[str, Any]
class ApplicationController(QObject):
# 单例实例
_instance = None
# 定义转发信号
signal_params_updated = Signal(ControllerSignalData)
@classmethod
def instance(cls) -> 'ApplicationController':
"""获取ApplicationController的单例实例"""
if cls._instance is None:
cls._instance = cls()
return cls._instance
def __init__(self):
if ApplicationController._instance is not None:
raise RuntimeError("ApplicationController is a singleton!")
super().__init__()
ApplicationController._instance = self
self._controllers: Dict[str, QObject] = {}
self._setup_service_connections()
def _setup_service_connections(self):
"""设置服务连接"""
service = ServiceManager.instance().params_service
# 连接服务信号到应用控制器的槽
service.signal_request_complete.connect(self._on_service_request_complete)
def register_controller(self, controller_id: str, controller: QObject):
"""注册控制器"""
self._controllers[controller_id] = controller
def unregister_controller(self, controller_id: str):
"""注销控制器"""
if controller_id in self._controllers:
del self._controllers[controller_id]
@Slot(SignalProxy)
def _on_service_request_complete(self, signal_proxy: SignalProxy):
"""服务请求完成的槽函数"""
# 找到对应的controller_id
print("CCCCCC:signal_proxy.data:", signal_proxy.data)
controller_id = self._get_controller_id_for_widget(signal_proxy.widget)
# 测试用 返回值类似这种格式 用来标机控件
controller_id = "audio_filter"
if controller_id:
# 转发信号
self.signal_params_updated.emit(ControllerSignalData(
controller_id=controller_id,
widget=signal_proxy.widget,
data=signal_proxy.data
))
def _get_controller_id_for_widget(self, widget: QObject) -> Optional[str]:
"""根据widget查找对应的controller_id"""
# 这里需要根据您的具体实现来确定如何找到对应的controller_id
# 示例实现
for controller_id, controller in self._controllers.items():
if hasattr(controller, 'widget') and controller.widget == widget:
return controller_id
return None

View File

@ -6,20 +6,20 @@ from PySide6.QtGui import QPainter, QColor, QPen, QBrush, QPainterPath, QIcon, Q
from PySide6.QtCore import QFile
from Ui_widget import Ui_Widget
from audio_filter_model import AudioFilterModel
from checkbox_header import SCheckBoxHeaderView
import resources
# from Ui_widget import Ui_Widget
# from audio_filter_model import AudioFilterModel
# from checkbox_header import SCheckBoxHeaderView
# import resources
from typing import List, Dict, Optional, Any
# from component.widget_filter.Ui_widget import Ui_Widget
# from component.widget_filter.checkbox_header import SCheckBoxHeaderView
# from component.widget_filter.checkbox_header import SCheckBoxHeaderView
# from component.widget_filter.Ui_widget import Ui_Widget
from component.widget_filter.Ui_widget import Ui_Widget
from component.widget_filter.checkbox_header import SCheckBoxHeaderView
from component.widget_filter.audio_filter_model import AudioFilterModel
from component.widget_filter.Ui_widget import Ui_Widget
# import component.widget_filter.resources
import component.widget_filter.resources
class ReadOnlyDelegate(QStyledItemDelegate):
@ -800,12 +800,12 @@ if __name__ == "__main__":
# 测试模型更新
def test_update():
# model.set_channel_params(ChannelParams(
# delay=50.0,
# volume=-40.0,
# mix_right=50.0,
# mix_left=50.0
# ))
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)

View File

@ -0,0 +1,257 @@
from PySide6.QtCore import QObject, Signal, Slot
from typing import Dict, Any, Optional
from dataclasses import dataclass
from enum import Enum, auto
from application.application_controller import ApplicationController, ControllerSignalData
from param_struct_test.service_manager import ServiceManager
from param_struct_test.params_service import ParamsService
from component.widget_filter.audio_filter_model import AudioFilterModel
from component.widget_filter.audio_filter_componet import AudioFilterWidget
from component.widget_filter.audio_filter_model import FilterParams, FilterType, ChannelParams
class AudioControllerState(Enum):
"""音频控制器状态"""
IDLE = auto()
UPDATING = auto()
ERROR = auto()
class AudioFilterController(QObject):
CONTROLLER_ID = "audio_filter"
# 定义信号
state_changed = Signal(AudioControllerState) # 状态变化信号
error_occurred = Signal(str) # 错误信号
params_synced = Signal() # 参数同步完成信号
filter_changed = Signal(int, str, float) # 滤波器参数变化信号
channel_changed = Signal(str, float) # 通道参数变化信号
def __init__(self, model: AudioFilterModel):
super().__init__()
self.model = model
self.widget = None
self._state = AudioControllerState.IDLE
self._setup_application_controller()
self._setup_model_connections()
@property
def state(self) -> AudioControllerState:
"""获取当前状态"""
return self._state
@state.setter
def state(self, value: AudioControllerState):
"""设置状态并发送信号"""
if self._state != value:
self._state = value
self.state_changed.emit(value)
def _setup_application_controller(self):
"""设置应用控制器连接"""
app_controller = ApplicationController.instance()
app_controller.register_controller(self.CONTROLLER_ID, self)
app_controller.signal_params_updated.connect(self._on_params_updated)
def _setup_model_connections(self):
pass
"""设置模型信号连接"""
# self.model.dataChanged.connect(self._on_model_data_changed)
# to do:后续看情况调整是否需要单独下发调整的滤波器数据
# self.model.filterAdded.connect(self._on_filter_added)
# self.model.filterRemoved.connect(self._on_filter_removed)
# self.model.filterUpdated.connect(self._on_filter_updated)
# self.model.channelParamsChanged.connect(self._on_channel_params_changed)
def set_widget(self, widget: AudioFilterWidget):
"""设置关联的widget"""
self.widget = widget
self.widget.setModel(self.model)
self._setup_widget_connections()
def _setup_widget_connections(self):
"""设置widget信号连接"""
if self.widget:
pass
# to do:后续看情况调整是否需要单独下发调整的滤波器数据
# self.widget.filter_changed.connect(self._on_widget_filter_changed)
# self.widget.param_changed.connect(self._on_widget_param_changed)
# self.widget.filter_added.connect(self._on_widget_filter_added)
# self.widget.filter_deleted.connect(self._on_widget_filter_deleted)
# self.widget.filter_enabled_changed.connect(self._on_widget_filter_enabled_changed)
@Slot(ControllerSignalData)
def _on_params_updated(self, signal_data: ControllerSignalData):
"""处理来自ApplicationController的参数更新信号"""
if signal_data.controller_id != self.CONTROLLER_ID:
return
try:
self.state = AudioControllerState.UPDATING
data = signal_data.data
# 使用ChannelParams类创建实例
channel_params = ChannelParams(
delay=data.get('delay_data1', 0.0),
volume=data.get('vol_data1', 0.0),
mix_right=data.get('mix_right_data1', 0.0),
mix_left=data.get('mix_left_data1', 0.0)
)
# 更新通道参数
self.model.set_channel_params(channel_params)
# 清除现有滤波器
self.model.filters.clear() # 使用filters列表的clear方法替代clear_filters
# 解析并添加滤波器参数
# filter_index = 1
# while True:
# filter_type_value = data.get(f'filterType1_{filter_index}')
# if filter_type_value is None:
# break
# # 使用FilterParams类创建实例
# filter_params = FilterParams(
# filter_type=FilterType(filter_type_value),
# frequency=data.get(f'fc1_{filter_index}', 0.0),
# q_value=data.get(f'q1_{filter_index}', 0.0),
# gain=data.get(f'gain1_{filter_index}', 0.0),
# slope=data.get(f'slope1_{filter_index}', 0.0)
# )
# self.model.add_filter(filter_params)
# filter_index += 1
self.params_synced.emit()
self.state = AudioControllerState.IDLE
except Exception as e:
self.state = AudioControllerState.ERROR
self.error_occurred.emit(f"Error updating params: {str(e)}")
def sync_to_server(self):
"""同步数据到服务器"""
try:
self.state = AudioControllerState.UPDATING
params = self.model.get_all_data()
ServiceManager.instance().params_service.set_params(params)
except Exception as e:
self.state = AudioControllerState.ERROR
self.error_occurred.emit(f"Error syncing to server: {str(e)}")
def load_from_server(self):
"""从服务器加载数据"""
try:
print("BBBBBB:load_from_server")
self.state = AudioControllerState.UPDATING
ServiceManager.instance().params_service.get_params(self.widget)
except Exception as e:
self.state = AudioControllerState.ERROR
self.error_occurred.emit(f"Error loading from server: {str(e)}")
# 模型信号处理器
def _on_model_data_changed(self):
"""处理模型数据变化"""
if self.widget and self.state != AudioControllerState.UPDATING:
self.widget.set_all_params(self.model.to_widget_params())
# def _on_filter_added(self, index: int):
# """处理滤波器添加"""
# if self.widget:
# filter_params = self.model.get_filter(index)
# if filter_params:
# self.widget.add_filter(filter_params)
# def _on_filter_removed(self, index: int):
# """处理滤波器移除"""
# if self.widget:
# self.widget.remove_filter(index)
# def _on_filter_updated(self, index: int):
# """处理滤波器更新"""
# if self.widget:
# filter_params = self.model.get_filter(index)
# if filter_params:
# self.widget.update_filter(index, filter_params)
# def _on_channel_params_changed(self):
# """处理通道参数变化"""
# if self.widget:
# channel_params = self.model.get_channel_params()
# self.widget.update_channel_params(channel_params)
#########################################################################################
# Widget信号处理器
# def _on_widget_filter_changed(self, index: int, param_name: str, value: float):
# """处理widget滤波器参数变化"""
# try:
# filter_params = self.model.get_filter(index)
# if filter_params:
# setattr(filter_params, param_name, value)
# # to do:按照目前架构,这块的调整是个死循环,后续看具体情况进行解耦
# self.model.update_filter(index, filter_params)
# # self.filter_changed.emit(index, param_name, value)
# except Exception as e:
# self.error_occurred.emit(f"Error updating filter: {str(e)}")
# def _on_widget_param_changed(self, param_name: str, value: float):
# """处理widget通道参数变化"""
# try:
# channel_params = self.model.get_channel_params()
# setattr(channel_params, param_name, value)
# self.model.set_channel_params(channel_params)
# self.channel_changed.emit(param_name, value)
# except Exception as e:
# self.error_occurred.emit(f"Error updating channel params: {str(e)}")
# def _on_widget_filter_added(self, filter_type: str):
# """处理widget添加滤波器"""
# try:
# filter_params = FilterParams(
# filter_type=FilterType[filter_type],
# frequency=0.0,
# q_value=0.0,
# gain=0.0,
# slope=0.0
# )
# self.model.add_filter(filter_params)
# except Exception as e:
# self.error_occurred.emit(f"Error adding filter: {str(e)}")
# def _on_widget_filter_deleted(self, index: int):
# """处理widget删除滤波器"""
# try:
# self.model.remove_filter(index)
# except Exception as e:
# self.error_occurred.emit(f"Error removing filter: {str(e)}")
# def _on_widget_filter_enabled_changed(self, index: int, enabled: bool):
# """处理widget滤波器启用状态变化"""
# try:
# filter_params = self.model.get_filter(index)
# if filter_params:
# filter_params.enabled = enabled
# self.model.update_filter(index, filter_params)
# except Exception as e:
# self.error_occurred.emit(f"Error updating filter state: {str(e)}")
##########################################################################################
# def save_preset(self, filepath: str):
# """保存预设"""
# try:
# self.model.save_to_file(filepath)
# except Exception as e:
# self.error_occurred.emit(f"Error saving preset: {str(e)}")
# def load_preset(self, filepath: str):
# """加载预设"""
# try:
# new_model = AudioFilterModel.load_from_file(filepath)
# self.model = new_model
# self._setup_model_connections()
# if self.widget:
# self.widget.set_all_params(self.model.to_widget_params())
# except Exception as e:
# self.error_occurred.emit(f"Error loading preset: {str(e)}")

@ -1 +1 @@
Subproject commit b130b72db80780cb7ca7636a08fc5052f3a6976f
Subproject commit 1dd0e56a13ecd81d921d2ac4c6e7132c3f9cc587