diff --git a/model.py b/model.py index 0fe098d..1a15544 100644 --- a/model.py +++ b/model.py @@ -5,7 +5,7 @@ Data: - dict with sensor data (temp, pressure, current) - dict with drivers (magnetic field control) """ -from measurement import Measurement +from sensor import Measurement class Model: diff --git a/measurement.py b/sensor.py similarity index 100% rename from measurement.py rename to sensor.py diff --git a/view.py b/view.py new file mode 100644 index 0000000..520229f --- /dev/null +++ b/view.py @@ -0,0 +1,262 @@ +#!/usr/bin/env python3 +# -*- coding: UTF-8 -*- +# +# generated by wxGlade 1.0.2 on Sun Jul 4 21:23:20 2021 +# + +import importlib.machinery +from threading import Thread +import wx +from model import Model + +# begin wxGlade: dependencies +# end wxGlade + +# begin wxGlade: extracode +# end wxGlade +import matplotlib.cm as cm +import matplotlib.cbook as cbook +from matplotlib.backends.backend_wxagg import ( + FigureCanvasWxAgg as FigureCanvas, + NavigationToolbar2WxAgg as NavigationToolbar, +) +from matplotlib.figure import Figure +import numpy as np + +# begin wxGlade: dependencies +# end wxGlade + +# begin wxGlade: extracode +# end wxGlade +class PlotPanel(wx.Panel): + def __init__(self, parent, model): + super().__init__(parent, -1) + self.model = model + self.fig = Figure((3, 3), 75) + self.canvas = FigureCanvas(self, -1, self.fig) + self.toolbar = NavigationToolbar(self.canvas) # matplotlib toolbar + self.toolbar.Realize() + # Now put all into a sizer + sizer = wx.BoxSizer(wx.VERTICAL) + # This way of adding to sizer allows resizing + sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) + # Best to allow the toolbar to resize! + sizer.Add(self.toolbar, 0, wx.GROW) + self.SetSizer(sizer) + self.Fit() + self.Bind(wx.EVT_PAINT, self.on_paint, self) + self.ax = None + self.im = None + self.init_plot_data() + self.x = self.y = None + + def init_plot_data(self): + self.ax = self.fig.add_subplot() + self.x, self.y = self.model.sensors["temp"].get_data + (self.im,) = self.ax.plot(self.x, self.y, "-.") + self.toolbar.update() # Not sure why this is needed - ADS + + def get_toolbar(self): + # You will need to override GetToolBar if you are using an + # unmanaged toolbar in your frame + return self.toolbar + + def on_paint(self, event): + self.x, self.y = self.model.sensors["temp"].get_data + # print(self.x) + self.im.set_data(self.x, self.y) + self.ax.relim() + self.ax.autoscale_view() + self.canvas.draw() + event.Skip() + + +class MyFrame(wx.Frame): + def __init__(self, *args, **kwds): + + self.model = Model() + + # begin wxGlade: MyFrame.__init__ + kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE + wx.Frame.__init__(self, *args, **kwds) + self.SetSize((1920, 1080)) + self.SetTitle("My Fancy Measurements :D") + + # Menu Bar + self.frame_menubar = wx.MenuBar() + tmp_menu = wx.Menu() + item = tmp_menu.Append(wx.ID_ANY, "Quit", "") + self.Bind(wx.EVT_MENU, self.on_close_window, item) + self.frame_menubar.Append(tmp_menu, "File") + self.SetMenuBar(self.frame_menubar) + # Menu Bar end + + self.frame_statusbar = self.CreateStatusBar(1) + self.frame_statusbar.SetStatusWidths([-1]) + # statusbar fields + frame_statusbar_fields = ["frame_statusbar"] + for i in range(len(frame_statusbar_fields)): + self.frame_statusbar.SetStatusText(frame_statusbar_fields[i], i) + + # Tool Bar + self.frame_toolbar = wx.ToolBar(self, -1) + self.SetToolBar(self.frame_toolbar) + self.frame_toolbar.Realize() + # Tool Bar end + + self.panel_1 = wx.Panel(self, wx.ID_ANY) + + grid_sizer_main = wx.GridBagSizer(0, 0) + + sizer_status = wx.BoxSizer(wx.VERTICAL) + grid_sizer_main.Add(sizer_status, (0, 0), (2, 1), wx.EXPAND, 0) + + #TODO test + label_1 = wx.StaticText(self.panel_1, wx.ID_ANY, "Text1") + sizer_status.Add(label_1, 0, 0, 0) + label_2 = wx.StaticText(self.panel_1, wx.ID_ANY, u"Für") + sizer_status.Add(label_2, 0, 0, 0) + label_3 = wx.StaticText(self.panel_1, wx.ID_ANY, "Statis") + sizer_status.Add(label_3, 0, 0, 0) + + self.tabs = wx.Notebook(self.panel_1, wx.ID_ANY) + grid_sizer_main.Add(self.tabs, (0, 1), (1, 1), wx.EXPAND, 0) + + self.plot_1 = PlotPanel(self.tabs, self.model) + self.tabs.AddPage(self.plot_1, "x vs y") + + self.plot_2 = PlotPanel(self.tabs, self.model) + self.tabs.AddPage(self.plot_2, "x vs z") + + grid_sizer_3 = wx.GridBagSizer(10, 0) + grid_sizer_main.Add(grid_sizer_3, (0, 2), (2, 1), wx.EXPAND, 0) + + grid_sizer_measurement = wx.GridBagSizer(0, 0) + grid_sizer_3.Add(grid_sizer_measurement, (0, 0), (1, 1), wx.EXPAND, 0) + + self.b_start = wx.Button(self.panel_1, wx.ID_ANY, "Start") + grid_sizer_measurement.Add(self.b_start, (0, 0), (1, 1), 0, 0) + + self.b_stop = wx.Button(self.panel_1, wx.ID_ANY, "Stop") + grid_sizer_measurement.Add(self.b_stop, (1, 0), (1, 1), 0, 0) + + self.b_run = wx.Button(self.panel_1, wx.ID_ANY, "Run") + grid_sizer_measurement.Add(self.b_run, (2, 0), (1, 1), 0, 0) + + + grid_sizer_5 = wx.GridBagSizer(0, 0) + grid_sizer_3.Add(grid_sizer_5, (1, 0), (1, 1), wx.EXPAND, 0) + + self.button_7 = wx.Button(self.panel_1, wx.ID_ANY, "button_7") + grid_sizer_5.Add(self.button_7, (0, 0), (1, 1), 0, 0) + + self.button_8 = wx.Button(self.panel_1, wx.ID_ANY, "button_8") + grid_sizer_5.Add(self.button_8, (1, 0), (1, 1), 0, 0) + + self.button_9 = wx.Button(self.panel_1, wx.ID_ANY, "button_9") + grid_sizer_5.Add(self.button_9, (2, 0), (1, 1), 0, 0) + + grid_sizer_ctrl_plot = wx.GridBagSizer(0, 0) + grid_sizer_main.Add(grid_sizer_ctrl_plot, (1, 1), (1, 1), wx.EXPAND, 0) + + self.b_clear = wx.Button(self.panel_1, wx.ID_ANY, "Clear") + grid_sizer_ctrl_plot.Add(self.b_clear, (0, 0), (1, 1), 0, 0) + + self.b_save = wx.Button(self.panel_1, wx.ID_ANY, "Save") + grid_sizer_ctrl_plot.Add(self.b_save, (0, 1), (1, 1), 0, 0) + + self.panel_1.SetSizer(grid_sizer_main) + + self.Layout() + # end wxGlade + self.timer = wx.Timer(self, wx.ID_ANY) + self.Bind(wx.EVT_CLOSE, self.on_close_window) + self.Bind(wx.EVT_BUTTON, self.on_b_start, self.b_start) + self.Bind(wx.EVT_BUTTON, self.on_b_stop, self.b_stop) + self.Bind(wx.EVT_BUTTON, self.on_b_clear, self.b_clear) + self.Bind(wx.EVT_BUTTON, self.on_b_save, self.b_save) + self.Bind(wx.EVT_BUTTON, self.on_b_run, self.b_run) + self.Bind(wx.EVT_TIMER, self.update, self.timer) + self.timer.Start(100, False) + self.runner_thread = None + def on_close_window(self, event): + self.model.exit() + print("Closing") + wx.Exit() + + def update(self, event): + self.tabs.Refresh() + if self.runner_thread is not None: + if not self.runner_thread.is_alive(): + self.unlock() + self.runner_thread = None + + def lock(self): + self.b_run.Disable() + self.b_start.Disable() + + def unlock(self): + self.b_run.Enable() + self.b_start.Enable() + + def on_b_start(self, event): # wxGlade: MyFrame. + print("Event handler 'on_b_start'") + self.model.start_measuring() + event.Skip() + + def on_b_save(self, event): # wxGlade: MyFrame. + print("Event handler 'on_b_save'") + with wx.FileDialog( + self, + "Save csv file", + wildcard="CSV files (*.csv)|*.csv", + style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT, + ) as fileDialog: + + if fileDialog.ShowModal() == wx.ID_CANCEL: + return # the user changed their mind + + # save the current contents in the file + pathname = fileDialog.GetPath() + self.model.save_measuring(path=pathname) + event.Skip() + + def on_b_run(self, event): # wxGlade: MyFrame. + print("Event handler 'on_b_run'") + with wx.FileDialog(self, "Open PY file", wildcard="PY files (*.py)|*.py", + style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog: + + if fileDialog.ShowModal() == wx.ID_CANCEL: + return # the user changed their mind + + # Proceed loading the file chosen by the user + pathname = fileDialog.GetPath() + script = importlib.machinery.SourceFileLoader("ghf", pathname).load_module() + self.runner_thread = Thread(target=script.main, args=(self.model,)) + self.lock() + self.runner_thread.start() + event.Skip() + + def on_b_stop(self, event): # wxGlade: MyFrame. + self.model.stop_measuring() + print("Event handler 'on_b_stop'") + event.Skip() + + def on_b_clear(self, event): # wxGlade: MyFrame. + self.model.clear() + print("Event handler 'on_b_clear'") + event.Skip() +# end of class MyFrame + +class MyApp(wx.App): + def OnInit(self): + self.frame = MyFrame(None, wx.ID_ANY, "") + self.SetTopWindow(self.frame) + self.frame.Show() + return True + +# end of class MyApp + +if __name__ == "__main__": + app = MyApp(0) + app.MainLoop()