fix: The QML cross-component id resolution for root.waferDetected was failing

silently. Exposing a proper waferDetected property on the Python
DeviceController ensures reliable gating, and resetting it on refresh
blocks the actions until the next successful detection.
This commit is contained in:
jack
2026-07-09 13:07:31 -07:00
parent 7b20ffa376
commit 4ee139ad8f
3 changed files with 19 additions and 4 deletions
@@ -44,7 +44,7 @@ ColumnLayout {
label: "READ MEMORY" label: "READ MEMORY"
iconSource: "../icons/read.svg" iconSource: "../icons/read.svg"
Layout.fillWidth: true Layout.fillWidth: true
enabled: root.waferDetected enabled: deviceController.waferDetected && !deviceController.operationInProgress
onClicked: deviceController.readMemoryAsync() onClicked: deviceController.readMemoryAsync()
} }
@@ -53,7 +53,7 @@ ColumnLayout {
iconSource: "../icons/erase.svg" iconSource: "../icons/erase.svg"
Layout.fillWidth: true Layout.fillWidth: true
destructive: true destructive: true
enabled: root.waferDetected enabled: deviceController.waferDetected && !deviceController.operationInProgress
onClicked: deviceController.eraseMemory( onClicked: deviceController.eraseMemory(
deviceController.selectedPort) deviceController.selectedPort)
} }
@@ -87,6 +87,7 @@ ColumnLayout {
label: "REFRESH SESSION" label: "REFRESH SESSION"
iconSource: "../icons/refresh.svg" iconSource: "../icons/refresh.svg"
Layout.fillWidth: true Layout.fillWidth: true
enabled: !deviceController.operationInProgress
onClicked: deviceController.clearSession() onClicked: deviceController.clearSession()
} }
@@ -38,6 +38,7 @@ class DeviceController(QObject):
portsUpdated = Signal(list) portsUpdated = Signal(list)
connectionStatusChanged = Signal() connectionStatusChanged = Signal()
operationInProgressChanged = Signal() operationInProgressChanged = Signal()
waferDetectedChanged = Signal()
selectedPortChanged = Signal() selectedPortChanged = Signal()
detectResult = Signal(object) # WaferInfo dict or None detectResult = Signal(object) # WaferInfo dict or None
readResult = Signal(dict) # {"success": bool, "bytes": int} or {"error": str} readResult = Signal(dict) # {"success": bool, "bytes": int} or {"error": str}
@@ -77,6 +78,7 @@ class DeviceController(QObject):
# → denied = safe default. Called by P2.1. # → denied = safe default. Called by P2.1.
# See docs/pending/license-gating-plan.md §1.2. # See docs/pending/license-gating-plan.md §1.2.
self._last_wafer_info: dict[str, Any] = {} self._last_wafer_info: dict[str, Any] = {}
self._wafer_detected: bool = False
self._last_csv_path: str = "" self._last_csv_path: str = ""
self._selected_port: str = "" self._selected_port: str = ""
self._data_row_count: int = 0 self._data_row_count: int = 0
@@ -212,6 +214,17 @@ class DeviceController(QObject):
info.get("cycleCount", 0), info.get("cycleCount", 0),
] ]
@Property(bool, notify=waferDetectedChanged)
def waferDetected(self) -> bool:
"""Whether a wafer is currently detected and ready for read/erase."""
return self._wafer_detected
def _set_wafer_detected(self, detected: bool) -> None:
if self._wafer_detected != detected:
self._wafer_detected = detected
self.waferDetectedChanged.emit()
@Property(object, notify=detectResult) @Property(object, notify=detectResult)
def dataModel(self) -> TemperatureTableModel: def dataModel(self) -> TemperatureTableModel:
"""QAbstractTableModel for the parsed temperature data table.""" """QAbstractTableModel for the parsed temperature data table."""
@@ -276,6 +289,7 @@ class DeviceController(QObject):
self._set_connection_status("Disconnected") self._set_connection_status("Disconnected")
self._selected_port = "" self._selected_port = ""
self._last_wafer_info = {} self._last_wafer_info = {}
self._set_wafer_detected(False)
self._data_row_count = 0 self._data_row_count = 0
self._data_col_count = 0 self._data_col_count = 0
self._raw_bytes = None self._raw_bytes = None
@@ -366,6 +380,7 @@ class DeviceController(QObject):
wafer_dict = self._wafer_info_to_dict(info) wafer_dict = self._wafer_info_to_dict(info)
self._selected_port = port or "" self._selected_port = port or ""
self._last_wafer_info = wafer_dict self._last_wafer_info = wafer_dict
self._set_wafer_detected(True)
self._set_connection_status("Connected") self._set_connection_status("Connected")
self.detectResult.emit(wafer_dict) self.detectResult.emit(wafer_dict)
self.selectedPortChanged.emit() self.selectedPortChanged.emit()
@@ -375,6 +390,7 @@ class DeviceController(QObject):
self._set_connection_status("Disconnected") self._set_connection_status("Disconnected")
self._append_log("No wafer detected on any port") self._append_log("No wafer detected on any port")
self._last_wafer_info = {} self._last_wafer_info = {}
self._set_wafer_detected(False)
self.detectResult.emit(None) self.detectResult.emit(None)
self.selectedPortChanged.emit() self.selectedPortChanged.emit()
finally: finally:
-2
View File
@@ -1,2 +0,0 @@
{
"_mock_return_value":