diff --git a/User_Interface.py b/User_Interface.py index a056c59..bb2db06 100644 --- a/User_Interface.py +++ b/User_Interface.py @@ -214,7 +214,7 @@ class ManualMode(Frame): field = g.AXES[i].max_comp_field * 1e6 else: field = [0, 0] - func.ui_print("Unexpected value encountered: compensate =", comp) + ui_print("Unexpected value encountered: compensate =", comp) val.set("(%0.1f to %0.1f \u03BCT)" % (field[0], field[1])) i += 1 @@ -236,22 +236,22 @@ class ManualMode(Frame): self.controller.StatusDisplay.update_labels() # update status display after change def execute_field(self, vector): - func.ui_print("field executing", vector) + ui_print("field executing", vector) comp = self.compensate.get() if comp == 1: func.set_field(vector * 1e-6) elif comp == 0: func.set_field_simple(vector * 1e-6) else: - func.ui_print("Unexpected value encountered: compensate =", comp) + ui_print("Unexpected value encountered: compensate =", comp) @staticmethod def execute_current(vector): - func.ui_print("current executing:", vector) + ui_print("current executing:", vector) try: func.set_current_vec(vector) except ValueError as e: - func.ui_print(e) + ui_print(e) class Configuration(Frame): @@ -425,7 +425,7 @@ class Configuration(Frame): try: value = self.entries[key][0][i].get() # get value from field except TclError as e: # wrong format entered, e.g. text in number fields - func.ui_print("Invalid entry for %s %s %s" % (g.AXIS_NAMES[i], key, e)) + ui_print("Invalid entry for %s %s %s" % (g.AXIS_NAMES[i], key, e)) else: # format is ok factor = self.entries[key][4] # get unit conversion factor @@ -484,9 +484,9 @@ class Configuration(Frame): func.setup_all() # reinitialize devices and program with new values self.update_fields() # update entry fields to show new values elif filename == '': # this happens when file selection window is closed without selecting a file - func.ui_print("No file selected, could not load config.") + ui_print("No file selected, could not load config.") else: - func.ui_print("Selected file", filename, "does not exist, could not load config.") + ui_print("Selected file", filename, "does not exist, could not load config.") def save_config_as(self): # save current configuration to a new config file directory = os.path.dirname(os.path.abspath(config.CONFIG_FILE)) # get directory of current config file @@ -496,17 +496,19 @@ class Configuration(Frame): defaultextension=[("Config File", "*.ini*")]) if filename == '': # this happens when file selection window is closed without selecting a file - func.ui_print("No file selected, could not save config.") + ui_print("No file selected, could not save config.") else: # a file name was entered config.CONFIG_FILE = filename # set global config file to the new file self.write_values() # write current entry field values to the config object config.write_config_to_file(config.CONFIG_OBJECT) # write contents of config object to file + func.setup_all() # reinitialize devices and program with new values self.update_fields() # update entry fields to show values as they are in the config def save_config(self): # same as save_config_as() but with the current config file self.write_values() config.write_config_to_file(config.CONFIG_OBJECT) - self.update_fields() + func.setup_all() # reinitialize devices and program with new values + self.update_fields() # update entry fields to show values as they are in the config class ExecuteCSVMode(Frame): @@ -563,19 +565,19 @@ class ExecuteCSVMode(Frame): filename = filedialog.askopenfilename(initialdir=directory, title="Select CSV File", filetypes=(("Comma Separated Values", "*.csv*"), ("All Files", "*.*"))) if exists(filename): # does the file exist? - func.ui_print("File selected:", filename) + ui_print("File selected:", filename) try: self.sequence_array = csv.read_csv_to_array(filename) except BaseException as e: - func.ui_print("Error while opening file:", e) + ui_print("Error while opening file:", e) # ToDo: make error a popup # ToDo: check for excessive values self.execute_button["state"] = "normal" # activate run button elif filename == '': # this happens when file selection window is closed without selecting a file - func.ui_print("No file selected, could not load.") + ui_print("No file selected, could not load.") else: - func.ui_print("Selected file", filename, "does not exist, could not load.") + ui_print("Selected file", filename, "does not exist, could not load.") def run_sequence(self): # (de)activate buttons as needed: @@ -688,3 +690,15 @@ class OutputConsole(Frame): # console to print stuff in, similar to standard py self.console.grid(row=0, column=0, sticky="nesw") scrollbar.config(command=self.console.yview) self.console.config(yscrollcommand=scrollbar.set) + + +def ui_print(*content): # prints text to built in console + output = "" + for text in content: + output = " ".join((output, str(text))) # append content + if g.app is not None: + output = "".join(("\n", output)) # begin new line each time + g.app.OutputConsole.console.insert(END, output) # print to console + g.app.OutputConsole.console.see(END) # scroll to bottom + else: # if window is not open, do normal print + print(output) \ No newline at end of file diff --git a/cage_func.py b/cage_func.py index a892022..e3f6c75 100644 --- a/cage_func.py +++ b/cage_func.py @@ -1,8 +1,8 @@ import numpy as np import serial import traceback -from tkinter import * +from User_Interface import ui_print from pyps2000b import PS2000B from Arduino import Arduino # noinspection PyPep8Naming @@ -177,18 +177,6 @@ class ArduinoCtrl(Arduino): self.digitalWrite(pin, "LOW") -def ui_print(*content): # prints text to built in console - output = "" - for text in content: - output = " ".join((output, str(text))) # append content - if g.app is not None: - output = "".join(("\n", output)) # begin new line each time - g.app.OutputConsole.console.insert(END, output) # print to console - g.app.OutputConsole.console.see(END) # scroll to bottom - else: # if window is not open, do normal print - print(output) - - def value_in_limits(axis, key, value): # Check if value is within safe limits (set in globals.py) max_value = g.default_arrays[key][1][g.AXIS_NAMES.index(axis)] # get max value min_value = g.default_arrays[key][2][g.AXIS_NAMES.index(axis)] # get min value diff --git a/config_handling.py b/config_handling.py index 13ff1ad..5651efe 100644 --- a/config_handling.py +++ b/config_handling.py @@ -6,8 +6,8 @@ import cage_func as func # noinspection PyPep8Naming import User_Interface as ui -global CONFIG_FILE -global CONFIG_OBJECT +global CONFIG_FILE # variable storing the path of the used config file +global CONFIG_OBJECT # object of type ConfigParser(), storing all configuration information def get_config_from_file(file): @@ -27,7 +27,7 @@ def read_from_config(section, key, config_object): # read specific value from c value = section_obj[key] # get relevant value in the section return value except KeyError as e: - func.ui_print("Error while reading config file:", e) + ui.ui_print("Error while reading config file:", e) raise KeyError("Could not find key", key, "in config file.") @@ -57,22 +57,22 @@ def edit_config(section, key, value, override=False): # edit specific value in try: section_obj = config_object[section] # get relevant section except KeyError: - func.ui_print("Could not find section", section, "in config file, creating new.") + ui.ui_print("Could not find section", section, "in config file, creating new.") config_object.add_section(section) section_obj = config_object[section] try: section_obj[key] = str(value) # set relevant value in the section except KeyError: - func.ui_print("Could not find key", key, "in config file, creating new.") + ui.ui_print("Could not find key", key, "in config file, creating new.") config_object.set(section, key, str(value)) except KeyError as e: - func.ui_print("Error while editing config file:", e) + ui.ui_print("Error while editing config file:", e) raise KeyError("Could not find key", key, "in config file.") def check_config(config_object): # check all numeric values in the config and see if they are within safe limits - func.ui_print("Checking config file for values exceeding limits:") + ui.ui_print("Checking config file for values exceeding limits:") i = 0 concerns = {} # initialize dictionary for found problems problem_counter = 0 @@ -90,7 +90,7 @@ def check_config(config_object): # check all numeric values in the config and s if len(concerns[axis]) == 0: concerns[axis].append("No problems detected.") - func.ui_print(axis, ":", *concerns[axis]) # print out results for this axis + ui.ui_print(axis, ":", *concerns[axis]) # print out results for this axis i += 1 if problem_counter > 0: # some values are not ok # shop pup-up warning message: @@ -101,7 +101,8 @@ def check_config(config_object): # check all numeric values in the config and s def reset_config_to_default(file): # reset values in config object to defaults (stored in globals.py) config = ConfigParser() # initialize global config object - config.CONFIG_OBJECT = config + global CONFIG_OBJECT + CONFIG_OBJECT = config i = 0 for axis_name in g.AXIS_NAMES: # go through axes diff --git a/csv_threading.py b/csv_threading.py index fedd674..0841dae 100644 --- a/csv_threading.py +++ b/csv_threading.py @@ -1,3 +1,4 @@ +import User_Interface as ui import cage_func as func import time import pandas @@ -16,7 +17,7 @@ class ExecCSVThread(Thread): self.controller = controller # object on which mainloop() is running, usually main window def run(self): - func.ui_print("Starting Sequence Execution...") + ui.ui_print("Starting Sequence Execution...") # g.threadLock.acquire() # Get lock to synchronize threads # ToDo: add locking/synchronization? Works without so far but might be more robust execute_sequence(self.array, 0.1, self.controller) @@ -38,10 +39,10 @@ def execute_sequence(array, delay, controller): # runs through array containing t = time.time() - t_zero # get relative time if t >= array[i, 0]: # time for this row has come field_vec = array[i, 1:4] # extract desired field vector - func.ui_print("%f s: t = %0.2f s, target field vector = " - % (time.time()-t_zero, array[i, 0]), field_vec*1e6, "\u03BCT") + ui.ui_print("%f s: t = %0.2f s, target field vector = " + % (time.time()-t_zero, array[i, 0]), field_vec * 1e6, "\u03BCT") func.set_field_simple(field_vec) # send field vector to test stand # ToDo!: reset to set_field() - func.ui_print(time.time()-t_zero) + ui.ui_print(time.time() - t_zero) controller.StatusDisplay.update_labels() # update status display after change i = i + 1 # next row @@ -50,16 +51,16 @@ def execute_sequence(array, delay, controller): # runs through array containing else: # sleep to give other threads time to run time.sleep(delay) if g.running: # sequence ended without interruption - func.ui_print("Sequence executed, powering down channels.") + ui.ui_print("Sequence executed, powering down channels.") else: # interrupted by user - func.ui_print("Sequence cancelled, powering down channels.") + ui.ui_print("Sequence cancelled, powering down channels.") func.power_down_all() # set currents and voltages to 0, set arduino pins to low def read_csv_to_array(filepath): # csv format: time (s); xField (T); yField (T); zField (T) # decimal commas - func.ui_print("Reading File:", filepath) + ui.ui_print("Reading File:", filepath) file = pandas.read_csv(filepath, sep=';', decimal=',', header=0) # read csv file array = file.to_numpy() # convert csv to array return array diff --git a/main.py b/main.py index d1dc877..2bd46c0 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,8 @@ from os.path import exists -from User_Interface import HelmholtzGUI import cage_func as func +from User_Interface import HelmholtzGUI +from User_Interface import ui_print import traceback import globals as g import config_handling as config @@ -24,10 +25,10 @@ try: # start normal operations print("\nOpening User Interface...") g.app = HelmholtzGUI() - func.ui_print("Program Initialized") + ui_print("Program Initialized") config.check_config(config.CONFIG_OBJECT) # check config for values exceeding limits - func.ui_print("\nStarting setup...") # do it again, so it is printed in the UI console ToDo: do it only once + ui_print("\nStarting setup...") # do it again, so it is printed in the UI console ToDo: do it only once func.setup_all() # initiate communication, set handles g.app.mainloop() g.app = None # reset to None so nothing tries to print in the UI output