178 lines
5.1 KiB
Python
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}")
|