[feature] 移除配置选项,为项目管理做准备
This commit is contained in:
parent
dc8d0e8bfd
commit
6a5702cf91
BIN
data/database.db
BIN
data/database.db
Binary file not shown.
Binary file not shown.
Binary file not shown.
1
database/database_manager.py
Normal file
1
database/database_manager.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
@ -2,7 +2,7 @@ import sqlite3
|
|||||||
from typing import List, Optional, Tuple
|
from typing import List, Optional, Tuple
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import os
|
import os
|
||||||
from .models import FilterData, ParamData, ConfigData
|
from .models import FilterData, ParamData, ConfigData, ProjectData
|
||||||
|
|
||||||
class DatabaseManager:
|
class DatabaseManager:
|
||||||
_instance = None
|
_instance = None
|
||||||
@ -27,15 +27,50 @@ class DatabaseManager:
|
|||||||
Path(self.db_path).parent.mkdir(parents=True, exist_ok=True)
|
Path(self.db_path).parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
with sqlite3.connect(self.db_path) as conn:
|
with sqlite3.connect(self.db_path) as conn:
|
||||||
conn.executescript("""
|
# 首先创建 projects 表(如果不存在)
|
||||||
CREATE TABLE IF NOT EXISTS configs (
|
conn.execute("""
|
||||||
|
CREATE TABLE IF NOT EXISTS projects (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL UNIQUE,
|
||||||
channel_id INTEGER NOT NULL,
|
description TEXT,
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
UNIQUE(name, channel_id)
|
|
||||||
);
|
);
|
||||||
|
""")
|
||||||
|
|
||||||
|
# 检查 configs 表是否存在
|
||||||
|
cursor = conn.execute("""
|
||||||
|
SELECT name FROM sqlite_master
|
||||||
|
WHERE type='table' AND name='configs';
|
||||||
|
""")
|
||||||
|
|
||||||
|
if cursor.fetchone() is None:
|
||||||
|
# 如果表不存在,创建新表
|
||||||
|
conn.execute("""
|
||||||
|
CREATE TABLE configs (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
channel_id INTEGER NOT NULL,
|
||||||
|
project_id INTEGER,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE(name, channel_id, project_id),
|
||||||
|
FOREIGN KEY (project_id) REFERENCES projects(id)
|
||||||
|
);
|
||||||
|
""")
|
||||||
|
else:
|
||||||
|
# 如果表已存在,检查是否需要添加 project_id 列
|
||||||
|
cursor = conn.execute("PRAGMA table_info(configs)")
|
||||||
|
columns = [row[1] for row in cursor.fetchall()]
|
||||||
|
|
||||||
|
if 'project_id' not in columns:
|
||||||
|
# 添加 project_id 列
|
||||||
|
conn.execute("""
|
||||||
|
ALTER TABLE configs
|
||||||
|
ADD COLUMN project_id INTEGER
|
||||||
|
REFERENCES projects(id);
|
||||||
|
""")
|
||||||
|
|
||||||
|
# 其他表的创建保持不变
|
||||||
|
conn.executescript("""
|
||||||
CREATE TABLE IF NOT EXISTS params (
|
CREATE TABLE IF NOT EXISTS params (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
config_id INTEGER,
|
config_id INTEGER,
|
||||||
@ -119,12 +154,14 @@ class DatabaseManager:
|
|||||||
print(f"load_config filters: {filters}")
|
print(f"load_config filters: {filters}")
|
||||||
return params, filters
|
return params, filters
|
||||||
|
|
||||||
def save_config(self, name: str, channel_id: int, params: ParamData, filters: List[FilterData]) -> int:
|
def save_config(self, name: str, channel_id: int, params: ParamData, filters: List[FilterData], project_id: Optional[int] = None) -> int:
|
||||||
with self.get_connection() as conn:
|
with self.get_connection() as conn:
|
||||||
# 检查是否存在相同的配置
|
# 检查是否存在相同的配置
|
||||||
cursor = conn.execute(
|
cursor = conn.execute(
|
||||||
"SELECT id FROM configs WHERE name = ? AND channel_id = ?",
|
"""SELECT id FROM configs
|
||||||
(name, channel_id)
|
WHERE name = ? AND channel_id = ? AND
|
||||||
|
(project_id = ? OR (project_id IS NULL AND ? IS NULL))""",
|
||||||
|
(name, channel_id, project_id, project_id)
|
||||||
)
|
)
|
||||||
existing_config = cursor.fetchone()
|
existing_config = cursor.fetchone()
|
||||||
|
|
||||||
@ -154,10 +191,10 @@ class DatabaseManager:
|
|||||||
|
|
||||||
return config_id
|
return config_id
|
||||||
else:
|
else:
|
||||||
# 创建新配置(原有的插入逻辑)
|
# 创建新配置
|
||||||
cursor = conn.execute(
|
cursor = conn.execute(
|
||||||
"INSERT INTO configs (name, channel_id) VALUES (?, ?)",
|
"INSERT INTO configs (name, channel_id, project_id) VALUES (?, ?, ?)",
|
||||||
(name, channel_id)
|
(name, channel_id, project_id)
|
||||||
)
|
)
|
||||||
config_id = cursor.lastrowid
|
config_id = cursor.lastrowid
|
||||||
|
|
||||||
@ -245,3 +282,43 @@ class DatabaseManager:
|
|||||||
|
|
||||||
# 保存默认配置
|
# 保存默认配置
|
||||||
self.save_config("Default Config", 1, default_params, default_filters)
|
self.save_config("Default Config", 1, default_params, default_filters)
|
||||||
|
|
||||||
|
def add_project(self, name: str, description: str) -> int:
|
||||||
|
with self.get_connection() as conn:
|
||||||
|
cursor = conn.execute(
|
||||||
|
"INSERT INTO projects (name, description) VALUES (?, ?)",
|
||||||
|
(name, description)
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
return cursor.lastrowid
|
||||||
|
|
||||||
|
def get_all_projects(self) -> List[ProjectData]:
|
||||||
|
with self.get_connection() as conn:
|
||||||
|
cursor = conn.execute(
|
||||||
|
"SELECT id, name, description, created_at FROM projects"
|
||||||
|
)
|
||||||
|
return [ProjectData(*row) for row in cursor.fetchall()]
|
||||||
|
|
||||||
|
def update_project_name(self, project_id: int, new_name: str) -> bool:
|
||||||
|
"""更新项目名称"""
|
||||||
|
try:
|
||||||
|
with self.get_connection() as conn:
|
||||||
|
cursor = conn.execute(
|
||||||
|
"UPDATE projects SET name = ? WHERE id = ?",
|
||||||
|
(new_name, project_id)
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
return cursor.rowcount > 0
|
||||||
|
except sqlite3.IntegrityError:
|
||||||
|
# 项目名已存在
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_project_configs(self, project_id: int) -> List[ConfigData]:
|
||||||
|
"""获取项目关联的所有配置"""
|
||||||
|
with self.get_connection() as conn:
|
||||||
|
cursor = conn.execute(
|
||||||
|
"""SELECT id, name, channel_id, created_at, project_id
|
||||||
|
FROM configs WHERE project_id = ?""",
|
||||||
|
(project_id,)
|
||||||
|
)
|
||||||
|
return [ConfigData(*row) for row in cursor.fetchall()]
|
||||||
|
|||||||
@ -30,3 +30,12 @@ class ConfigData:
|
|||||||
name: str
|
name: str
|
||||||
channel_id: int
|
channel_id: int
|
||||||
created_at: str
|
created_at: str
|
||||||
|
project_id: Optional[int] = None
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ProjectData:
|
||||||
|
id: Optional[int]
|
||||||
|
name: str
|
||||||
|
description: str
|
||||||
|
created_at: str = None
|
||||||
|
configs: List[ConfigData] = None
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
widgets/__pycache__/project_dialog.cpython-313.pyc
Normal file
BIN
widgets/__pycache__/project_dialog.cpython-313.pyc
Normal file
Binary file not shown.
@ -3,12 +3,13 @@ from PySide6.QtCore import Qt
|
|||||||
from widgets.Ui_widget import Ui_Widget
|
from widgets.Ui_widget import Ui_Widget
|
||||||
from database.db_manager import DatabaseManager
|
from database.db_manager import DatabaseManager
|
||||||
from database.models import FilterData, ParamData, ConfigData
|
from database.models import FilterData, ParamData, ConfigData
|
||||||
from typing import List
|
from typing import List, Optional
|
||||||
|
|
||||||
class AudioFilterModel:
|
class AudioFilterModel:
|
||||||
def __init__(self, db_manager: DatabaseManager):
|
def __init__(self, db_manager: DatabaseManager):
|
||||||
self.db_manager = db_manager
|
self.db_manager = db_manager
|
||||||
self.current_config_id: Optional[int] = None
|
self.current_config_id: Optional[int] = None
|
||||||
|
self.current_project_id: Optional[int] = None # 添加当前项目ID
|
||||||
self.current_channel_id: int = 1 # 添加当前通道ID
|
self.current_channel_id: int = 1 # 添加当前通道ID
|
||||||
self.filters: List[FilterData] = []
|
self.filters: List[FilterData] = []
|
||||||
self.params: ParamData = ParamData(
|
self.params: ParamData = ParamData(
|
||||||
@ -38,7 +39,13 @@ class AudioFilterModel:
|
|||||||
for filter_data in self.filters:
|
for filter_data in self.filters:
|
||||||
print(f"save_config filter_data.channel_id: {filter_data.channel_id}")
|
print(f"save_config filter_data.channel_id: {filter_data.channel_id}")
|
||||||
filter_data.channel_id = self.current_channel_id
|
filter_data.channel_id = self.current_channel_id
|
||||||
return self.db_manager.save_config(name, self.current_channel_id, self.params, self.filters)
|
return self.db_manager.save_config(
|
||||||
|
name,
|
||||||
|
self.current_channel_id,
|
||||||
|
self.params,
|
||||||
|
self.filters,
|
||||||
|
self.current_project_id # 添加项目ID
|
||||||
|
)
|
||||||
|
|
||||||
def update_filter(self, index: int, **kwargs):
|
def update_filter(self, index: int, **kwargs):
|
||||||
if 0 <= index < len(self.filters):
|
if 0 <= index < len(self.filters):
|
||||||
@ -60,6 +67,10 @@ class AudioFilterModel:
|
|||||||
if self.current_config_id:
|
if self.current_config_id:
|
||||||
self.db_manager.update_params(self.current_config_id, self.params)
|
self.db_manager.update_params(self.current_config_id, self.params)
|
||||||
|
|
||||||
|
def set_project(self, project_id: Optional[int]):
|
||||||
|
"""设置当前项目"""
|
||||||
|
self.current_project_id = project_id
|
||||||
|
|
||||||
class FilterTypeDialog(QDialog):
|
class FilterTypeDialog(QDialog):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
@ -254,15 +265,7 @@ class AudioFilterWidget(QWidget):
|
|||||||
self.model = AudioFilterModel(self.db_manager)
|
self.model = AudioFilterModel(self.db_manager)
|
||||||
self.model.current_channel_id = channel_id # 设置当前通道ID
|
self.model.current_channel_id = channel_id # 设置当前通道ID
|
||||||
|
|
||||||
# 加载该通道的所有配置
|
# 移除配置选择相关代码
|
||||||
configs = self.db_manager.get_all_configs()
|
|
||||||
if configs:
|
|
||||||
# 获取当前通道的所有配置
|
|
||||||
channel_configs = [config for config in configs if config.channel_id == channel_id]
|
|
||||||
if channel_configs:
|
|
||||||
# 可以让用户选择要加载哪个配置
|
|
||||||
self.show_config_selection_dialog(channel_configs)
|
|
||||||
|
|
||||||
self.controller = AudioFilterController(self.model, self)
|
self.controller = AudioFilterController(self.model, self)
|
||||||
self.update_view()
|
self.update_view()
|
||||||
|
|
||||||
@ -445,31 +448,3 @@ class AudioFilterWidget(QWidget):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
print("输入的值无效,请输入数字")
|
print("输入的值无效,请输入数字")
|
||||||
|
|
||||||
def show_config_selection_dialog(self, configs: List[ConfigData]):
|
|
||||||
dialog = QDialog(self)
|
|
||||||
dialog.setWindowTitle("选择配置")
|
|
||||||
layout = QVBoxLayout()
|
|
||||||
|
|
||||||
combo = QComboBox()
|
|
||||||
for config in configs:
|
|
||||||
combo.addItem(f"{config.name} (创建于: {config.created_at})", config.id)
|
|
||||||
|
|
||||||
layout.addWidget(QLabel("请选择要加载的配置:"))
|
|
||||||
layout.addWidget(combo)
|
|
||||||
|
|
||||||
buttons = QHBoxLayout()
|
|
||||||
ok_button = QPushButton("确定")
|
|
||||||
cancel_button = QPushButton("取消")
|
|
||||||
|
|
||||||
ok_button.clicked.connect(dialog.accept)
|
|
||||||
cancel_button.clicked.connect(dialog.reject)
|
|
||||||
|
|
||||||
buttons.addWidget(ok_button)
|
|
||||||
buttons.addWidget(cancel_button)
|
|
||||||
layout.addLayout(buttons)
|
|
||||||
|
|
||||||
dialog.setLayout(layout)
|
|
||||||
|
|
||||||
if dialog.exec() == QDialog.Accepted:
|
|
||||||
selected_config_id = combo.currentData()
|
|
||||||
self.model.load_config(selected_config_id)
|
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
import sys
|
import sys
|
||||||
from PySide6.QtWidgets import (QApplication, QWidget, QPushButton, QGridLayout,
|
from PySide6.QtWidgets import (QApplication, QWidget, QPushButton, QGridLayout,
|
||||||
QVBoxLayout, QHBoxLayout, QCheckBox, QComboBox,
|
QVBoxLayout, QHBoxLayout, QCheckBox, QComboBox,
|
||||||
QLabel, QSlider, QFrame, QGroupBox, QListView)
|
QLabel, QSlider, QFrame, QGroupBox, QListView, QListWidgetItem, QMessageBox)
|
||||||
from PySide6.QtCore import Qt, QSize
|
from PySide6.QtCore import Qt, QSize
|
||||||
from PySide6.QtGui import QIcon
|
from PySide6.QtGui import QIcon, QStandardItemModel, QStandardItem
|
||||||
from widgets.audio_filter_widget import AudioFilterWidget
|
from widgets.audio_filter_widget import AudioFilterWidget
|
||||||
|
from widgets.project_dialog import AddProjectDialog
|
||||||
|
import sqlite3
|
||||||
|
from database.db_manager import DatabaseManager # 添加这行导入
|
||||||
|
|
||||||
class ChannelButton(QWidget):
|
class ChannelButton(QWidget):
|
||||||
def __init__(self, channel_num):
|
def __init__(self, channel_num):
|
||||||
@ -120,9 +123,13 @@ class ChannelButton(QWidget):
|
|||||||
class AVAS_WIDGET(QWidget):
|
class AVAS_WIDGET(QWidget):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
# 初始化数据库管理器
|
||||||
|
self.db_manager = DatabaseManager()
|
||||||
|
|
||||||
self.setWindowTitle("AVAS")
|
self.setWindowTitle("AVAS")
|
||||||
self.is_panel_visible = True # 添加状态标记
|
self.is_panel_visible = True # 添加状态标记
|
||||||
self.setup_ui()
|
self.setup_ui()
|
||||||
|
self.setup_connections()
|
||||||
|
|
||||||
def setup_ui(self):
|
def setup_ui(self):
|
||||||
# 创建主水平布局
|
# 创建主水平布局
|
||||||
@ -241,9 +248,9 @@ class AVAS_WIDGET(QWidget):
|
|||||||
|
|
||||||
# 添加工具栏按钮
|
# 添加工具栏按钮
|
||||||
toolbar = QHBoxLayout()
|
toolbar = QHBoxLayout()
|
||||||
add_btn = QPushButton("添加")
|
self.add_btn = QPushButton("添加")
|
||||||
delete_btn = QPushButton("删除")
|
self.delete_btn = QPushButton("删除")
|
||||||
refresh_btn = QPushButton("刷新")
|
self.refresh_btn = QPushButton("刷新")
|
||||||
|
|
||||||
# 设置按钮样式
|
# 设置按钮样式
|
||||||
button_style = """
|
button_style = """
|
||||||
@ -262,13 +269,13 @@ class AVAS_WIDGET(QWidget):
|
|||||||
background-color: #303030;
|
background-color: #303030;
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
add_btn.setStyleSheet(button_style)
|
self.add_btn.setStyleSheet(button_style)
|
||||||
delete_btn.setStyleSheet(button_style)
|
self.delete_btn.setStyleSheet(button_style)
|
||||||
refresh_btn.setStyleSheet(button_style)
|
self.refresh_btn.setStyleSheet(button_style)
|
||||||
|
|
||||||
toolbar.addWidget(add_btn)
|
toolbar.addWidget(self.add_btn)
|
||||||
toolbar.addWidget(delete_btn)
|
toolbar.addWidget(self.delete_btn)
|
||||||
toolbar.addWidget(refresh_btn)
|
toolbar.addWidget(self.refresh_btn)
|
||||||
|
|
||||||
# 组装面板
|
# 组装面板
|
||||||
layout.addLayout(toolbar)
|
layout.addLayout(toolbar)
|
||||||
@ -339,3 +346,47 @@ class AVAS_WIDGET(QWidget):
|
|||||||
frame.setLayout(layout)
|
frame.setLayout(layout)
|
||||||
return frame
|
return frame
|
||||||
|
|
||||||
|
def setup_connections(self):
|
||||||
|
# 假设添加按钮的变量名是 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)
|
||||||
|
|
||||||
|
|||||||
46
widgets/project_dialog.py
Normal file
46
widgets/project_dialog.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
from PySide6.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QMessageBox
|
||||||
|
from PySide6.QtCore import Qt
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
|
class AddProjectDialog(QDialog):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setup_ui()
|
||||||
|
|
||||||
|
def setup_ui(self):
|
||||||
|
self.setWindowTitle("添加项目")
|
||||||
|
layout = QVBoxLayout()
|
||||||
|
|
||||||
|
# 项目名称输入
|
||||||
|
self.name_label = QLabel("项目名称:")
|
||||||
|
self.name_edit = QLineEdit()
|
||||||
|
self.name_edit.setPlaceholderText("请输入项目名称")
|
||||||
|
|
||||||
|
# 项目描述输入
|
||||||
|
self.desc_label = QLabel("项目描述:")
|
||||||
|
self.desc_edit = QTextEdit()
|
||||||
|
self.desc_edit.setPlaceholderText("请输入项目描述")
|
||||||
|
|
||||||
|
# 按钮
|
||||||
|
self.btn_layout = QHBoxLayout()
|
||||||
|
self.ok_btn = QPushButton("确定")
|
||||||
|
self.cancel_btn = QPushButton("取消")
|
||||||
|
|
||||||
|
self.btn_layout.addWidget(self.ok_btn)
|
||||||
|
self.btn_layout.addWidget(self.cancel_btn)
|
||||||
|
|
||||||
|
# 添加到主布局
|
||||||
|
layout.addWidget(self.name_label)
|
||||||
|
layout.addWidget(self.name_edit)
|
||||||
|
layout.addWidget(self.desc_label)
|
||||||
|
layout.addWidget(self.desc_edit)
|
||||||
|
layout.addLayout(self.btn_layout)
|
||||||
|
|
||||||
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
# 连接信号
|
||||||
|
self.ok_btn.clicked.connect(self.accept)
|
||||||
|
self.cancel_btn.clicked.connect(self.reject)
|
||||||
|
|
||||||
|
def get_project_data(self) -> Tuple[str, str]:
|
||||||
|
return self.name_edit.text().strip(), self.desc_edit.toPlainText().strip()
|
||||||
Loading…
Reference in New Issue
Block a user