From 5a3625021e60703dc775fef0b4e49755ff629aee Mon Sep 17 00:00:00 2001 From: Leon Teichroeb Date: Fri, 22 Oct 2021 20:56:16 +0200 Subject: [PATCH] Cleaned main.py. Renamed exit_flag global. --- main.py | 98 +++++++++++++++++++----------------- src/csv_threading.py | 4 +- src/globals.py | 2 +- src/helmholtz_cage_device.py | 2 - src/utility.py | 2 +- 5 files changed, 56 insertions(+), 52 deletions(-) diff --git a/main.py b/main.py index 2809b56..66b82ff 100644 --- a/main.py +++ b/main.py @@ -1,45 +1,23 @@ +#!/usr/bin/env python # Main file of the program. Run this file to start the application. -# ToDo: improve performance, communication to PSUs is way too slow for dynamic field changes -# import packages: + + from os.path import exists import traceback -from threading import Thread from tkinter import messagebox -# import other project files: from src.helmholtz_cage_device import HelmholtzCageDevice import src.globals as g import src.config_handling as config import src.csv_logging as log from src.magnetometer import MagnetometerProxy -from src.user_interface import HelmholtzGUI, ExecuteCSVMode +from src.user_interface import HelmholtzGUI from src.socket_control import SocketInterfaceThread from src.utility import ui_print -def program_end(): # called on exception or when user closes application - # safely shuts everything down and saves any unsaved data - - g.exitFlag = True # tell everything else the application has been closed - if g.app is not None: # the main Tkinter app object has been initialized before - if g.app.pages[ExecuteCSVMode].csv_thread is not None: # check if a thread for executing CSVs exists - g.app.pages[ExecuteCSVMode].csv_thread.stop() # stop the thread - - g.CAGE_DEVICE.destroy() # shut down devices and end all threads. - - if log.unsaved_data: # Check if there is logged data that has not been saved yet - # open pop-up to ask user if he wants to save the data: - save_log = messagebox.askquestion("Save log data?", "There seems to be unsaved logging data. " - "Do you wish to write it to a file now?") - if save_log == 'yes': # user has chosen yes - filepath = log.select_file() # let user select a file to write to - log.write_to_file(filepath) # write the data to the chosen file - - if g.app is not None: - g.app.destroy() # close application - - -try: # start normal operations +def program_start(): + """ Application entry point """ print("Starting application") config.CONFIG_FILE = 'config.ini' # set the config file path @@ -56,33 +34,61 @@ try: # start normal operations # Mostly a data structure to hold field data broadcast by connected tcp client with HW access. g.MAGNETOMETER = MagnetometerProxy() - g.app = HelmholtzGUI() # initialize user interface - g.exitFlag = False # tell all functions that the user interface is now running + # initialize user interface + g.app = HelmholtzGUI() + # tell all functions that the user interface is now runnings + g.exit_flag = False # Connect hardware to HelmholtzCageDevice adapter object g.CAGE_DEVICE.reconnect_hardware_async() - # g.app.state('zoomed') # open UI in maximized window - # g.app.StatusDisplay.continuous_label_update(g.app, 1000) # initiate regular Status Display updates (ms) - # ToDo: label update is very slow, commented out to save performance but should be implemented - # ToDo!: csv thread + continuous label update seems to exceed capacity of PSU communication - ui_print("Program Initialized") - config.check_config(config.CONFIG_OBJECT) # check config for values exceeding limits + # check config for values exceeding limits + config.check_config(config.CONFIG_OBJECT) # Create TCP/Socket listener socket_controller = SocketInterfaceThread() socket_controller.start() - g.app.protocol("WM_DELETE_WINDOW", program_end) # call program_end function if user closes the application + # call program_end function if user closes the application + g.app.protocol("WM_DELETE_WINDOW", program_end) - g.app.mainloop() # start main program loop + ui_print("Application initialized") + # start main program loop + g.app.mainloop() -except Exception as e: # An error has occurred somewhere in the program - print("\nAn error occurred, Shutting down.") - # shop pup-up error message: - message = "%s.\nSee python console traceback for more details. " \ - "\nShutting down devices, check equipment to confirm." % e - messagebox.showerror("Error!", message) - print(traceback.print_exc()) # print error traceback in the python console - program_end() # safely close everything and shut down devices +def program_end(): + """ Safely shuts everything down and saves any unsaved data. + Called on exception or when user closes application """ + + # tell everything else the application has been closed + g.exit_flag = True + + # shut down devices and end all threads. + g.CAGE_DEVICE.destroy() + + if log.unsaved_data: # Check if there is logged data that has not been saved yet + # open pop-up to ask user if he wants to save the data: + save_log = messagebox.askquestion("Save log data?", "There seems to be unsaved logging data. " + "Do you wish to write it to a file now?") + if save_log == 'yes': # user has chosen yes + filepath = log.select_file() # let user select a file to write to + log.write_to_file(filepath) # write the data to the chosen file + + if g.app is not None: + g.app.destroy() # close application + + +if __name__ == '__main__': + try: + program_start() + except Exception as e: # An error has occurred somewhere in the program + print("\nAn error occurred, shutting down.") + # shop pop-up error message: + message = "%s.\nSee Python console traceback for more details. " \ + "\nShutting down devices, check equipment to confirm." % e + messagebox.showerror("Error!", message) + # print error traceback in the python console + print(traceback.print_exc()) + # safely close everything and shut down devices + program_end() diff --git a/src/csv_threading.py b/src/csv_threading.py index 841c438..a48ef77 100644 --- a/src/csv_threading.py +++ b/src/csv_threading.py @@ -45,7 +45,7 @@ class ExecCSVThread(Thread): self.cage_dev.close() # when the sequence has ended, reset buttons on the UI: - if not g.exitFlag: # main window is open + if not g.exit_flag: # main window is open self.parent.select_file_button["state"] = "normal" self.parent.execute_button["state"] = "normal" self.parent.stop_button["state"] = "disabled" @@ -79,7 +79,7 @@ class ExecCSVThread(Thread): i = 0 # index of the current array row while i < len(array): - if self.stopped or g.exitFlag: + if self.stopped or g.exit_flag: # Interrupt sequence ui_print("Sequence interrupted, powering down channels.") # Channels powered down in run function diff --git a/src/globals.py b/src/globals.py index 0e2d9c6..0fccb56 100644 --- a/src/globals.py +++ b/src/globals.py @@ -22,7 +22,7 @@ global PORTS # list containing [XY_PORT, XY_PORT, Z_PORT], used in loops where global threadLock # thread locking object, used to force threads to perform actions in a certain order (threading.Lock) -exitFlag = True # False when main window is open, True otherwise +exit_flag = True # False when main window is open, True otherwise # Create dictionaries with default Constants and maximum/minimum values # Used to create default configs and to check if user inputs are within safe limits diff --git a/src/helmholtz_cage_device.py b/src/helmholtz_cage_device.py index 42579cc..d27350e 100644 --- a/src/helmholtz_cage_device.py +++ b/src/helmholtz_cage_device.py @@ -95,8 +95,6 @@ class HelmholtzCageDevice: # TODO: Move to proxy def connect_hardware(self): """Connects devices. Does not check if they are already connected: Remember to call shutdown first""" - time.sleep(3) - with self.hardware_lock: # All devices are usable if the object exists. None indicates # the device is not connected/not working properly diff --git a/src/utility.py b/src/utility.py index 3346833..c1fdcde 100644 --- a/src/utility.py +++ b/src/utility.py @@ -7,7 +7,7 @@ def ui_print(*content): """prints text to built-in console, use exactly like normal print(). Requires the ui to be initialized""" output = " ".join([str(c) for c in content]) - if not g.exitFlag and g.app is not None: # application is still running --> output window is visible + if not g.exit_flag and g.app is not None: # application is still running --> output window is visible 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 console to bottom