brisonus_app_eq/widgets/avas_widget.py

421 lines
14 KiB
Python
Raw Normal View History

2025-02-15 21:20:54 +08:00
import sys
from PySide6.QtWidgets import (QApplication, QWidget, QPushButton, QGridLayout,
QVBoxLayout, QHBoxLayout, QCheckBox, QComboBox,
QLabel, QSlider, QFrame, QGroupBox, QListView, QListWidgetItem, QMessageBox)
2025-02-16 21:53:51 +08:00
from PySide6.QtCore import Qt, QSize
from PySide6.QtGui import QIcon, QStandardItemModel, QStandardItem
2025-02-15 21:20:54 +08:00
from widgets.audio_filter_widget import AudioFilterWidget
from widgets.project_dialog import AddProjectDialog
import sqlite3
from database.db_manager import DatabaseManager # 添加这行导入
from widgets.avas_controller import AVASController
2025-02-15 21:20:54 +08:00
class ChannelButton(QWidget):
def __init__(self, channel_num):
super().__init__()
self.channel_num = channel_num # 保存通道号
2025-02-15 21:20:54 +08:00
# Create GroupBox for the channel
self.group = QGroupBox(f"CH{channel_num}")
layout = QVBoxLayout()
layout.setSpacing(2)
# Channel button
self.channel_btn = QPushButton(f"Channel {channel_num}")
self.channel_btn.setFixedHeight(25)
# Store audio filter window reference
self.filter_window = None
# Controls container with two rows
controls_layout = QGridLayout()
controls_layout.setSpacing(2)
# SOLO row
self.solo_cb = QCheckBox("S")
self.solo_btn = QPushButton("SOLO")
self.solo_btn.setFixedHeight(20)
controls_layout.addWidget(self.solo_cb, 0, 0)
controls_layout.addWidget(self.solo_btn, 0, 1)
# MUTE row
self.mute_cb = QCheckBox("M")
self.mute_btn = QPushButton("MUTE")
self.mute_btn.setFixedHeight(20)
controls_layout.addWidget(self.mute_cb, 1, 0)
controls_layout.addWidget(self.mute_btn, 1, 1)
# Add widgets to main layout
layout.addWidget(self.channel_btn)
layout.addLayout(controls_layout)
# Set GroupBox layout
self.group.setLayout(layout)
# Main layout
main_layout = QVBoxLayout()
main_layout.addWidget(self.group)
main_layout.setContentsMargins(2, 2, 2, 2)
self.setLayout(main_layout)
# Set fixed size for the channel widget
self.setFixedSize(110, 100)
# Style
self.channel_btn.setStyleSheet("""
QPushButton {
background-color: #404040;
color: white;
border: 1px solid #505050;
}
QPushButton:hover {
background-color: #505050;
}
""")
button_style = """
QPushButton {
background-color: #303030;
color: white;
border: 1px solid #404040;
padding: 2px;
}
QPushButton:hover {
background-color: #404040;
}
"""
self.solo_btn.setStyleSheet(button_style)
self.mute_btn.setStyleSheet(button_style)
self.group.setStyleSheet("""
QGroupBox {
border: 1px solid #505050;
margin-top: 0.5em;
padding: 2px;
}
QCheckBox {
spacing: 2px;
}
""")
# Connect button click event
self.channel_btn.clicked.connect(self.show_filter_window)
def show_filter_window(self):
2025-02-16 21:24:51 +08:00
# 如果窗口已存在且可见,则关闭它
if self.filter_window and self.filter_window.isVisible():
self.filter_window.raise_()
self.filter_window.activateWindow()
else:
# 如果窗口不存在或已关闭,创建新窗口
self.filter_window = AudioFilterWidget(channel_id=self.channel_num)
2025-02-15 21:20:54 +08:00
self.filter_window.setWindowTitle(f"Channel {self.group.title()} Filter Settings")
2025-02-16 21:24:51 +08:00
# 监听窗口关闭事件,在窗口关闭时重置 filter_window
self.filter_window.destroyed.connect(self._on_filter_window_closed)
2025-02-15 21:20:54 +08:00
self.filter_window.show()
2025-02-16 21:24:51 +08:00
def _on_filter_window_closed(self):
"""当滤波器窗口关闭时调用"""
self.filter_window = None
2025-02-15 21:20:54 +08:00
class AVAS_WIDGET(QWidget):
def __init__(self):
super().__init__()
# 初始化数据库管理器
self.db_manager = DatabaseManager()
# 初始化控制器
self.controller = AVASController(self.db_manager, self)
2025-02-15 21:20:54 +08:00
self.setWindowTitle("AVAS")
self.is_panel_visible = True
2025-02-15 21:20:54 +08:00
self.setup_ui()
self.setup_connections()
2025-02-15 21:20:54 +08:00
def setup_ui(self):
2025-02-16 21:53:51 +08:00
# 创建主水平布局
main_layout = QHBoxLayout()
# 左侧项目信息面板
self.left_panel = self.create_project_panel()
# 创建切换按钮容器
toggle_container = QVBoxLayout()
self.toggle_button = QPushButton("") # 使用箭头符号
self.toggle_button.setFixedSize(20, 60)
self.toggle_button.clicked.connect(self.controller.toggle_panel)
2025-02-16 21:53:51 +08:00
self.toggle_button.setStyleSheet("""
QPushButton {
background-color: #404040;
color: white;
border: 1px solid #505050;
border-radius: 3px;
}
QPushButton:hover {
background-color: #505050;
}
QPushButton:pressed {
background-color: #303030;
}
""")
toggle_container.addStretch()
toggle_container.addWidget(self.toggle_button)
toggle_container.addStretch()
2025-02-15 21:20:54 +08:00
2025-02-16 21:53:51 +08:00
# 右侧原有内容面板
right_panel = QVBoxLayout()
# 添加原有的通道按钮网格
2025-02-15 21:20:54 +08:00
channels_layout = QGridLayout()
for i in range(24):
row = i // 8
col = i % 8
channel = ChannelButton(i + 1)
channels_layout.addWidget(channel, row, col)
2025-02-16 21:53:51 +08:00
# 中间部分
2025-02-15 21:20:54 +08:00
middle_layout = QHBoxLayout()
param_matrix = self.create_parameter_matrix()
filter_controls = self.create_filter_controls()
middle_layout.addWidget(param_matrix, stretch=2)
middle_layout.addWidget(filter_controls, stretch=1)
2025-02-16 21:53:51 +08:00
# 底部按钮
2025-02-15 21:20:54 +08:00
bottom_layout = QHBoxLayout()
clean_btn = QPushButton("Clean")
send_btn = QPushButton("Send")
enable_cb = QCheckBox("Enable")
bottom_layout.addStretch()
bottom_layout.addWidget(clean_btn)
bottom_layout.addWidget(send_btn)
bottom_layout.addWidget(enable_cb)
2025-02-16 21:53:51 +08:00
# 将所有部分添加到右侧面板
right_panel.addLayout(channels_layout)
right_panel.addLayout(middle_layout)
right_panel.addLayout(bottom_layout)
# 添加左右面板和切换按钮到主布局
main_layout.addWidget(self.left_panel, stretch=1)
main_layout.addLayout(toggle_container)
main_layout.addLayout(right_panel, stretch=4)
2025-02-15 21:20:54 +08:00
self.setLayout(main_layout)
2025-02-16 21:53:51 +08:00
def toggle_panel(self):
"""切换左侧面板的显示状态"""
self.is_panel_visible = not self.is_panel_visible
self.left_panel.setVisible(self.is_panel_visible)
# 更新切换按钮的箭头方向
if self.is_panel_visible:
self.toggle_button.setText("")
else:
self.toggle_button.setText("")
def create_project_panel(self):
"""创建左侧项目信息面板"""
panel = QGroupBox("项目信息")
layout = QVBoxLayout()
# 创建列表视图
self.project_list = QListView()
self.project_list.setViewMode(QListView.ViewMode.IconMode)
self.project_list.setIconSize(QSize(80, 80))
self.project_list.setSpacing(10)
self.project_list.setResizeMode(QListView.ResizeMode.Adjust)
self.project_list.setMovement(QListView.Movement.Static)
# 设置样式
self.project_list.setStyleSheet("""
QListView {
background-color: #2D2D2D;
border: none;
border-radius: 4px;
padding: 5px;
}
QListView::item {
background-color: #3D3D3D;
border-radius: 6px;
margin: 5px;
}
QListView::item:selected {
background-color: #4A4A4A;
}
QListView::item:hover {
background-color: #454545;
}
""")
# 添加工具栏按钮
toolbar = QHBoxLayout()
self.add_btn = QPushButton("添加")
self.delete_btn = QPushButton("删除")
self.refresh_btn = QPushButton("刷新")
2025-02-16 21:53:51 +08:00
# 设置按钮样式
button_style = """
QPushButton {
background-color: #404040;
color: white;
border: 1px solid #505050;
border-radius: 3px;
padding: 5px 10px;
min-width: 60px;
}
QPushButton:hover {
background-color: #505050;
}
QPushButton:pressed {
background-color: #303030;
}
"""
self.add_btn.setStyleSheet(button_style)
self.delete_btn.setStyleSheet(button_style)
self.refresh_btn.setStyleSheet(button_style)
2025-02-16 21:53:51 +08:00
toolbar.addWidget(self.add_btn)
toolbar.addWidget(self.delete_btn)
toolbar.addWidget(self.refresh_btn)
2025-02-16 21:53:51 +08:00
# 组装面板
layout.addLayout(toolbar)
layout.addWidget(self.project_list)
panel.setLayout(layout)
# 设置面板样式
panel.setStyleSheet("""
QGroupBox {
background-color: #2D2D2D;
border: 1px solid #505050;
border-radius: 6px;
margin-top: 1ex;
padding: 10px;
color: white;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top center;
padding: 0 3px;
}
""")
return panel
2025-02-15 21:20:54 +08:00
def create_parameter_matrix(self):
frame = QFrame()
frame.setFrameStyle(QFrame.Box)
layout = QGridLayout()
# Add headers and parameter rows
for i in range(24): # 24 channels
layout.addWidget(QLabel(f"Ch{i+1}"), i+1, 0)
# Add parameter controls for each channel
for j in range(5): # Example: 5 parameters per channel
layout.addWidget(QSlider(Qt.Horizontal), i+1, j+1)
frame.setLayout(layout)
return frame
def create_filter_controls(self):
frame = QFrame()
frame.setFrameStyle(QFrame.Box)
layout = QVBoxLayout()
# Filter selection
filter_select = QComboBox()
filter_select.addItems(["Filter 1", "Filter 2", "Filter 3"])
# Filter type radio buttons
filter_types = QVBoxLayout()
types = ["Pink-Pin", "Bass Setting", "Stereo Surround", "None"]
for type_name in types:
filter_types.addWidget(QCheckBox(type_name))
# Sliders
sliders_layout = QVBoxLayout()
slider_labels = ["Input Level", "Freq", "Gain"]
for label in slider_labels:
sliders_layout.addWidget(QLabel(label))
sliders_layout.addWidget(QSlider(Qt.Horizontal))
layout.addWidget(QLabel("Filter Select"))
layout.addWidget(filter_select)
layout.addLayout(filter_types)
layout.addLayout(sliders_layout)
frame.setLayout(layout)
return frame
def setup_connections(self):
"""设置信号连接"""
# 连接控制器信号
self.controller.channel_selected.connect(self.on_channel_selected)
self.controller.panel_toggled.connect(self.on_panel_toggled)
# 连接切换按钮
self.toggle_button.clicked.connect(self.controller.toggle_panel)
# 假设添加按钮的变量名是 add_btn
self.add_btn.clicked.connect(self.add_project)
def add_project(self):
dialog = AddProjectDialog(self)
if dialog.exec():
name, description = dialog.get_project_data()
# 验证输入
if not name:
QMessageBox.warning(self, "警告", "项目名称不能为空!")
return
try:
# 保存到数据库
project_id = self.db_manager.add_project(name, description)
# 更新项目列表
self.update_project_list()
QMessageBox.information(self, "成功", "项目添加成功!")
except sqlite3.IntegrityError:
QMessageBox.warning(self, "警告", "项目名称已存在!")
except Exception as e:
QMessageBox.critical(self, "错误", f"添加项目失败:{str(e)}")
def update_project_list(self):
"""更新项目列表显示"""
# 创建新的模型
model = QStandardItemModel()
self.project_list.setModel(model)
# 获取所有项目
projects = self.db_manager.get_all_projects()
# 创建项目列表项
for project in projects:
item = QStandardItem(project.name)
item.setData(project.id, Qt.UserRole) # 存储项目ID
item.setToolTip(project.description) # 显示项目描述为提示
model.appendRow(item)
def on_channel_selected(self, channel_num: int):
"""处理通道选择事件"""
# 更新UI显示
pass
def on_panel_toggled(self, is_visible: bool):
"""处理面板切换事件"""
# 更新UI布局
self.adjustSize()
def closeEvent(self, event):
"""窗口关闭事件"""
# 关闭所有打开的滤波器窗口
self.controller.close_all_filter_windows()
super().closeEvent(event)