OlliTut/GUI/main_view.py

242 lines
8.1 KiB
Python

#!/usr/bin/env python3
import importlib.machinery
import logging
from threading import Thread
import wx
from CoreLibrary.Param_Model import Param_Model
from plotView import PlotPanel
LOGGER = logging.getLogger("my_logger")
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "MESS MICH")
self.configure_window()
self.green = wx.Bitmap("./GUI/img/green.bmp")
self.red = wx.Bitmap("./GUI/img/red.bmp")
self.model, self.pd = self.init_api()
# MENU BAR
self.menu_bar()
# self.status_bar()
# self.tool_bar()
self.panel = wx.Panel(self, wx.ID_ANY)
grid_sizer_main = wx.GridBagSizer(0, 0)
self.status = self.status_init(grid_sizer_main)
self.tabs = self.plot_init(grid_sizer_main)
grid_group = wx.GridBagSizer(10, 0)
grid_sizer_main.Add(grid_group, (0, 2), (2, 1), wx.EXPAND, 0)
self.b_run, self.b_start, self.b_stop = self.init_measurement_buttons(grid_group)
self.plot_buttons(grid_sizer_main)
self.panel.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_TIMER, self.update, self.timer)
self.timer.Start(100, False)
self.runner_thread = None
def configure_window(self):
self.SetSize((1920, 1080))
self.SetTitle("My Fancy Measurements :D")
def init_api(self):
model = Param_Model()
pd = model.get_plot_data()
return model, pd
def 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)
frame_menubar.Append(tmp_menu, "File")
self.SetMenuBar(frame_menubar)
def status_bar(self):
frame_statusbar = self.CreateStatusBar(1)
frame_statusbar.SetStatusWidths([-1])
# statusbar fields
frame_statusbar_fields = ["frame_statusbar"]
for count, field in enumerate(frame_statusbar_fields):
frame_statusbar.SetStatusText(field, count)
def tool_bar(self):
frame_toolbar = wx.ToolBar(self, -1)
self.SetToolBar(frame_toolbar)
frame_toolbar.Realize()
def status_init(self, grid_sizer_main):
sizer_status = wx.GridBagSizer(vgap=5, hgap=5)
grid_sizer_main.Add(sizer_status, (0, 0), (2, 1), wx.EXPAND, 0)
# STATUS
data = {"over1": False, "over2": True, "motor": 123}
status_dict = {}
for row, (key, val) in enumerate(data.items()):
label = wx.StaticText(self.panel, wx.ID_ANY, key)
sizer_status.Add(label, (row, 0))
if isinstance(val, bool):
if val:
icon = wx.StaticBitmap(self.panel, bitmap=self.green)
status_dict[key] = icon
sizer_status.Add(icon, (row, 1))
else:
icon = wx.StaticBitmap(self.panel, bitmap=self.red)
status_dict[key] = icon
sizer_status.Add(icon, (row, 1))
else:
label = wx.StaticText(self.panel, wx.ID_ANY, str(val))
status_dict[key] = label
sizer_status.Add(label, (row, 1))
return status_dict
def plot_init(self, grid_sizer_main):
tabs = wx.Notebook(self.panel, wx.ID_ANY)
grid_sizer_main.Add(tabs, (0, 1), (1, 1), wx.EXPAND, 0)
plot = lambda ax, dat: ax.plot(dat["time"], dat["mess1"])
update = lambda im, dat: im.set_data(dat["time"], dat["mess1"])
plot_1 = PlotPanel(tabs, self.pd, plot, update)
tabs.AddPage(plot_1, "Temp")
plot = lambda ax, dat: ax.plot(dat["mess1"], dat["mess1"])
update = lambda im, dat: im.set_data(dat["mess1"], dat["mess1"])
plot_2 = PlotPanel(tabs, self.pd, plot, update)
tabs.AddPage(plot_2, "Multi")
return tabs
def init_measurement_buttons(self, grid_upper):
grid_sizer_measurement = wx.GridBagSizer(0, 0)
grid_upper.Add(grid_sizer_measurement, (0, 0), (1, 1), wx.EXPAND, 0)
b_start = wx.Button(self.panel, wx.ID_ANY, "Start")
grid_sizer_measurement.Add(b_start, (0, 0), (1, 1), 0, 0)
b_stop = wx.Button(self.panel, wx.ID_ANY, "Stop")
grid_sizer_measurement.Add(b_stop, (1, 0), (1, 1), 0, 0)
b_run = wx.Button(self.panel, wx.ID_ANY, "Run")
grid_sizer_measurement.Add(b_run, (2, 0), (1, 1), 0, 0)
self.Bind(wx.EVT_BUTTON, self.on_b_start, b_start)
self.Bind(wx.EVT_BUTTON, self.on_b_stop, b_stop)
self.Bind(wx.EVT_BUTTON, self.on_b_run, b_run)
return b_run, b_start, b_stop
def plot_buttons(self, grid_sizer_main):
grid_sizer_ctrl_plot = wx.GridBagSizer(0, 0)
grid_sizer_main.Add(grid_sizer_ctrl_plot, (1, 1), (1, 1), wx.EXPAND, 0)
b_clear = wx.Button(self.panel, wx.ID_ANY, "Clear")
grid_sizer_ctrl_plot.Add(b_clear, (0, 0), (1, 1), 0, 0)
b_save = wx.Button(self.panel, wx.ID_ANY, "Save")
grid_sizer_ctrl_plot.Add(b_save, (0, 1), (1, 1), 0, 0)
self.Bind(wx.EVT_BUTTON, self.on_b_clear, b_clear)
self.Bind(wx.EVT_BUTTON, self.on_b_save, b_save)
def on_close_window(self, _):
self.model.exit()
LOGGER.info("Closing")
wx.Exit()
def update(self, _):
# Repaint gui
self.tabs.Refresh()
self.model.refresh()
# Unlock if script is finished
if self.runner_thread is not None:
if not self.runner_thread.is_alive():
self.unlock()
self.runner_thread = None
# update Stuff
data = {"over1": True, "over2": True, "motor": 12}
for key, val in data.items():
if type(val) is bool:
if val:
self.status[key].SetBitmap(self.green)
else:
self.status[key].SetBitmap(self.red)
else:
self.status[key].SetLabel(str(val))
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.<event_handler>
LOGGER.info("Event handler 'on_b_start'")
self.model.start_measuring()
event.Skip()
def on_b_save(self, event): # wxGlade: MyFrame.<event_handler>
LOGGER.info("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.<event_handler>
LOGGER.info("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.<event_handler>
self.model.stop_measuring()
LOGGER.info("Event handler 'on_b_stop'")
event.Skip()
def on_b_clear(self, event): # wxGlade: MyFrame.<event_handler>
self.model.clear()
LOGGER.info("Event handler 'on_b_clear'")
event.Skip()
# end of class MyFrame