Add SettingsTab, StatusTab, DataTab and wire up DeviceController
- 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
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
"""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)
|
||||
Reference in New Issue
Block a user