#!/usr/bin/env python3 # -*- coding: UTF-8 -*- # # generated by wxGlade 1.0.2 on Sun Jun 20 19:31:43 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 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): # begin wxGlade: MyFrame.__init__ self.model = Model() kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) self.SetSize((500, 400)) self.SetTitle("frame") self.panel_1 = wx.Panel(self, wx.ID_ANY) grid_sizer_1 = wx.GridBagSizer(0, 0) self.b_start = wx.Button(self.panel_1, wx.ID_ANY, "Start") grid_sizer_1.Add(self.b_start, (0, 0), (1, 1), 0, 0) self.b_stop = wx.Button(self.panel_1, wx.ID_ANY, "Stop") grid_sizer_1.Add(self.b_stop, (0, 1), (1, 1), 0, 0) self.b_clear = wx.Button(self.panel_1, wx.ID_ANY, "Clear") grid_sizer_1.Add(self.b_clear, (0, 2), (1, 1), 0, 0) self.b_save = wx.Button(self.panel_1, wx.ID_ANY, "Save") grid_sizer_1.Add(self.b_save, (0, 3), (1, 1), 0, 0) self.b_run = wx.Button(self.panel_1, wx.ID_ANY, "Run") grid_sizer_1.Add(self.b_run, (0, 4), (1, 1), 0, 0) self.plot = PlotPanel(self.panel_1, self.model) self.plot.SetMinSize((300, 300)) grid_sizer_1.Add(self.plot, (1, 0), (1, 3), wx.EXPAND, 0) label_1 = wx.StaticText(self.panel_1, wx.ID_ANY, "Test") grid_sizer_1.Add(label_1, (2, 0), (1, 3), 0, 0) self.panel_1.SetSizer(grid_sizer_1) self.timer = wx.Timer(self, wx.ID_ANY) self.Layout() 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 # end wxGlade def on_close_window(self, event): self.model.exit() print("Closing") wx.Exit() def update(self, event): self.plot.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 MeinErsterMessApp(wx.App): def __init__(self): super().__init__() self.frame = None def OnInit(self): self.frame = MyFrame(None, wx.ID_ANY, "") self.SetTopWindow(self.frame) self.frame.Show() return True # end of class MeinErsterMessApp if __name__ == "__main__": app = MeinErsterMessApp() app.MainLoop()