7e76cffc88
- SettingsTab: chamber ID, master CSV mapping, wafer behavior toggle, light/dark mode toggle, Edit CSV Metadata dialog - StatusTab: connection status, wafer info, activity log (blank until Detect Wafer fires) - DataTab: empty state, ready for parsed data - HomePage: side rail buttons dispatch device actions and jump to Status tab; selectedSideActionIndex defaults to -1 (nothing active on startup) - DeviceController registered as QML context property in main.py - LocalSettings: added status persistence fields - Theme: added subheadingColor and disabledText - Added serialcomm/ package and backend data/graph modules - gitignore: added build/, dist/, *.spec
85 lines
2.6 KiB
Python
85 lines
2.6 KiB
Python
"""QAbstractTableModel for displaying parsed wafer temperature data in QML."""
|
||
|
||
from __future__ import annotations
|
||
|
||
import logging
|
||
from typing import Any
|
||
|
||
from PySide6.QtCore import QAbstractTableModel, Qt
|
||
|
||
log = logging.getLogger(__name__)
|
||
|
||
# Column roles for the temperature data table
|
||
ROW_ROLE = Qt.ItemDataRole.UserRole + 1
|
||
COL_ROLE = Qt.ItemDataRole.UserRole + 2
|
||
|
||
|
||
class TemperatureTableModel(QAbstractTableModel):
|
||
"""Table model for parsed wafer temperature data.
|
||
|
||
Exposes a 2D list of temperature strings to QML TableView.
|
||
Column 0 = row index, remaining columns = Sensor1, Sensor2, ...
|
||
"""
|
||
|
||
def __init__(self, parent: Any = None) -> None:
|
||
super().__init__(parent)
|
||
self._data: list[list[str]] = [] # 2D array of temperature strings
|
||
self._col_count: int = 0 # Number of sensor columns (excludes row index)
|
||
|
||
def reset(self) -> None:
|
||
"""Clear all data."""
|
||
self.beginResetModel()
|
||
self._data = []
|
||
self._col_count = 0
|
||
self.endResetModel()
|
||
|
||
def load_data(self, data: list[list[str]], col_count: int) -> None:
|
||
"""Load parsed temperature data into the model.
|
||
|
||
Args:
|
||
data: 2D list of temperature strings (e.g. [["25.30", "24.80", ...], ...]).
|
||
col_count: Number of sensor columns (may differ from data[0] length).
|
||
"""
|
||
self.beginResetModel()
|
||
self._data = data
|
||
self._col_count = col_count
|
||
self.endResetModel()
|
||
log.info("Loaded %d rows × %d cols into model", len(data), col_count)
|
||
|
||
# ---- QAbstractTableModel interface ----
|
||
|
||
def rowCount(self, parent: Any = None) -> int:
|
||
return len(self._data)
|
||
|
||
def columnCount(self, parent: Any = None) -> int:
|
||
# Column 0 = row index, columns 1..N = sensor values
|
||
return self._col_count + 1
|
||
|
||
def data(self, index: Any, role: int = ...) -> Any:
|
||
if not index.isValid():
|
||
return None
|
||
|
||
row = index.row()
|
||
col = index.column()
|
||
|
||
if role == Qt.ItemDataRole.DisplayRole:
|
||
if col == 0:
|
||
return str(row + 1) # 1-based row index
|
||
sensor_col = col - 1
|
||
if row < len(self._data) and sensor_col < len(self._data[row]):
|
||
return self._data[row][sensor_col]
|
||
return "0"
|
||
|
||
return None
|
||
|
||
def headerData(
|
||
self, section: int, orientation: int, role: int = ...
|
||
) -> Any:
|
||
if role != Qt.ItemDataRole.DisplayRole:
|
||
return None
|
||
if orientation == Qt.Orientation.Horizontal:
|
||
if section == 0:
|
||
return "Row"
|
||
return f"Sensor{section}"
|
||
return str(section + 1)
|