aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--picostream/main.py150
1 files changed, 90 insertions, 60 deletions
diff --git a/picostream/main.py b/picostream/main.py
index fc1b914..e7eb709 100644
--- a/picostream/main.py
+++ b/picostream/main.py
@@ -1,5 +1,3 @@
-
-
import os
import re
import sys
@@ -15,8 +13,10 @@ from PyQt5.QtWidgets import (
QDoubleSpinBox,
QFileDialog,
QFormLayout,
+ QGroupBox,
QHBoxLayout,
QLabel,
+ QLCDNumber,
QLineEdit,
QMainWindow,
QPushButton,
@@ -134,17 +134,33 @@ class PicoStreamMainWindow(QMainWindow):
)
form_layout.addRow(self.live_only_checkbox, self.max_buffer_input)
- # Plot settings
+ settings_layout.addLayout(form_layout)
+
+ # Start/Stop buttons
+ self.start_button = QPushButton("Start Acquisition")
+ self.stop_button = QPushButton("Stop Acquisition")
+ self.stop_button.setEnabled(False)
+
+ button_layout = QHBoxLayout()
+ button_layout.addWidget(self.start_button)
+ button_layout.addWidget(self.stop_button)
+ settings_layout.addLayout(button_layout)
+
+ # Plot settings group
+ plot_settings_group = QGroupBox("Plot Settings")
+ plot_settings_form = QFormLayout(plot_settings_group)
+
self.plot_window_input = QDoubleSpinBox()
self.plot_window_input.setRange(0.01, 10.0)
self.plot_window_input.setValue(0.5)
self.plot_window_input.setSingleStep(0.1)
self.plot_window_input.setDecimals(2)
self.plot_window_input.setSuffix(" s")
- form_layout.addRow("Plot Window:", self.plot_window_input)
+ plot_settings_form.addRow("Display Window:", self.plot_window_input)
self.y_axis_auto_checkbox = QCheckBox("Auto Y-axis")
self.y_axis_auto_checkbox.setChecked(True)
+ self.y_axis_auto_checkbox.setLayoutDirection(Qt.RightToLeft)
self.y_min_input = QDoubleSpinBox()
self.y_min_input.setRange(-100000, 100000)
self.y_min_input.setValue(-1000)
@@ -163,65 +179,59 @@ class PicoStreamMainWindow(QMainWindow):
lambda state: self.y_max_input.setEnabled(state == 0)
)
- form_layout.addRow(self.y_axis_auto_checkbox)
+ # plot_settings_form.addRow()
y_limits_layout = QHBoxLayout()
+ y_limits_layout.addWidget(self.y_axis_auto_checkbox)
y_limits_layout.addWidget(QLabel("Min:"))
y_limits_layout.addWidget(self.y_min_input)
y_limits_layout.addWidget(QLabel("Max:"))
y_limits_layout.addWidget(self.y_max_input)
- form_layout.addRow("Y-axis Limits:", y_limits_layout)
-
- settings_layout.addLayout(form_layout)
+ plot_settings_form.addRow(y_limits_layout)
- self.start_button = QPushButton("Start Acquisition")
- self.stop_button = QPushButton("Stop Acquisition")
- self.stop_button.setEnabled(False)
self.apply_plot_settings_button = QPushButton("Apply Plot Settings")
+ plot_settings_form.addRow(self.apply_plot_settings_button)
+
+ settings_layout.addWidget(plot_settings_group)
+
+ # Status display section using QGroupBox and QFormLayout
+ status_group = QGroupBox("Status")
+ status_form_layout = QFormLayout(status_group)
- settings_layout.addWidget(self.start_button)
- settings_layout.addWidget(self.stop_button)
- settings_layout.addWidget(self.apply_plot_settings_button)
-
- # Add status display section
- status_group = QWidget()
- status_group_layout = QVBoxLayout(status_group)
- status_title = QLabel("Status")
- status_title.setStyleSheet("font-weight: bold; font-size: 12px;")
- status_group_layout.addWidget(status_title)
-
- # Create status labels with initial values
- self.status_heartbeat = QLabel("UI: -")
- self.status_samples = QLabel("Samples: 0")
- self.status_rate = QLabel("Rate: -")
- self.status_latency = QLabel("Latency: -")
- self.status_errors = QLabel("Errors: 0")
- self.status_saturation = QLabel("Saturation: -")
- self.status_acquisition = QLabel("Waiting for file...")
-
- # Set monospace font for status
+ # Create status value labels with monospace font
font = QFont()
font.setFamily("Monospace")
font.setFixedPitch(True)
font.setPointSize(9)
- for label in [
- self.status_heartbeat,
- self.status_samples,
- self.status_rate,
- self.status_latency,
- self.status_errors,
- self.status_saturation,
- self.status_acquisition,
- ]:
- label.setFont(font)
- label.setWordWrap(True)
- status_group_layout.addWidget(self.status_heartbeat)
- status_group_layout.addWidget(self.status_errors)
- status_group_layout.addWidget(self.status_saturation)
- status_group_layout.addWidget(self.status_samples)
- status_group_layout.addWidget(self.status_latency)
- status_group_layout.addWidget(self.status_rate)
- status_group_layout.addWidget(self.status_acquisition)
+ self.status_heartbeat = QLabel("-")
+ self.status_heartbeat.setFont(font)
+ status_form_layout.addRow("UI:", self.status_heartbeat)
+
+ self.status_errors = self._create_status_label(font)
+ status_form_layout.addRow("Errors:", self.status_errors)
+
+ self.status_saturation = QLabel("-")
+ self.status_saturation.setFont(font)
+ status_form_layout.addRow("Saturation:", self.status_saturation)
+
+ self.status_samples = QLCDNumber()
+ self.status_samples.setDigitCount(10)
+ self.status_samples.setSegmentStyle(QLCDNumber.Flat)
+ self.status_samples.display("0")
+ status_form_layout.addRow("Samples:", self.status_samples)
+
+ self.status_latency = QLabel("-")
+ self.status_latency.setFont(font)
+ status_form_layout.addRow("Latency:", self.status_latency)
+
+ self.status_rate = QLabel("-")
+ self.status_rate.setFont(font)
+ status_form_layout.addRow("Rate:", self.status_rate)
+
+ self.status_acquisition = QLabel("Waiting for file...")
+ self.status_acquisition.setFont(font)
+ self.status_acquisition.setWordWrap(True)
+ status_form_layout.addRow("Acquisition:", self.status_acquisition)
settings_layout.addWidget(status_group)
settings_layout.addStretch()
@@ -247,6 +257,19 @@ class PicoStreamMainWindow(QMainWindow):
self.load_settings()
+ def _create_status_label(self, font: QFont) -> QLabel:
+ """Create a status label with error styling capability."""
+ label = QLabel("0")
+ label.setFont(font)
+ return label
+
+ def _set_status_error_style(self, label: QLabel, is_error: bool) -> None:
+ """Apply error styling (red background) to a status label."""
+ if is_error:
+ label.setStyleSheet("background-color: #ffcccc; padding: 2px;")
+ else:
+ label.setStyleSheet("")
+
def select_output_file(self) -> None:
"""Open a dialog to select the output HDF5 file."""
file_name, _ = QFileDialog.getSaveFileName(
@@ -361,17 +384,10 @@ class PicoStreamMainWindow(QMainWindow):
def sync_status_from_plotter(self) -> None:
"""Sync status from the plotter to the main window status labels."""
try:
- # Check if plotter exists and has been initialized
+ # Check if plotter exists and has been initialised
if not hasattr(self, 'plotter') or not self.plotter:
return
- # Check if plotter has the required attributes
- required_labels = [
- 'heartbeat_label', 'samples_label', 'rate_label',
- 'plotter_latency_label', 'error_label',
- 'saturation_label', 'acq_status_label'
- ]
-
# Helper function to safely strip HTML tags
def strip_html(text: str) -> str:
if not text:
@@ -389,10 +405,24 @@ class PicoStreamMainWindow(QMainWindow):
# Update all status labels
self.status_heartbeat.setText(safe_get_text('heartbeat_label'))
- self.status_samples.setText(safe_get_text('samples_label'))
+
+ # Update samples with QLCDNumber
+ samples_text = safe_get_text('samples_label')
+ try:
+ samples_int = int(samples_text)
+ self.status_samples.display(samples_int)
+ except (ValueError, TypeError):
+ self.status_samples.display(0)
+
self.status_rate.setText(safe_get_text('rate_label'))
self.status_latency.setText(safe_get_text('plotter_latency_label'))
- self.status_errors.setText(safe_get_text('error_label'))
+
+ # Update errors with colour coding
+ errors_text = safe_get_text('error_label')
+ self.status_errors.setText(errors_text)
+ has_errors = errors_text != "0" and errors_text != "-"
+ self._set_status_error_style(self.status_errors, has_errors)
+
self.status_saturation.setText(safe_get_text('saturation_label'))
self.status_acquisition.setText(safe_get_text('acq_status_label'))