PCM_Viewer/data_model.py

178 lines
5.1 KiB
Python

"""
数据模型模块
"""
from PyQt6.QtCore import QObject, pyqtSignal as Signal, pyqtProperty as Property, pyqtSlot as Slot
from typing import Dict, List, Optional
import json
class TextItem(QObject):
"""文本项数据模型"""
valueChanged = Signal(str)
def __init__(self, parent=None):
super().__init__(parent)
self._field_name: str = ""
self._x: float = 0.0
self._y: float = 0.0
self._font_size: int = 16
self._color: str = "#FFFFFF"
self._value: str = "--"
def getFieldName(self):
return self._field_name
def setFieldName(self, value: str):
if self._field_name != value:
self._field_name = value
self.valueChanged.emit(self._field_name)
fieldName = Property(str, getFieldName, setFieldName, notify=valueChanged)
def getX(self):
return self._x
def setX(self, value: float):
if self._x != value:
self._x = value
self.valueChanged.emit(str(self._x))
x = Property(float, getX, setX, notify=valueChanged)
def getY(self):
return self._y
def setY(self, value: float):
if self._y != value:
self._y = value
self.valueChanged.emit(str(self._y))
y = Property(float, getY, setY, notify=valueChanged)
def getFontSize(self):
return self._font_size
def setFontSize(self, value: int):
if self._font_size != value:
self._font_size = value
self.valueChanged.emit(str(self._font_size))
fontSize = Property(int, getFontSize, setFontSize, notify=valueChanged)
def getColor(self):
return self._color
def setColor(self, value: str):
if self._color != value:
self._color = value
self.valueChanged.emit(self._color)
color = Property(str, getColor, setColor, notify=valueChanged)
def getValue(self):
return self._value
def setValue(self, v: str):
if self._value != v:
self._value = v
self.valueChanged.emit(self._value)
value = Property(str, getValue, setValue, notify=valueChanged)
def toDict(self) -> dict:
"""转换为字典"""
return {
"fieldName": self._field_name,
"x": self._x,
"y": self._y,
"fontSize": self._font_size,
"color": self._color
}
def fromDict(self, data: dict):
"""从字典加载"""
self._field_name = data.get("fieldName", "")
self._x = data.get("x", 0.0)
self._y = data.get("y", 0.0)
self._font_size = data.get("fontSize", 16)
self._color = data.get("color", "#FFFFFF")
class DataModel(QObject):
"""数据模型,管理文本项和数据更新"""
textItemsChanged = Signal()
def __init__(self, parent=None):
super().__init__(parent)
self._text_items: List[TextItem] = []
self._data_cache: Dict[str, str] = {}
def getTextItems(self):
return self._text_items
textItems = Property(list, getTextItems, notify=textItemsChanged)
@Slot(result='QObject*')
def addTextItem(self):
"""添加文本项"""
item = TextItem(self)
self._text_items.append(item)
self.textItemsChanged.emit()
return item
@Slot(int)
def removeTextItem(self, index: int):
"""删除文本项"""
if 0 <= index < len(self._text_items):
item = self._text_items.pop(index)
item.deleteLater()
self.textItemsChanged.emit()
@Slot(int, result='QObject*')
def getTextItem(self, index: int):
"""获取文本项"""
if 0 <= index < len(self._text_items):
return self._text_items[index]
return None
@Slot(dict)
def updateData(self, data: Dict[str, any]):
"""更新数据"""
self._data_cache = {str(k): str(v) for k, v in data.items()}
# 更新所有文本项的值
for item in self._text_items:
field_name = item.fieldName
if field_name in self._data_cache:
item.value = self._data_cache[field_name]
else:
item.value = "--"
@Slot(result=str)
def toJson(self) -> str:
"""导出为 JSON"""
data = {
"textItems": [item.toDict() for item in self._text_items]
}
return json.dumps(data, indent=2, ensure_ascii=False)
@Slot(str)
def fromJson(self, json_str: str):
"""从 JSON 加载"""
try:
data = json.loads(json_str)
# 清空现有项
for item in self._text_items:
item.deleteLater()
self._text_items.clear()
# 加载新项
for item_data in data.get("textItems", []):
item = TextItem(self)
item.fromDict(item_data)
self._text_items.append(item)
self.textItemsChanged.emit()
except Exception as e:
print(f"加载 JSON 失败: {e}")