fix: energy spin movestate colors never rendered

The movestate property sat on the spinbox's inner QLineEdit, which both
themes deliberately paint transparent (QAbstractSpinBox QLineEdit rule)
- the state machine worked but no color ever showed, and the tests only
asserted the property, not the paint. The property now lives on the
spinbox itself with QAbstractSpinBox[movestate=...] added to both
themes' rules, verified by a pixel-sampling regression test that grabs
the rendered widget through the real stylesheet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-24 13:40:03 +02:00
committed by duan_j
co-authored by Claude Fable 5
parent 1708a92459
commit 01731c5a0f
5 changed files with 60 additions and 16 deletions
+8 -5
View File
@@ -744,12 +744,15 @@ def _sunrise_stylesheet(overrides: dict[str, str] | None = None) -> str:
}
/* Motor batch-move states (before the invalid rules on purpose: equal
specificity, so out-of-range red must come last to win). */
QLineEdit[movestate="pending"] {
specificity, so out-of-range red must come last to win). Spinboxes
(Set Energy) carry the property on the box itself — their inner
QLineEdit is transparent by design (rule below), so it can't show
the state. */
QLineEdit[movestate="pending"], QAbstractSpinBox[movestate="pending"] {
background-color: $input_pending_bg;
}
QLineEdit[movestate="moving"] {
QLineEdit[movestate="moving"], QAbstractSpinBox[movestate="moving"] {
background-color: $input_moving_bg;
}
@@ -1429,11 +1432,11 @@ def _sunset_stylesheet() -> str:
background-color: $dark_disabled;
}
QLineEdit[movestate="pending"] {
QLineEdit[movestate="pending"], QAbstractSpinBox[movestate="pending"] {
background-color: $dark_input_pending_bg;
}
QLineEdit[movestate="moving"] {
QLineEdit[movestate="moving"], QAbstractSpinBox[movestate="moving"] {
background-color: $dark_input_moving_bg;
}
+8 -9
View File
@@ -26,10 +26,10 @@ class SpinMoveState(QObject):
"""MotorMoveGroup's state machine for a single QDoubleSpinBox whose apply
gate is a button (the Set Energy rows): neutral tracks the readback, a
user edit stages pending (orange) and enables the button, the click turns
moving (green), and arrival within tol returns to neutral. Colors ride the
same movestate QSS via the spinbox's internal QLineEdit, so no new
styling. The caller keeps its own clicked connection for the actual send;
this object only tracks state."""
moving (green), and arrival within tol returns to neutral. The movestate
property sits on the spinbox itself — its inner QLineEdit is transparent
by theme design, so coloring it shows nothing. The caller keeps its own
clicked connection for the actual send; this object only tracks state."""
def __init__(self, spin: QDoubleSpinBox, button: QPushButton, tol: float, parent=None):
super().__init__(parent)
@@ -76,11 +76,10 @@ class SpinMoveState(QObject):
self._syncing = False
def _set_state(self, state: str):
box = self._spin.lineEdit()
if box.property("movestate") != state:
box.setProperty("movestate", state)
box.style().unpolish(box)
box.style().polish(box)
if self._spin.property("movestate") != state:
self._spin.setProperty("movestate", state)
self._spin.style().unpolish(self._spin)
self._spin.style().polish(self._spin)
self._state = state
self._button.setEnabled(state == "pending")