def delete_run(self): table_ids = [] program_names = [] program_types = [] conf_parser = configparser.ConfigParser() conf_parser.read(PROG_CONFIG_PATH) for item in self.tree.selection(): values = self.tree.item(item)['values'] table_id = values[0] table_ids.append(table_id) is_running = False try: is_running = conf_parser.getboolean( BAKING, "running") or conf_parser.getboolean( CAL, "running") except configparser.NoOptionError: pass except configparser.NoSectionError: reset_config.reset_config(rewrite_program=True) if table_id is not None and table_id == self.current_table_id and is_running: mbox.showerror("Deletion Error", "Cannot delete the currently running program.") return program_name = values[1] program_names.append(program_name) program_type = values[2] program_types.append(program_type) message = "Are you sure you would like to delete the runs: {}?".format( ", ".join(program_names)) if mbox.askyesno("Delete Programs", message): delete_tables(table_ids, program_types) self.refresh()
def __init__(self, *args, **kwargs): """ Setup the main program gui skeleton. :param args: additional positional arguments to pass to the Tk constructor :param kwargs: additional keyword arguments to pass to the Tk constructor """ super().__init__(*args, **kwargs) install.install() reset_config.reset_config() self.conf_parser = configparser.ConfigParser() self.conf_parser.read(os.path.join("config", "devices.cfg")) self.manager = None # type: visa.ResourceManager try: self.manager = visa.ResourceManager() except OSError as e: if "VISA" in str(e): mbox.showerror("NIVisa not installed", "Need to install NIVisa to run the program.") self.destroy() raise RuntimeError("NIVisa not installed.") self.main_queue = Queue() self.thread_map = {} # type: Dict[UUID, bool] self.open_threads = [] # type: List[UUID] self.graph_threads = [] # type: List[UUID] self.running = False self.running_prog = None # type: Optional[str] self.temp_controller = None # type: Optional[TemperatureController] self.oven = None # type: Optional[Oven] self.laser = None # type: Optional[SM125] self.switch = None # type: Optional[OpticalSwitch] self.is_full_screen = False self.excel_table = None # type: create_excel_table.ExcelTable self.controller_location = tk.StringVar() self.oven_location = tk.StringVar() self.op_switch_address = tk.StringVar() self.op_switch_port = tk.IntVar() self.sm125_address = tk.StringVar() self.sm125_port = tk.IntVar() uh.setup_style() self.setup_window() self.main_notebook = ttk.Notebook(self) self.main_notebook.enable_traversal() self.home_frame = None # type: ttk.Frame self.device_frame = None # type: ttk.Frame self.log_view = None # type: messages.LogView self.setup_home_frame() self.bake_program = None # type: BakingProgram self.calibration_program = None # type: CalProgram self.check_queue()
def __init__(self, master: Application, program_type: ProgramType): """ Sets up the program UI, and data structures. :param master: master Application program :param program_type: type of program that is being created """ style = ttk.Style() style.configure('InnerNB.TNotebook', tabposition='wn') super().__init__(master.main_notebook, style='InnerNB.TNotebook') self.conf_parser = configparser.ConfigParser() self.conf_parser.read(PROG_CONFIG_PATH) self.master = master self.program_type = program_type self.channels = [[], [], [], []] # type: List[List[str]] self.switches = [[], [], [], []] # type: List[List[int]] self.snums = [] # type: List[str] self.start_btn = None # type: ttk.Button self.need_oven = False self.options = None # type: options_frame.OptionsPanel self.table = None # type: DataTable self.graph_helper = None # type: graphing.Graphing self.database_controller = None # type: DatabaseController # Needed to avoid garbage collection self.config_photo = ImageTk.PhotoImage(Image.open(CONFIG_IMG_PATH)) self.graph_photo = ImageTk.PhotoImage(Image.open(GRAPH_PATH)) self.file_photo = ImageTk.PhotoImage(Image.open(FILE_PATH)) self.setup_tabs() is_running = False try: try: is_running = self.program_type.prog_id == BAKING and self.conf_parser.getboolean( BAKING, "running") except configparser.NoOptionError: pass try: is_running = is_running or self.program_type.prog_id == CAL \ and self.conf_parser.getboolean(CAL, "running") except configparser.NoOptionError: pass except configparser.NoSectionError: reset_config.reset_config(rewrite_program=True) if is_running: self.start()
def init_fbgs(self): """ Initialize the fbg input section of the options page, using settings stored in prog_config.""" for i in range(4): title_frame = ttk.Frame(self.fbg_grid) ttk.Label(title_frame, text="Channel {}".format(i + 1), style="Bold.TLabel")\ .pack(side='left', anchor='w') buttons_frame = ttk.Frame(title_frame) ttk.Button(buttons_frame, image=self.img_minus, command=lambda chan=i: self.minus_fbg(chan)) \ .pack(side="left", anchor='e') ttk.Button(buttons_frame, image=self.img_plus, command=lambda col=i, chan=i: self.add_fbg(chan)).pack( side='left', anchor='e') buttons_frame.pack(anchor='e') title_frame.grid(sticky='nsew', column=i, row=0) for i in range(4): try: try: snums = self.conf_parser.get( self.program, "chan{}_fbgs".format(i + 1)).split(",") except configparser.NoOptionError: return try: positions = self.conf_parser.get( self.program, "chan{}_positions".format(i + 1)).split(",") except configparser.NoOptionError: return except configparser.NoSectionError: reset_config.reset_config(rewrite_program=True) return if len(snums) != len(positions): return try: positions = helpers.list_cast(positions, int) for snum, pos in zip(snums, positions): self.add_fbg(i, snum, pos) except ValueError: for snum in snums: if snum: self.add_fbg(i, snum)
def get_configured_fbg_names(is_calibration: bool) -> List[str]: """ Get the serial numbers recorded in the prog_config configuration file, under the header based on the is_cal parameter :param is_calibration: True if program is calibration, False otherwise :return: list of serial numbers """ program = BAKING if is_calibration: program = CAL parser = configparser.ConfigParser() parser.read(PROG_CONFIG_PATH) serial_nums = [] for i in range(4): try: serial_nums.extend( parser.get(program, "chan{}_fbgs".format(i + 1)).split(",")) except configparser.NoOptionError: pass except configparser.NoSectionError: reset_config.reset_config(rewrite_program=True) serial_nums = [s for s in serial_nums if s != ''] return serial_nums
def __init__(self, parent: ttk.Frame, program: str): super().__init__(parent) self.sn_ents = [[], [], [], []] # type: List[List[tk.Entry]] self.chan_nums = [[], [], [], []] # type: List[List[int]] self.switch_positions = [[], [], [], []] # type: List[List[tk.IntVar]] self.snum_frames = [[], [], [], []] # type: List[List[ttk.Frame]] self.selected_fbgs = [[], [], [], []] # type: List[List[tk.IntVar]] self.extra_points = [] # type: List[List[tk.DoubleVar]] self.file_name = tk.StringVar() self.prim_time = tk.DoubleVar() self.num_pts = tk.IntVar() self.num_temp_readings = tk.IntVar() self.temp_interval = tk.IntVar() self.drift_rate = tk.DoubleVar() self.num_cal_cycles = tk.IntVar() self.set_temp = tk.DoubleVar() self.cooling = tk.IntVar() self._bake_sensitivity = None # type: tk.Text self.target_temps_entry = None # type: tk.Text self.program = program self.options_grid = ttk.Frame(self) self.conf_parser = configparser.ConfigParser() self.conf_parser.read(os.path.join("config", "prog_config.cfg")) if self.program == BAKING: text = "Configure Baking Run" ttk.Label(self, text=text).pack(anchor="center", pady=20) else: text = "Configure Calibration Run" header = ttk.Frame(self) header.pack(anchor=tk.W, pady=5) ttk.Label(header, text=text).pack(anchor=tk.W, side=tk.LEFT) try: use_cool = self.conf_parser.getboolean(self.program, "use_cool") except configparser.NoOptionError: use_cool = False self.cooling = tk.IntVar() ttk.Label(header, text="Use oven cooling function?").pack(side=tk.LEFT, padx=50) checkbox = ttk.Checkbutton(header, variable=self.cooling, width=5) checkbox.pack(side=tk.LEFT) if use_cool: checkbox.invoke() self.options_grid.pack(expand=True, fill="both", anchor="center") self.fbg_grid = ttk.Frame(self) self.fbg_grid.pack(expand=True, fill="both", anchor="n") # Prevent from being garbage collected path = os.path.join(ASSETS_PATH, 'plus.png') self.img_plus = tk.PhotoImage(file=path) path = os.path.join(ASSETS_PATH, 'minus.png') self.img_minus = tk.PhotoImage(file=path) try: self.create_options_grid() except configparser.NoSectionError: reset_config.reset_config(rewrite_program=True) mbox.showerror("Internal error", "Please restart the program.")
def setup_home_frame(self): """Sets up the home frame, ttk frame, that is displayed on launch.""" self.home_frame = ttk.Frame(self.main_notebook) self.main_notebook.add(self.home_frame, text="Home") self.main_notebook.pack(side="top", fill="both", expand=True) hframe = ttk.Frame(self.home_frame) hframe.pack() self.device_frame = ttk.Frame(hframe) col = 0 self.device_frame.grid_columnconfigure(col, minsize=10) col = 2 while col < 8: self.device_frame.grid_columnconfigure(col, minsize=20) col += 2 self.device_frame.grid_columnconfigure(col, minsize=100) self.device_frame.grid_rowconfigure(0, minsize=10) ttk.Label(self.device_frame, text="Device", style="Bold.TLabel").grid(row=1, column=1, sticky='nsew') ttk.Label(self.device_frame, text="Location", style="Bold.TLabel").grid(row=1, column=3, sticky='nsew') ttk.Label(self.device_frame, text="Port", style="Bold.TLabel").grid(row=1, column=5, sticky='nsew') laser_loc, laser_port, switch_loc, switch_port, temp_loc, oven_loc = "", "", "", "", "", "" try: try: laser_loc = self.conf_parser.get(constants.DEV_HEADER, "sm125_address") except configparser.NoOptionError: pass try: laser_port = self.conf_parser.get(constants.DEV_HEADER, "sm125_port") except configparser.NoOptionError: pass try: switch_loc = self.conf_parser.get(constants.DEV_HEADER, "op_switch_address") except configparser.NoOptionError: pass try: switch_port = self.conf_parser.get(constants.DEV_HEADER, "op_switch_port") except configparser.NoOptionError: pass try: temp_loc = self.conf_parser.get(constants.DEV_HEADER, "controller_location") except configparser.NoOptionError: pass try: oven_loc = self.conf_parser.get(constants.DEV_HEADER, "oven_location") except configparser.NoOptionError: pass except configparser.NoSectionError: reset_config.reset_config(rewrite_dev=True) switch_conf = [(constants.LASER, laser_loc, laser_port, self.sm125_address, self.sm125_port), (constants.SWITCH, switch_loc, switch_port, self.op_switch_address, self.op_switch_port), (constants.TEMP, temp_loc, None, self.controller_location, None), (constants.OVEN, oven_loc, None, self.oven_location, None)] for i, dev in enumerate(switch_conf): self.device_frame.grid_rowconfigure(i * 2, pad=20) uh.device_entry(self.device_frame, dev[0], dev[1], i + 2, dev[2], dev[3], dev[4]) self.device_frame.pack(anchor=tk.CENTER, expand=True, pady=15) self.log_view = messages.LogView(hframe) self.log_view.pack(expand=True, fill=tk.BOTH, side=tk.LEFT, anchor=tk.W, padx=25, pady=50) self.excel_table = create_excel_table.ExcelTable(hframe, self.main_queue) self.excel_table.pack(anchor=tk.E, expand=True, side=tk.LEFT, padx=25)