Big refactoring - it works now!

This commit is contained in:
Jacob Holder 2022-01-30 21:18:19 +01:00
parent 65ec111c8e
commit 90b0983160
Signed by: jacob
GPG Key ID: 2194FC747048A7FD
14 changed files with 406 additions and 307 deletions

View File

@ -8,7 +8,7 @@ from time import sleep
from Driver import Driver
from Sensor import Sensor
LOGGER = logging.getLogger()
LOGGER = logging.getLogger("my_logger")
class ExampleDriverWorker(Thread):
@ -60,11 +60,11 @@ class ExampleDriver(Driver, Sensor):
def start_measuring(self):
self.measureThread.produceData.set()
logging.info("I started meas")
LOGGER.info("I started meas")
def stop_measuring(self):
self.measureThread.produceData.clear()
logging.info("I stopped meas")
LOGGER.info("I stopped meas")
def exit(self):
self.stop_measuring()

View File

@ -5,7 +5,7 @@ from queue import Queue
from CoreLibrary.Driver import Driver
import logging
LOGGER = logging.getLogger()
LOGGER = logging.getLogger("my_logger")
class ExampleDriverWorker(Thread):

View File

@ -6,7 +6,7 @@ from random import random
from CoreLibrary.Sensor import Sensor
import logging
LOGGER = logging.getLogger()
LOGGER = logging.getLogger("my_logger")
class ExampleSensorWorker(Thread):
@ -44,11 +44,11 @@ class ExampleSensor(Sensor):
def start_measuring(self):
self.measureThread.produceData.set()
logging.info("I started meas")
LOGGER.info("I started meas")
def stop_measuring(self):
self.measureThread.produceData.clear()
logging.info("I stopped meas")
LOGGER.info("I stopped meas")
def exit(self):
self.stop_measuring()

View File

@ -1,20 +1,44 @@
import datetime
import json
import logging
import os
from CoreLibrary.Driver import Driver
from CoreLibrary.Sensor import Sensor
LOGGER = logging.getLogger("my_logger")
class Measurement:
"""
Handle data and write it in a file
"""
def attach(self, sensor):
pass
def __init__(self, name, path=None, comment=None, writer=None):
self.name = name
self.path = os.path.join(path or "./meas_values", self.name)
os.makedirs(self.path)
self.save_version_text(comment)
self.sensors = {}
self.drivers = {}
self.data_files = {}
self.data_files["log"] = self.create_file("log")
self.data_files = {} # sensor_name: file_handler
def create_file(self, name: str):
return open(os.path.join(self.path, name), "w")
def attach_sensor(self, sensor: Sensor, name: str):
self.sensors[name] = sensor
def attach_driver(self, driver: Driver, name: str):
self.drivers[name] = driver
def attach_combined(self, comb, name: str):
self.attach_sensor(comb, name)
self.attach_driver(comb, name)
def write_log(self, text: str):
self.data_files["log"].write(str(datetime.datetime.utcnow()) + ":\t" + text + "\n")
def append_data(self, sensor_name, data):
"""
@ -23,18 +47,21 @@ class Measurement:
TODO: file size limit, zip?
data: list of tuples: (timestamp, value)
"""
if sensor_name not in self.sensors:
return
LOGGER.info("append-data: " + sensor_name)
if sensor_name not in self.data_files:
self.data_files[sensor_name] = open(
os.path.join(self.path, f"{sensor_name}_data.csv"), "w"
)
self.data_files[sensor_name] = self.create_file(sensor_name)
for timestamp, value in zip(data[0], data[1]):
self.data_files[sensor_name].write(
f"{timestamp.isoformat()}, {timestamp.timestamp()}, {value}\n"
)
def save_version_text(self, comment):
with open(os.path.join(self.path, "version.txt"), "w") as file:
file.write("Version 0.1\n")
if comment:
file.write(comment + "\n")
file.write("More descriptions of relevant parameters\n")
params = {
"version": "0.1",
"Start time": datetime.datetime.utcnow().isoformat(),
}
with open(os.path.join(self.path, "params.json"), "w") as file:
json.dump(params, file, indent=4)

View File

@ -1,3 +1,5 @@
import logging
from logging.handlers import RotatingFileHandler
from time import sleep
from threading import Thread, Event
@ -6,17 +8,34 @@ from CoreLibrary.ExampleSensor import ExampleSensor
from CoreLibrary.Measurement import Measurement
from CoreLibrary.Plot_Data import Plot_Data
LOGGER = logging.getLogger("my_logger")
LOGGER.setLevel(logging.DEBUG)
LOGGER.propagate = False
class ExampleDriverWorker(Thread):
"""Communicates with the measuring hardware. Here we only produce random data."""
# create formatter
formatter = logging.Formatter('%(levelname)s %(asctime)s - %(module)s: %(message)s')
# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
# add formatter to ch
ch.setFormatter(formatter)
# add ch to logger
LOGGER.addHandler(ch)
fi = RotatingFileHandler("my_logger.log", maxBytes=10**5, backupCount=5)
fi.setLevel(logging.DEBUG)
fi.setFormatter(formatter)
LOGGER.addHandler(fi)
class DataWorker(Thread):
def __init__(self, pd):
super().__init__(name="Data_Worker")
self.exit_request = Event()
self.pd = pd
def run(self):
"""Worker method of a python Thread. Called when the Thread is started."""
while not self.exit_request.is_set():
self.pd.refresh()
sleep(1)
@ -28,6 +47,8 @@ class Param_Model:
self.sensors = {"mess1": ExampleSensor()}
self.__plot_data = []
self.__measurement = []
self.data_worker = DataWorker(self)
self.data_worker.start()
def new_measurement(self, name=None, writer=None) -> Measurement:
mess = Measurement(name=name)
@ -40,7 +61,8 @@ class Param_Model:
return plot_data
def refresh(self):
for name, sens in self.sensors:
LOGGER.debug("refresh")
for name, sens in self.sensors.items():
data = sens.get_data
for meas in self.__measurement:
meas.append_data(name, data)
@ -48,12 +70,17 @@ class Param_Model:
pd.append_data(name, data)
def stop_measuring(self):
for sens in self.sensors.items():
for sens in self.sensors.values():
sens.stop_measuring()
pass
def start_measuring(self):
pass
for sens in self.sensors.values():
sens.start_measuring()
def exit(self):
pass
LOGGER.warning("entering exit method")
for sens in self.sensors.values():
sens.exit()
for drv in self.drivers.values():
drv.exit()
self.data_worker.exit_request.set()

View File

@ -64,7 +64,7 @@ class Plot_Data:
old = self.data["time"][-1] - self.timeout
if time.size > 2:
drop_index = np.where(time < old)[0]
if len(drop_index) is not 0:
if len(drop_index) != 0:
drop_index = drop_index[-1]
self.queues[key] = (
self.queues[key][0][drop_index:],

View File

@ -1,29 +1,44 @@
from time import sleep
from shutil import rmtree
from CoreLibrary.Param_Model import Param_Model
from CoreLibrary.Measurement import Measurement
import matplotlib.pyplot as plt
def clean():
rmtree("meas_values")
def main(param_model: Param_Model):
sensor = param_model.sensors["mess1"]
driver = param_model.drivers["treib1"]
driver.set_config({"speed": 2})
status = driver.get_status()
plot_data = param_model.get_plot_data()
for speed in [1.0, 2.0, 3.0]:
print(speed)
driver.set_config({"speed": speed})
measurement = param_model.new_measurement(name=f"penis_{speed}", writer="CSV")
measurement.attach("mess1")
measurement.attach_sensor(sensor=sensor, name="mess1")
measurement.write_log("ich mag ramen")
param_model.start_measuring()
sleep(2)
param_model.stop_measuring()
print("main exited")
plt.plot(plot_data.data["time"], plot_data.data["mess1"])
plt.show()
sensor.start_measuring()
sleep(1)
sensor.stop_measuring()
print("test")
sensor.exit()
driver.exit()
if __name__ == '__main__':
print("HEADLESS RUN")
pd = Param_Model()
main(pd)
clean()
main(pd)
pd.exit()

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

17
GUI/main.py Normal file
View File

@ -0,0 +1,17 @@
import wx
from main_view import MainFrame
class MyApp(wx.App):
def OnInit(self):
self.frame = MainFrame()
self.SetTopWindow(self.frame)
self.frame.Show()
return True
# end of class MyApp
if __name__ == "__main__":
app = MyApp(0)
app.MainLoop()

241
GUI/main_view.py Normal file
View File

@ -0,0 +1,241 @@
#!/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

42
GUI/status_bar.py Normal file
View File

@ -0,0 +1,42 @@
import wx
class StatusPanel(wx.Panel):
def __init__(self, parent, pd):
super().__init__(parent, -1)
#TODO get proper data
data = {"over1":False,"over2":True,"motor":123}
sizer_status = wx.GridBagSizer(vgap=5, hgap=5)
self.status={}
self.green = wx.Bitmap("./GUI/img/green.bmp")
self.red = wx.Bitmap("./GUI/img/red.bmp")
row = 0
for key, val in data.items():
label = wx.StaticText(self, wx.ID_ANY, key)
sizer_status.Add(label, (row,0))
if type(val) is bool:
if val:
icon = wx.StaticBitmap(self,bitmap=self.green)
self.status[key] = icon
sizer_status.Add(icon, (row,1))
else:
icon = wx.StaticBitmap(self,bitmap=self.red)
self.status[key] = icon
sizer_status.Add(icon, (row,1))
else:
label = wx.StaticText(self, wx.ID_ANY, str(val))
self.status[key] = label
sizer_status.Add(label, (row,1))
row +=1
def update(self):
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))

270
view.py
View File

@ -1,270 +0,0 @@
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
#
# generated by wxGlade 1.0.2 on Sun Jul 4 21:23:20 2021
#
import importlib.machinery
import logging
from threading import Thread
import wx
# 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
from CoreLibrary.Param_Model import Param_Model
#from plotView import PlotPanel
from plotView import PlotPanel
LOGGER = logging.getLogger("myLogger")
# begin wxGlade: dependencies
# end wxGlade
# begin wxGlade: extracode
# end wxGlade
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
self.model = Param_Model()
self.pd = self.model.get_plot_data()
# 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.GridBagSizer(vgap=5, hgap=5)
grid_sizer_main.Add(sizer_status, (0, 0), (2, 1), wx.EXPAND, 0)
# TODO test
data = {"over1":False,"over2":True,"motor":123}
self.status={}
self.green = wx.Bitmap("./img/green.bmp")
self.red = wx.Bitmap("./img/red.bmp")
row = 0
for key, val in data.items():
label = wx.StaticText(self.panel_1, wx.ID_ANY, key)
sizer_status.Add(label, (row,0))
if type(val) is bool:
if val:
icon = wx.StaticBitmap(self.panel_1,bitmap=self.green)
self.status[key] = icon
sizer_status.Add(icon, (row,1))
else:
icon = wx.StaticBitmap(self.panel_1,bitmap=self.red)
self.status[key] = icon
sizer_status.Add(icon, (row,1))
else:
label = wx.StaticText(self.panel_1, wx.ID_ANY, str(val))
self.status[key] = label
sizer_status.Add(label, (row,1))
row +=1
self.tabs = wx.Notebook(self.panel_1, wx.ID_ANY)
grid_sizer_main.Add(self.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"])
self.plot_1 = PlotPanel(self.tabs, self.pd, plot, update)
self.tabs.AddPage(self.plot_1, "Temp")
plot = lambda ax, dat: ax.plot(dat["time"], dat["mess1"])
update = lambda im, dat: im.set_data(dat["time"], dat["mess1"])
self.plot_2 = PlotPanel(self.tabs, self.pd, plot, update)
self.tabs.AddPage(self.plot_2, "Multi")
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()
LOGGER.info("Closing")
wx.Exit()
def update(self, event):
#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
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()