From 7d9d928bb151417c52e53d3811a2118a96bd847f Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Mon, 25 May 2026 23:55:00 +0200 Subject: [PATCH] Move time window to per-plot spinbox in control bar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the single global toolbar spinbox with one QSpinBox per plot, placed between the '+' button and the trace chips. Each plot has an independent 1–24 h window; values are persisted in plot_settings.json under 'time_windows'. Co-Authored-By: Claude Sonnet 4.6 --- gui_client.py | 58 +++++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/gui_client.py b/gui_client.py index a01afe4..709d06a 100644 --- a/gui_client.py +++ b/gui_client.py @@ -349,25 +349,10 @@ class PlotTab(QWidget): main_layout.setContentsMargins(4, 4, 4, 4) main_layout.setSpacing(4) - # ── toolbar ─────────────────────────────────────────────────────────── - tb = QWidget() - tb.setMaximumHeight(32) - tb_row = QHBoxLayout(tb) - tb_row.setContentsMargins(0, 0, 0, 0) - tb_row.setSpacing(6) - tb_row.addWidget(QLabel("Time window:")) - self._tw_spin = QSpinBox() - self._tw_spin.setRange(1, 24) - self._tw_spin.setSuffix(" h") - self._tw_spin.setFixedWidth(72) - self._tw_spin.valueChanged.connect(self._on_time_window_changed) - tb_row.addWidget(self._tw_spin) - tb_row.addStretch() - main_layout.addWidget(tb) - # ── data ────────────────────────────────────────────────────────────── - self._traces: list[list[str]] = [[] for _ in range(self.NUM_PLOTS)] - self._saved_traces: list[list[str]] = self._load_settings() + self._tw_spins: list[QSpinBox] = [] + self._traces: list[list[str]] = [[] for _ in range(self.NUM_PLOTS)] + self._saved_traces, _saved_tw = self._load_settings() self._series: dict[str, deque] = {} self._units: dict[str, str] = {} @@ -411,7 +396,16 @@ class PlotTab(QWidget): add_btn.clicked.connect(lambda checked, idx=i: self._add_trace(idx)) ctrl_row.addWidget(add_btn) - ctrl_row.addSpacing(8) + tw_spin = QSpinBox() + tw_spin.setRange(1, 24) + tw_spin.setSuffix(" h") + tw_spin.setFixedWidth(60) + tw_spin.setValue(_saved_tw[i]) + tw_spin.valueChanged.connect(lambda _, idx=i: self._on_time_window_changed(idx)) + self._tw_spins.append(tw_spin) + ctrl_row.addWidget(tw_spin) + + ctrl_row.addSpacing(4) chip_bar = QHBoxLayout() chip_bar.setSpacing(4) chip_bar.setContentsMargins(0, 0, 0, 0) @@ -558,37 +552,37 @@ class PlotTab(QWidget): try: _SETTINGS_PATH.parent.mkdir(parents=True, exist_ok=True) _SETTINGS_PATH.write_text(json.dumps({ - "traces": [list(t) for t in self._traces], - "time_window": self._tw_spin.value(), + "traces": [list(t) for t in self._traces], + "time_windows": [sp.value() for sp in self._tw_spins], }, indent=2)) except OSError: pass - def _load_settings(self) -> list[list[str]]: + def _load_settings(self) -> tuple[list[list[str]], list[int]]: try: data = json.loads(_SETTINGS_PATH.read_text()) saved = data.get("traces", []) while len(saved) < self.NUM_PLOTS: saved.append([]) - tw = int(data.get("time_window", 1)) - self._tw_spin.blockSignals(True) - self._tw_spin.setValue(max(1, min(24, tw))) - self._tw_spin.blockSignals(False) - return [list(t) for t in saved[: self.NUM_PLOTS]] - except (OSError, json.JSONDecodeError, KeyError, AttributeError): - return [[] for _ in range(self.NUM_PLOTS)] + tws = data.get("time_windows", []) + while len(tws) < self.NUM_PLOTS: + tws.append(1) + tws = [max(1, min(24, int(v))) for v in tws[: self.NUM_PLOTS]] + return [list(t) for t in saved[: self.NUM_PLOTS]], tws + except (OSError, json.JSONDecodeError, KeyError): + return [[] for _ in range(self.NUM_PLOTS)], [1] * self.NUM_PLOTS # ── drawing ─────────────────────────────────────────────────────────────── - def _on_time_window_changed(self): + def _on_time_window_changed(self, plot_idx: int): self._save_settings() self._redraw() def _redraw(self): - now = time.time() - cutoff = now - self._tw_spin.value() * 3600 + now = time.time() for i, pw in enumerate(self._plot_widgets): + cutoff = now - self._tw_spins[i].value() * 3600 pi = pw.getPlotItem() pi.clear() pi.addItem(self._vlines[i], ignoreBounds=True)