Add plot update
This commit is contained in:
parent
8d6ae914db
commit
96c1231ed0
@ -1,5 +1,5 @@
|
|||||||
''' app/ui/main_window.py '''
|
''' app/ui/main_window.py '''
|
||||||
from PyQt6.QtCore import Qt
|
from PyQt6.QtCore import Qt, QTimer
|
||||||
from PyQt6.QtWidgets import QMainWindow, QWidget, QHBoxLayout, QTextEdit, QLabel, QDialog
|
from PyQt6.QtWidgets import QMainWindow, QWidget, QHBoxLayout, QTextEdit, QLabel, QDialog
|
||||||
from PyQt6.QtGui import QIcon
|
from PyQt6.QtGui import QIcon
|
||||||
from .widgets.menubar import MenuBar
|
from .widgets.menubar import MenuBar
|
||||||
@ -22,6 +22,7 @@ from cpdctrl.utility.data import DataCollector
|
|||||||
from cpdctrl.measurement import measure
|
from cpdctrl.measurement import measure
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MainWindow(QMainWindow):
|
class MainWindow(QMainWindow):
|
||||||
"""
|
"""
|
||||||
MainWindow
|
MainWindow
|
||||||
@ -60,7 +61,8 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
init_elements = [("name1", "val1"), ("name2", "val2")]
|
init_elements = [("name1", "val1"), ("name2", "val2")]
|
||||||
layout.addWidget(MetadataInput(init_elements))
|
layout.addWidget(MetadataInput(init_elements))
|
||||||
layout.addWidget(Plot())
|
self.plot_widget = Plot()
|
||||||
|
layout.addWidget(self.plot_widget)
|
||||||
|
|
||||||
self.verbose = True
|
self.verbose = True
|
||||||
|
|
||||||
@ -70,6 +72,13 @@ class MainWindow(QMainWindow):
|
|||||||
self.vmdev_autoconnect()
|
self.vmdev_autoconnect()
|
||||||
self.leddev_autoconnect()
|
self.leddev_autoconnect()
|
||||||
|
|
||||||
|
# Measurement
|
||||||
|
self.measurement_timer = None
|
||||||
|
self.led_script = None
|
||||||
|
self.data_collector = None
|
||||||
|
self.data_queue = None
|
||||||
|
self.proc_measure = None
|
||||||
|
|
||||||
def create_toolbars(self) -> None:
|
def create_toolbars(self) -> None:
|
||||||
"""
|
"""
|
||||||
Creates and adds the top and right toolbars to the main window.
|
Creates and adds the top and right toolbars to the main window.
|
||||||
@ -81,6 +90,7 @@ class MainWindow(QMainWindow):
|
|||||||
# Top Toolbar Buttons
|
# Top Toolbar Buttons
|
||||||
self.topbar.add_button("Devices", QIcon.fromTheme(QIcon.ThemeIcon.Printer), self.vmdev_connect_from_dialog)
|
self.topbar.add_button("Devices", QIcon.fromTheme(QIcon.ThemeIcon.Printer), self.vmdev_connect_from_dialog)
|
||||||
self.topbar.add_button("Start", QIcon.fromTheme(QIcon.ThemeIcon.MediaPlaybackStart), self.measure_start)
|
self.topbar.add_button("Start", QIcon.fromTheme(QIcon.ThemeIcon.MediaPlaybackStart), self.measure_start)
|
||||||
|
self.topbar.add_button("Stop", QIcon.fromTheme(QIcon.ThemeIcon.MediaPlaybackStop), self.measure_stop)
|
||||||
self.topbar.add_button("Save", "resources/assets/icons/windows/shell32-259.ico", self.save_file)
|
self.topbar.add_button("Save", "resources/assets/icons/windows/shell32-259.ico", self.save_file)
|
||||||
self.topbar.add_separator()
|
self.topbar.add_separator()
|
||||||
self.topbar.add_button("Exit", "resources/assets/icons/windows/shell32-220.ico", self.exit_app)
|
self.topbar.add_button("Exit", "resources/assets/icons/windows/shell32-220.ico", self.exit_app)
|
||||||
@ -179,46 +189,58 @@ class MainWindow(QMainWindow):
|
|||||||
if self.verbose:
|
if self.verbose:
|
||||||
print(f"Starting measurement with:\n\tinterval = {interval}\n\tflush_after = {flush_after}\n\tuse_buffer = {use_buffer}\n\tmax_measurements = {max_measurements}\n\tstop_on_script_end = {stop_on_script_end}")
|
print(f"Starting measurement with:\n\tinterval = {interval}\n\tflush_after = {flush_after}\n\tuse_buffer = {use_buffer}\n\tmax_measurements = {max_measurements}\n\tstop_on_script_end = {stop_on_script_end}")
|
||||||
|
|
||||||
led_script = LedScript(script=script, auto_update=True, verbose=True)
|
self.led_script = LedScript(script=script, auto_update=True, verbose=True)
|
||||||
data_collector = DataCollector(metadata=metadata, data_path=AppConfig.MAIN_CFG.get("datadir"), data_name=measurement_name)
|
self.data_collector = DataCollector(metadata=metadata, data_path=AppConfig.MAIN_CFG.get("datadir"), data_name=measurement_name)
|
||||||
# data_collector.clear()
|
# data_collector.clear()
|
||||||
data_queue = mp.Queue()
|
self.data_queue = mp.Queue()
|
||||||
command_queue = mp.Queue()
|
self.command_queue = mp.Queue()
|
||||||
# Argument order must match the definition
|
# Argument order must match the definition
|
||||||
|
self.proc_measure = mt.Thread(target=measure, args=(
|
||||||
proc_measure = mt.Thread(target=measure, args=(
|
|
||||||
self.vmdev,
|
self.vmdev,
|
||||||
self.leddev,
|
self.leddev,
|
||||||
led_script,
|
self.led_script,
|
||||||
data_collector,
|
self.data_collector,
|
||||||
interval,
|
interval,
|
||||||
flush_after,
|
flush_after,
|
||||||
use_buffer,
|
use_buffer,
|
||||||
max_measurements,
|
max_measurements,
|
||||||
stop_on_script_end,
|
stop_on_script_end,
|
||||||
self.verbose, # verbose
|
self.verbose, # verbose
|
||||||
command_queue,
|
self.command_queue,
|
||||||
data_queue
|
self.data_queue
|
||||||
))
|
))
|
||||||
proc_measure.start()
|
self.proc_measure.start()
|
||||||
try:
|
self.measurement_timer = QTimer(self)
|
||||||
while proc_measure.is_alive():
|
self.measurement_timer.timeout.connect(self.measure_update)
|
||||||
while not data_queue.empty():
|
self.measurement_timer.start(300) # TODO: set interval
|
||||||
# print(data_queue.qsize(), "\n\n")
|
|
||||||
current_data = data_queue.get(block=False)
|
|
||||||
i, tval, vval, led_val = current_data
|
|
||||||
print(f"Data {i:03}: {tval}s, {vval}V, {led_val}%")
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
def measure_stop(self):
|
||||||
pass
|
if not self.measurement_is_running():
|
||||||
command_queue.put("stop")
|
raise RuntimeError("measure_stop: Measurement is not running")
|
||||||
proc_measure.join()
|
self.command_queue.put("stop")
|
||||||
|
self.measurement_timer.stop()
|
||||||
|
self.proc_measure.join()
|
||||||
print("Measurement stopped" + " " * 50)
|
print("Measurement stopped" + " " * 50)
|
||||||
led_script.stop_updating() # stop watching for file updates (if enabled)
|
self.led_script.stop_updating() # stop watching for file updates (if enabled)
|
||||||
data_collector.save_csv(verbose=True)
|
self.data_collector.save_csv(verbose=True)
|
||||||
data, metadata = data_collector.get_data()
|
data, metadata = self.data_collector.get_data()
|
||||||
|
self.proc_measure = None
|
||||||
|
self.led_script = None
|
||||||
|
|
||||||
|
|
||||||
|
def measure_update(self):
|
||||||
|
if self.proc_measure.is_alive():
|
||||||
|
while not self.data_queue.empty():
|
||||||
|
# print(data_queue.qsize(), "\n\n")
|
||||||
|
current_data = self.data_queue.get(block=False)
|
||||||
|
i, tval, vval, led_val = current_data
|
||||||
|
print(f"Data {i:03}: {tval}s, {vval}V, {led_val}%")
|
||||||
|
# update the plot
|
||||||
|
self.plot_widget.update(tval, vval, led_val)
|
||||||
|
|
||||||
|
def measurement_is_running(self):
|
||||||
|
return self.proc_measure is not None
|
||||||
|
|
||||||
def create_edit(self) -> QTextEdit:
|
def create_edit(self) -> QTextEdit:
|
||||||
"""
|
"""
|
||||||
Creates and adds the QTextEdit widget to the main window.
|
Creates and adds the QTextEdit widget to the main window.
|
||||||
|
@ -2,6 +2,9 @@ import pyqtgraph as pg
|
|||||||
from PyQt6.QtWidgets import QWidget
|
from PyQt6.QtWidgets import QWidget
|
||||||
|
|
||||||
class Plot(pg.PlotWidget):
|
class Plot(pg.PlotWidget):
|
||||||
|
"""
|
||||||
|
pyqtgraph plot widget for showing voltage and LED vs time
|
||||||
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.setBackground("w")
|
self.setBackground("w")
|
||||||
@ -9,11 +12,29 @@ class Plot(pg.PlotWidget):
|
|||||||
self.setLabel("bottom", "time [s]")
|
self.setLabel("bottom", "time [s]")
|
||||||
self.setLabel("left", "Voltage [V]")
|
self.setLabel("left", "Voltage [V]")
|
||||||
self.setLabel("right", "LED [%]")
|
self.setLabel("right", "LED [%]")
|
||||||
|
self.getAxis("right").setRange(0, 110) # Adding some margin
|
||||||
self.showGrid(x=True, y=True)
|
self.showGrid(x=True, y=True)
|
||||||
self.time = list(range(10))
|
self.time = []
|
||||||
self.voltage = list(range(10))
|
self.voltage = []
|
||||||
self.led = list(range(-10))
|
self.led = []
|
||||||
self.line = self.plot(
|
|
||||||
|
self.vline = self.plot(
|
||||||
self.time,
|
self.time,
|
||||||
self.voltage
|
self.voltage,
|
||||||
|
pen=pg.mkPen("b", width=2),
|
||||||
|
symbol="o",
|
||||||
|
symbolSize=5,
|
||||||
|
symbolBrush="b",
|
||||||
)
|
)
|
||||||
|
self.lline = self.plot(
|
||||||
|
self.time,
|
||||||
|
self.led,
|
||||||
|
pen=pg.mkPen("r", width=2)
|
||||||
|
)
|
||||||
|
|
||||||
|
def update(self, time, voltage, led):
|
||||||
|
self.time.append(time)
|
||||||
|
self.voltage.append(voltage)
|
||||||
|
self.led.append(led)
|
||||||
|
self.vline.setData(self.time, self.voltage)
|
||||||
|
self.lline.setData(self.time, self.led)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user