reworked config handling

file is now only written when explicitly wanted, e.g. on button press.
global config stored instead as config object
This commit is contained in:
Martin Zietz
2021-02-04 15:33:19 +01:00
parent ef914ff6fc
commit 8d1870956f
5 changed files with 128 additions and 42 deletions
+79 -11
View File
@@ -1,14 +1,18 @@
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
from tkinter import filedialog
import globals as g
import cage_func as func
import numpy as np
import os
from os.path import exists
NORM_FONT = ()
HEADER_FONT = ("Arial", 13, "bold")
SUB_HEADER_FONT = ("Arial", 9, "bold")
BIG_BUTTON_FONT = ("Arial", 11, "bold")
SMALL_BUTTON_FONT = ("Arial", 9)
class HelmholtzGUI(Tk):
@@ -74,7 +78,6 @@ class TopMenu:
class ManualMode(Frame):
# ToDo: Add buttons to safe and set to 0
def __init__(self, parent, controller):
Frame.__init__(self, parent)
@@ -162,10 +165,15 @@ class ManualMode(Frame):
pady=5, padx=5, font=BIG_BUTTON_FONT)
execute_button.grid(row=row_counter, column=0, padx=5)
# add button for quick power_down
power_down_button = Button(self.buttons_frame, text="Power Down All", command=func.power_down_all,
pady=5, padx=5, font=BIG_BUTTON_FONT)
power_down_button.grid(row=row_counter, column=1, padx=5)
# add button for reinitialization
reinit_button = Button(self.buttons_frame, text="Reinitialize", command=func.setup_all,
pady=5, padx=5, font=BIG_BUTTON_FONT)
reinit_button.grid(row=row_counter, column=1, padx=5)
reinit_button.grid(row=row_counter, column=2, padx=5)
row_counter = row_counter + 1
# Add spacer to Frame below
@@ -250,6 +258,27 @@ class Configuration(Frame):
row_counter += 1
# Setup buttons to select config file
# Setup frame to house buttons:
self.file_select_frame = Frame(self)
self.file_select_frame.grid_rowconfigure(ALL, weight=1)
self.file_select_frame.grid_columnconfigure(ALL, weight=1)
self.file_select_frame.grid(row=row_counter, column=0, sticky=W, padx=20)
# Create and place buttons
# ToDo: comments
load_file_button = Button(self.file_select_frame, text="Load config file...", command=self.load_config,
pady=5, padx=5, font=SMALL_BUTTON_FONT)
load_file_button.grid(row=0, column=0, padx=5)
save_button = Button(self.file_select_frame, text="Save current config", command=self.save_config,
pady=5, padx=5, font=SMALL_BUTTON_FONT)
save_button.grid(row=0, column=1, padx=5)
save_as_button = Button(self.file_select_frame, text="Save current config as...", command=self.save_config_as,
pady=5, padx=5, font=SMALL_BUTTON_FONT)
save_as_button.grid(row=0, column=2, padx=5)
row_counter += 1
# Serial port settings frame:
port_frame = Frame(self)
port_frame.grid_rowconfigure(ALL, weight=1)
@@ -308,7 +337,7 @@ class Configuration(Frame):
self.fields[key] = []
for axis in range(3): # generate entry fields
field = Entry(value_frame, textvariable=self.entries[key][0][axis], width=10)
field.grid(row=row, column=axis+1, sticky=W, padx=2)
field.grid(row=row, column=axis + 1, sticky=W, padx=2)
self.fields[key].append(field) # safe access to field for use elsewhere
axis_label = Label(value_frame, text=key, padx=5, pady=5)
axis_label.grid(row=row, column=0, sticky=W)
@@ -347,7 +376,7 @@ class Configuration(Frame):
self.update_fields()
def restore_defaults(self): # restore all default settings
func.create_default_config(g.CONFIG_FILE) # overwrite config file with default
func.reset_config_to_default(g.CONFIG_FILE) # overwrite config file with default
func.setup_all() # setup everything with the defaults
self.update_fields() # update fields in config window
@@ -358,7 +387,8 @@ class Configuration(Frame):
for key in self.entries.keys():
for i in [0, 1, 2]:
value = func.read_config(g.AXIS_NAMES[i], self.entries[key][3]) # get value from config file
value = func.read_from_config(g.AXIS_NAMES[i], self.entries[key][3],
g.CONFIG_OBJECT) # get value from config file
self.entries[key][0][i].set(value) # set initial value on variable
type_value = self.entries[key][0][i].get() # get value with correct data type
factor = self.entries[key][4] # get unit conversion factor
@@ -371,7 +401,7 @@ class Configuration(Frame):
else: # value exceeds limits
self.fields[key][i].config(background="Red") # set colour of this entry to red to show problem
def implement(self): # update config file with user inputs into entry fields and reinitialize
def write_values(self): # update config file with user inputs into entry fields and reinitialize
# set serial ports for PSUs:
func.edit_config("PORTS", "xy_port", self.XY_port.get())
@@ -404,16 +434,17 @@ class Configuration(Frame):
message = "Attempted to set too high value for {s} {k}\n" \
"{v} {unit}, max. {mv} {unit} allowed.\n" \
"Excessive values may damage equipment!\n" \
"Do you really want to use this value?"\
.format(s=axis, k=key, v=value*factor, mv=round(max_value*factor, 1), unit=unit)
"Do you really want to use this value?" \
.format(s=axis, k=key, v=value * factor, mv=round(max_value * factor, 1), unit=unit)
elif value_ok == 'LOW':
min_value = g.default_arrays[config_key][2][i] # get min value
message = "Attempted to set too low value for {s} {k}\n" \
"{v} {unit}, min. {mv} {unit} allowed.\n" \
"Excessive values may damage equipment!\n" \
"Do you really want to use this value?"\
.format(s=axis, k=key, v=value*factor, mv=round(min_value*factor, 1), unit=unit)
else: message = "Unknown case, this should not happen."
"Do you really want to use this value?" \
.format(s=axis, k=key, v=value * factor, mv=round(min_value * factor, 1), unit=unit)
else:
message = "Unknown case, this should not happen."
# display pop-up message to ask user if he really wants the value
answer = messagebox.askquestion("Value out of Bounds", message)
@@ -423,9 +454,46 @@ class Configuration(Frame):
func.edit_config(g.AXIS_NAMES[i], config_key, value, True)
# if user chooses 'no' nothing happens, old value is kept
def implement(self):
self.write_values()
func.setup_all() # reinitialize devices and program with new values
self.update_fields() # update entry fields to show new values
def load_config(self): # ToDo: comments
directory = os.path.dirname(os.path.abspath(g.CONFIG_FILE))
filename = filedialog.askopenfilename(initialdir=directory, title="Select Config File",
filetypes=(("Config File", "*.ini*"), ("All Files", "*.*")))
if exists(filename):
g.CONFIG_FILE = filename
g.CONFIG_OBJECT = func.get_config_from_file(filename)
func.check_config(g.CONFIG_OBJECT)
func.setup_all()
self.update_fields()
elif filename == '':
func.ui_print("No file selected, could not load config.")
else:
func.ui_print("Selected file", filename, "does not seem to exist, could not load config.")
def save_config_as(self): # ToDo: comments
directory = os.path.dirname(os.path.abspath(g.CONFIG_FILE))
filename = filedialog.asksaveasfilename(initialdir=directory, title="Select Config File",
filetypes=([("Config File", "*.ini*")]),
defaultextension=[("Config File", "*.ini*")])
if exists(filename):
g.CONFIG_FILE = filename
self.write_values()
func.write_config_to_file(g.CONFIG_OBJECT)
self.update_fields()
elif filename == '':
func.ui_print("No file selected, could not save config.")
else:
func.ui_print("Selected file", filename, "does not seem to exist, could not save config.")
def save_config(self): # ToDo: comments
self.write_values()
func.write_config_to_file(g.CONFIG_OBJECT)
self.update_fields()
class StatusDisplay(Frame):