SIT/ui/widgets/mapping_graph_widget.py

149 lines
4.7 KiB
Python
Raw Permalink Normal View History

2026-01-29 09:22:54 +00:00
"""
映射图管理控件
结合图形化编辑器和列表管理
"""
from PyQt5.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
QSplitter, QGroupBox, QListWidget, QListWidgetItem,
QMessageBox, QLabel
)
from PyQt5.QtCore import Qt, pyqtSignal
from controllers.mapping_controller import MappingController
from controllers.field_controller import FieldController
from ui.widgets.graph_view_widget import GraphViewWidget
from utils.logger import get_logger
logger = get_logger(__name__)
class MappingManagementWidget(QWidget):
"""映射管理控件"""
mapping_selected = pyqtSignal(object)
def __init__(self, mapping_controller: MappingController,
field_controller: FieldController):
super().__init__()
self.mapping_controller = mapping_controller
self.field_controller = field_controller
self.current_mapping = None
self.init_ui()
self.load_mappings()
def init_ui(self):
"""初始化UI"""
main_layout = QVBoxLayout(self)
# 工具栏
toolbar_layout = QHBoxLayout()
self.add_mapping_btn = QPushButton("新建映射")
self.add_mapping_btn.clicked.connect(self.on_add_mapping)
self.delete_mapping_btn = QPushButton("删除映射")
self.delete_mapping_btn.clicked.connect(self.on_delete_mapping)
self.auto_layout_btn = QPushButton("自动布局")
self.auto_layout_btn.clicked.connect(self.on_auto_layout)
self.refresh_btn = QPushButton("刷新")
self.refresh_btn.clicked.connect(self.load_mappings)
toolbar_layout.addWidget(self.add_mapping_btn)
toolbar_layout.addWidget(self.delete_mapping_btn)
toolbar_layout.addWidget(self.auto_layout_btn)
toolbar_layout.addWidget(self.refresh_btn)
toolbar_layout.addStretch()
main_layout.addLayout(toolbar_layout)
# 分割器
splitter = QSplitter(Qt.Horizontal)
# 左侧:映射列表
left_widget = QWidget()
left_layout = QVBoxLayout(left_widget)
list_label = QLabel("映射列表:")
left_layout.addWidget(list_label)
self.mapping_list = QListWidget()
self.mapping_list.itemClicked.connect(self.on_mapping_clicked)
left_layout.addWidget(self.mapping_list)
# 右侧:图形化视图
right_widget = QWidget()
right_layout = QVBoxLayout(right_widget)
graph_label = QLabel("映射图:")
right_layout.addWidget(graph_label)
self.graph_view = GraphViewWidget()
right_layout.addWidget(self.graph_view)
splitter.addWidget(left_widget)
splitter.addWidget(right_widget)
splitter.setStretchFactor(0, 1)
splitter.setStretchFactor(1, 3)
main_layout.addWidget(splitter)
def load_mappings(self):
"""加载映射列表"""
self.mapping_list.clear()
# 加载映射图
graph = self.mapping_controller.get_mapping_graph()
if graph:
self.graph_view.load_graph(graph)
# 显示边(映射)列表
for edge in graph.edges:
item_text = f"{edge.mapping.source_field.full_name} -> {edge.mapping.target_field.full_name}"
item = QListWidgetItem(item_text)
item.setData(Qt.UserRole, edge.mapping)
self.mapping_list.addItem(item)
def on_mapping_clicked(self, item: QListWidgetItem):
"""映射被点击"""
mapping = item.data(Qt.UserRole)
if mapping:
self.current_mapping = mapping
self.mapping_selected.emit(mapping)
def on_add_mapping(self):
"""新建映射"""
from ui.dialogs.mapping_dialog import MappingDialog
dialog = MappingDialog(self)
if dialog.exec_():
self.load_mappings()
def on_delete_mapping(self):
"""删除映射"""
if not self.current_mapping:
QMessageBox.warning(self, "警告", "请先选择要删除的映射")
return
reply = QMessageBox.question(
self,
"确认删除",
"确定要删除该映射吗?",
QMessageBox.Yes | QMessageBox.No
)
if reply == QMessageBox.Yes:
if hasattr(self.current_mapping, 'id'):
success, msg = self.mapping_controller.delete_mapping(self.current_mapping.id)
if success:
QMessageBox.information(self, "成功", msg)
self.load_mappings()
else:
QMessageBox.warning(self, "失败", msg)
def on_auto_layout(self):
"""自动布局"""
self.graph_view.auto_layout()