class MyApp(Tk): """ This class serves as a central control. Where are all process are launched and variables are set and shared. """ __title__ = "Senior" def __init__(self, *args, **kwargs): Tk.__init__(self, *args, **kwargs) container = Frame(self) container.grid() self.serial = SerialComm() self.frames = {} self.q = LifoQueue() self.eye_tracker = EyeTracker(self.q) self.variables = {} self.fps = IntVar() self.fps.set(20) self.temp = IntVar() self.temp.set(20) self.temp.trace("w", self.send_command) self.variables[self.temp.__str__()] = 't', self.temp self.temp_current = StringVar() self.temp_current.set('Temperature') self.tts = StringVar() self.tts.set('Type and Play') self.temp_offset = IntVar() self.temp_offset.set(5) self.temp_offset.trace("w", self.send_command) self.variables[self.temp_offset.__str__()] = 'o', self.temp_offset self.samples = 9 self.window = IntVar() self.window.trace("w", self.send_command) self.variables[self.window.__str__()] = 'w', self.window self.mouse_control = BooleanVar() self.mouse_control.set(False) self.talk = BooleanVar() self.talk.set(True) self.alarm = BooleanVar() self.alarm.set(False) self.alarm.trace("w", self.send_command) self.variables[self.alarm.__str__()] = 'a', self.alarm self.light = BooleanVar() self.light.set(False) self.light.trace("w", self.send_command) self.variables[self.light.__str__()] = 'l', self.light self.heater = BooleanVar() self.heater.set(False) self.heater.trace("w", self.send_command) self.variables[self.heater.__str__()] = 'h', self.heater self.ac = BooleanVar() self.ac.set(False) self.ac.trace("w", self.send_command) self.variables[self.ac.__str__()] = 'f', self.ac self.move = BooleanVar() self.move.set(False) self.w, self.h = pyautogui.size() self.hor_div = DoubleVar() self.hor_div.set(5) self.hor_div.trace("w", self.send_command) self.variables[self.hor_div.__str__()] = 'hor', self.hor_div self.ver_div = DoubleVar() self.ver_div.set(5) self.ver_div.trace("w", self.send_command) self.variables[self.ver_div.__str__()] = 'ver', self.ver_div self.mouse_directions = [] self.mouse = MouseAndSpeech(self) self.t = Thread(target=self.mouse.process) self.t.start() self.frame = None self.draw = False frame = Preview(container, self) self.frames[Preview] = frame frame.grid(row=0, column=1, sticky="nsew", rowspan=100) self.current_frame = frame frame = Settings(container, self) self.frames[Settings] = frame frame.grid(row=0, column=0, sticky="nsew", pady=10, padx=10) frame.grid_remove() frame = Applications(container, self) self.frames[Applications] = frame frame.grid(row=0, column=0, sticky="nsew", pady=10, padx=10) frame.grid_remove() # Menu Bar menu = MyMenu(self) self.config(menu=menu) Tk.iconbitmap(self, default=resource_path('icon.ico')) Tk.wm_title(self, "Senior") w = (self.winfo_screenwidth() - self.eye_tracker.window_size) // 2 self.geometry('+{}+{}'.format(w, 0)) self.protocol("WM_DELETE_WINDOW", lambda: self.close()) def show_frame(self, cont): """ This method is used to switch betwen views. """ if self.current_frame is not None: self.current_frame.grid_remove() frame = self.frames[cont] frame.grid() self.current_frame = frame if cont is Applications: frame.button_alarm.focus() def send_command(self, widget, *args): """ This method send data to the Arduino whenever a button is clicked. """ w = self.variables[widget] try: indicator = w[0] value = str(int(w[1].get())) if indicator == 'f' and value == '1': self.heater.set(False) self.serial.send_serial('h0') elif indicator == 'h' and value == '1': self.ac.set(False) self.serial.send_serial('f0') elif indicator == 't': self.heater.set(False) self.ac.set(False) s = indicator + value self.serial.send_serial(s) if len(value) > 0: value = float(w[1].get()) if indicator in ['ver', 'hor']: x_offset = self.ver_div.get() y_offset = self.hor_div.get() if indicator == 'ver': y_offset = value * (self.h // 100) elif indicator == 'hor': x_offset = value * (self.w // 100) self.mouse_directions = [(-x_offset, -y_offset), (0, -y_offset), (x_offset, -y_offset), (-x_offset, 0), 0, (x_offset, 0), (-x_offset, y_offset), (0, y_offset), (x_offset, y_offset), 0] except: pass def close(self): """ Method used to to close the program orderly so no threads are left hanging. """ print(self.__title__) while self.mouse.isTalking: print('Is Talking') self.eye_tracker.video_capture.release() clear_queue(self.q) self.q.put(False) self.q.join() self.t.join() self.destroy()
def __init__(self, master, par=False): """ GUI for selecting default parameters - will write parameters to file \ of users choosing. :type master: Tk :param master: Tkinter window :type par: EQcorrscanParameters :param par: Default parameters to start-up with. """ from tkinter import Label, Button, Entry, DoubleVar, StringVar, IntVar from tkinter import BooleanVar, OptionMenu, Checkbutton import tkMessageBox from eqcorrscan.utils import parameters from obspy import UTCDateTime import warnings # Set the default par, only if they don't already exist. if not par: par = parameters.EQcorrscanParameters([''], 2, 10, 4, 100, 2, '1900-01-01', '2300-01-01', '', 'seishub', 4, False, '', 'jpg', False, 8, 'MAD', 6) # Callback functions for all variables (ugly) def update_template_names(*args): par.template_names = [ name.strip() for name in template_names.get().split(',') ] template_names.set(', '.join(par.template_names)) def update_lowcut(*args): par.lowcut = lowcut.get() lowcut.set(par.lowcut) def update_highcut(*args): par.highcut = highcut.get() if par.highcut >= 0.5 * par.samp_rate: msg = ('Highcut must be less than the Nyquist, setting to ' + str((par.samp_rate / 2.0) - 1)) tkMessageBox.showwarning(title="Nyquist error", message=msg) par.highcut = (par.samp_rate / 2.0) - 1 highcut.set(par.highcut) def update_filt_order(*args): par.filt_order = filt_order.get() filt_order.set(par.filt_order) def update_samp_rate(*args): par.samp_rate = samp_rate.get() if par.highcut >= 0.5 * par.samp_rate: msg = ('Highcut must be less than the Nyquist, setting to ' + str((par.samp_rate / 2.0) - 1)) tkMessageBox.showwarning(title="Nyquist error", message=msg) par.highcut = (par.samp_rate / 2.0) - 1 highcut.set(par.highcut) samp_rate.set(par.samp_rate) def update_debug(*args): par.debug = debug.get() debug.set(par.debug) def update_startdate(*args): par.startdate = UTCDateTime(startdate.get()) startdate.set(str(par.startdate)) def update_enddate(*args): par.enddate = UTCDateTime(enddate.get()) enddate.set(str(par.enddate)) def update_archive(*args): par.archive = archive.get() archive.set(par.archive) def update_arc_type(*args): par.arc_type = arc_type.get() arc_type.set(par.arc_type) def update_cores(*args): par.cores = cores.get() cores.set(par.cores) def update_plotvar(*args): par.plotvar = plotvar.get() plotvar.set(par.plotvar) def update_plot_format(*args): par.plot_format = plot_format.get() plot_format.set(par.plot_format) def update_tempdir(*args): par.tempdir = tempdir.get() tempdir.set(par.tempdir) def update_threshold(*args): par.threshold = threshold.get() threshold.set(par.threshold) def update_threshold_type(*args): par.threshold_type = threshold_type.get() threshold_type.set(par.threshold_type) def update_plotdir(*args): par.plotdir = plotdir.get() plotdir.set(par.plotdir) def update_trigger_interval(*args): par.trigger_interval = trigger_interval.get() trigger_interval.set(par.trigger_interval) # Set some grid parameters nrows = 25 ncolumns = 3 self.master = master master.title("EQcorrscan parameter setup") self.label = Label(master, text="Alpha GUI for default setup") self.label.grid(column=0, columnspan=ncolumns, row=0) # Set up parameter input self.t_names_label = Label(master, text="Template names", anchor='e') self.t_names_label.grid(column=0, row=1, sticky='e') template_names = StringVar() template_names.set(', '.join(par.template_names)) self.t_names_box = Entry(master, bd=2, textvariable=template_names) self.t_names_box.grid(column=1, row=1) template_names.trace("w", update_template_names) self.t_names_lookup = Button( master, text="Lookup", command=lambda: self.get_template_names(par)) self.t_names_lookup.grid(column=2, row=1) self.lowcut_label = Label(master, text="Lowcut (Hz)", anchor='e') self.lowcut_label.grid(column=0, row=2, sticky='e') lowcut = DoubleVar() lowcut.set(par.lowcut) self.lowcut_box = Entry(master, bd=2, textvariable=lowcut) self.lowcut_box.grid(column=1, row=2) lowcut.trace("w", update_lowcut) self.highcut_label = Label(master, text="Highcut (Hz)", anchor='e') self.highcut_label.grid(column=0, row=3, sticky='e') highcut = DoubleVar() highcut.set(par.highcut) self.highcut_box = Entry(master, bd=2, textvariable=highcut) self.highcut_box.grid(column=1, row=3) highcut.trace("w", update_highcut) self.filt_order_label = Label(master, text="Filter order") self.filt_order_label.grid(column=0, row=4, sticky='e') filt_order = DoubleVar() filt_order.set(par.filt_order) self.filt_order_box = Entry(master, bd=2, textvariable=filt_order) self.filt_order_box.grid(column=1, row=4) filt_order.trace("w", update_filt_order) self.samp_rate_label = Label(master, text="Sample rate (Hz)") self.samp_rate_label.grid(column=0, row=5, sticky='e') samp_rate = DoubleVar() samp_rate.set(par.samp_rate) self.samp_rate_box = Entry(master, bd=2, textvariable=samp_rate) self.samp_rate_box.grid(column=1, row=5) samp_rate.trace("w", update_samp_rate) self.debug_label = Label(master, text="Debug") self.debug_label.grid(column=0, row=6, sticky='e') debug = IntVar() debug.set(par.debug) self.debug_box = Entry(master, bd=2, textvariable=debug) self.debug_box.grid(column=1, row=6) debug.trace("w", update_debug) self.startdate_label = Label(master, text="Start date (yyyy-mm-dd)") self.startdate_label.grid(column=0, row=6, sticky='e') startdate = StringVar() startdate.set(par.startdate) self.startdate_box = Entry(master, bd=2, textvariable=startdate) self.startdate_box.grid(column=1, row=6) startdate.trace("w", update_startdate) self.enddate_label = Label(master, text="End date (yyyy-mm-dd)") self.enddate_label.grid(column=0, row=8, sticky='e') enddate = StringVar() enddate.set(par.enddate) self.enddate_box = Entry(master, bd=2, textvariable=enddate) self.enddate_box.grid(column=1, row=8) enddate.trace("w", update_enddate) self.archive_label = Label(master, text="Archive") self.archive_label.grid(column=0, row=9, sticky='e') archive = StringVar() archive.set(par.archive) self.archive_box = Entry(master, bd=2, textvariable=archive) self.archive_box.grid(column=1, row=9) archive.trace("w", update_archive) self.archive_lookup = Button(master, text="Lookup", command=lambda: self.get_archive(par)) self.archive_lookup.grid(column=2, row=9) self.arc_type_label = Label(master, text="Archive type") self.arc_type_label.grid(column=0, row=10, sticky='e') arc_type = StringVar() arc_type.set(par.arc_type) self.arc_type_box = OptionMenu(master, arc_type, "seishub", "fdsn", "day_vols") self.arc_type_box.grid(column=1, row=10, sticky='w,e') arc_type.trace("w", update_arc_type) self.cores_label = Label(master, text="Number of cores") self.cores_label.grid(column=0, row=11, sticky='e') cores = IntVar() cores.set(par.cores) self.cores_box = Entry(master, bd=2, textvariable=cores) self.cores_box.grid(column=1, row=11) cores.trace("w", update_cores) self.plotvar_label = Label(master, text="Plotting on/off") self.plotvar_label.grid(column=0, row=12, sticky='e') plotvar = BooleanVar() plotvar.set(par.plotvar) self.plotvar_box = Checkbutton(master, text='Plot on', var=plotvar, onvalue=True, offvalue=False) self.plotvar_box.grid(column=1, row=12) plotvar.trace("w", update_plotvar) self.plotdir_label = Label(master, text="Plot directory") self.plotdir_label.grid(column=0, row=13, sticky='e') plotdir = StringVar() plotdir.set(par.plotdir) self.plotdir_box = Entry(master, bd=2, textvariable=plotdir) self.plotdir_box.grid(column=1, row=13) plotdir.trace("w", update_plotdir) self.plotdir_lookup = Button(master, text="Lookup", command=lambda: self.get_plotdir(par)) self.plotdir_lookup.grid(column=2, row=13) self.plot_format_label = Label(master, text="Plot format") self.plot_format_label.grid(column=0, row=14, sticky='e') plot_format = StringVar() plot_format.set(par.plot_format) self.plot_format_box = OptionMenu(master, plot_format, "jpg", "eps", "pdf", "png") self.plot_format_box.grid(column=1, row=14, sticky='w,e') plot_format.trace("w", update_plot_format) self.tempdir_label = Label(master, text="Temporary directory") self.tempdir_label.grid(column=0, row=15, sticky='e') tempdir = StringVar() tempdir.set(par.tempdir) self.tempdir_box = Entry(master, bd=2, textvariable=tempdir) self.tempdir_box.grid(column=1, row=15) tempdir.trace("w", update_tempdir) self.tempdir_lookup = Button(master, text="Lookup", command=lambda: self.get_tempdir(par)) self.tempdir_lookup.grid(column=2, row=15) self.threshold_label = Label(master, text="Threshold") self.threshold_label.grid(column=0, row=16, sticky='e') threshold = DoubleVar() threshold.set(par.threshold) self.threshold_box = Entry(master, bd=2, textvariable=threshold) self.threshold_box.grid(column=1, row=16) threshold.trace("w", update_threshold) self.threshold_type_label = Label(master, text="Threshold type") self.threshold_type_label.grid(column=0, row=17, sticky='e') threshold_type = StringVar() threshold_type.set(par.threshold_type) self.threshold_type_box = OptionMenu(master, threshold_type, "MAD", "absolute", "av_chan_corr") self.threshold_type_box.grid(column=1, row=17, sticky='w,e') threshold_type.trace("w", update_threshold_type) self.trigger_interval_label = Label(master, text="Minimum trigger " + "interval (s)") self.trigger_interval_label.grid(column=0, row=18, sticky='e') trigger_interval = DoubleVar() trigger_interval.set(par.trigger_interval) self.trigger_interval_box = Entry(master, bd=2, textvariable=trigger_interval) self.trigger_interval_box.grid(column=1, row=18) trigger_interval.trace("w", update_trigger_interval) # End of user editable section, now we have read/write buttons self.read_button = Button(master, text="Read parameters", command=lambda: self.read_par(master)) self.read_button.grid(column=0, row=nrows - 2, sticky='w,e') self.write_button = Button(master, text="Write parameters", command=lambda: self.write_par(par)) self.write_button.grid(column=1, row=nrows - 2, sticky='w,e')
class GraphyInspector: def __init__(self, parent): self.parent = parent self.width = self.parent.right_frame_width self.padding = self.parent.right_frame_padding self.frame = Frame(master=self.parent.right_frame) self.frame.pack(side='top', fill='y', ) # "Inspector" title bar self.title_frame = Frame(master=self.frame) self.title_frame.pack(side='top') self.title_label = Label(master=self.title_frame, text="Inspector", width=self.width, bg='lightgray') self.title_label.pack() # identifier for type of object selected self.type_frame = Frame(master=self.frame, relief='sunken') self.type_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.type_label1 = Label(master=self.type_frame, width=int(self.width/2)-self.padding, text='Object:') self.type_label1.pack(side='left', padx=self.padding, pady=self.padding) self.type_label2 = Label(master=self.type_frame, width=int(self.width / 2) - self.padding, text='', bg='white') self.type_label2.pack(side='right', padx=self.padding, pady=self.padding) # label of selected object (i.e. name user gives them, no canvas IDs here) self.label_frame = Frame(master=self.frame, relief='sunken') self.label_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.label_label = Label(master=self.label_frame, width=int(self.width/2)-self.padding, text="Label:") self.label_label.pack(side='left', padx=self.padding, pady=self.padding) self.label_var = StringVar() self.label_var.set('') self.label_entry = Entry(self.label_frame, width=int(self.width/2)-self.padding, textvariable=self.label_var) self.label_entry.pack(side='right', padx=self.padding, pady=self.padding) self.label_entry.bind('<Button-1>', self.select_label_text) self.label_entry.bind('<Return>', self.drop_widget_focus) # status identifier (for vertices and layers) self.status_frame = Frame(master=self.frame, relief='sunken') self.status_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.status_label1 = Label(master=self.status_frame, width=int(self.width/2)-self.padding, text='Status:') self.status_label1.pack(side='left', padx=self.padding, pady=self.padding) self.status_label2 = Label(master=self.status_frame, width=int(self.width/2)-self.padding, text='', bg='white') self.status_label2.pack(side='right', padx=self.padding, pady=self.padding) self.activation_var = StringVar() self.activation_var.set('') self.activation_menu = OptionMenu(self.status_frame, self.activation_var, "Identity", "Sigmoid", "ReLU", "Logarithmic", "Exponential") self.activation_menu.pack(side='right', padx=self.padding, pady=self.padding) # weight identifier (for edges only) self.weight_frame = Frame(master=self.frame, relief='sunken') self.weight_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.weight_label = Label(master=self.weight_frame, width=int(self.width/2)-self.padding, text="Weight:") self.weight_label.pack(side='left', padx=self.padding, pady=self.padding) self.weight_var = DoubleVar() self.weight_entry = Entry(self.weight_frame, width=int(self.width / 2) - self.padding, textvariable=self.weight_var) self.weight_entry.pack(side='right', padx=self.padding, pady=self.padding) self.weight_entry.bind('<Button-1>', self.select_weight_text) self.weight_entry.bind('<Return>', self.drop_widget_focus) # node count identifier (for layers only) self.node_frame = Frame(master=self.frame, relief='sunken') self.node_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.node_label = Label(master=self.node_frame, width=int(self.width/2)-self.padding, text="Node Count:") self.node_label.pack(side='left', padx=self.padding, pady=self.padding) self.node_var = IntVar() self.node_entry = Entry(self.node_frame, width=int(self.width / 2) - self.padding, textvariable=self.node_var) self.node_entry.pack(side='right', padx=self.padding, pady=self.padding) self.node_entry.bind('<Button-1>', self.select_node_text) self.node_entry.bind('<Return>', self.drop_widget_focus) # leakiness self.leakiness_frame = Frame(master=self.frame, relief='sunken') self.leakiness_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.leakiness_label = Label(master=self.leakiness_frame, width=int(self.width/2)-self.padding, text="Leakiness") self.leakiness_label.pack(side='left', padx=self.padding, pady=self.padding) self.leakiness_var = DoubleVar() self.leakiness_entry = Entry(self.leakiness_frame, width=int(self.width / 2) - self.padding, textvariable=self.leakiness_var) self.leakiness_entry.pack(side='right', padx=self.padding, pady=self.padding) self.leakiness_entry.bind('<Button-1>', self.select_leakiness_text) self.leakiness_entry.bind('<Return>', self.drop_widget_focus) # bias self.bias_frame = Frame(master=self.frame, relief='sunken') self.bias_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.bias_label = Label(master=self.bias_frame, width=int(self.width/2)-self.padding, text="Bias:") self.bias_label.pack(side='left', padx=self.padding, pady=self.padding) self.bias_var = DoubleVar() self.bias_entry = Entry(self.bias_frame, width=int(self.width / 2) - self.padding, textvariable=self.bias_var) self.bias_entry.pack(side='right', padx=self.padding, pady=self.padding) self.bias_entry.bind('<Button-1>', self.select_bias_text) self.bias_entry.bind('<Return>', self.drop_widget_focus) # output bound self.bound_frame = Frame(master=self.frame, relief='sunken') self.bound_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.bound_label = Label(master=self.bound_frame, width=int(self.width/2)-self.padding, text="Output Bound:") self.bound_label.pack(side='left', padx=self.padding, pady=self.padding) self.bound_var = DoubleVar() self.bound_entry = Entry(self.bound_frame, width=int(self.width / 2) - self.padding, textvariable=self.bound_var) self.bound_entry.pack(side='right', padx=self.padding, pady=self.padding) self.bound_entry.bind('<Button-1>', self.select_bound_text) self.bound_entry.bind('<Return>', self.drop_widget_focus) # noise self.noise_frame = Frame(master=self.frame, relief='sunken') self.noise_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.noise_label = Label(master=self.noise_frame, width=int(self.width/2)-self.padding, text="Weight Noise:") self.noise_label.pack(side='left', padx=self.padding, pady=self.padding) self.noise_var = DoubleVar() self.noise_entry = Entry(self.noise_frame, width=int(self.width / 2) - self.padding, textvariable=self.noise_var) self.noise_entry.pack(side='right', padx=self.padding, pady=self.padding) self.noise_entry.bind('<Button-1>', self.select_noise_text) self.noise_entry.bind('<Return>', self.drop_widget_focus) # input / output self.input_output_frame = Frame(master=self.frame, relief='sunken') self.input_output_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.input_var = BooleanVar() self.input_var.set(False) self.output_var = BooleanVar() self.output_var.set(False) self.input_toggle = Checkbutton(master=self.input_output_frame, text="Is Input", variable=self.input_var) self.output_toggle = Checkbutton(master=self.input_output_frame, text="Is Output", variable=self.output_var) self.input_toggle.pack(side='left', padx=self.padding, pady=self.padding) self.output_toggle.pack(side='left', padx=self.padding, pady=self.padding) self.selected = None self.selected_type = None self.set_unselected() self.label_var.trace('w', self.set_selected_label) self.weight_var.trace('w', self.set_selected_weight) self.activation_var.trace('w', self.set_selected_activation) self.leakiness_var.trace('w', self.set_selected_leakiness) self.node_var.trace('w', self.set_selected_node_count) self.bias_var.trace('w', self.set_selected_bias) self.bound_var.trace('w', self.set_selected_bound) self.noise_var.trace('w', self.set_selected_noise) self.input_var.trace('w', self.set_input) self.output_var.trace('w', self.set_output) # mode self.mode = parent.mode self.set_mode(parent.mode) # object is a vertex or edge, type is 'vertex' or 'edge'... def set_selected(self, selected_object, selected_object_type): self.selected = selected_object self.selected_type = selected_object_type if self.mode == "Graph": if selected_object_type == 'vertex': self.type_label2.config(text="Vertex") self.status_label2.config(text=selected_object.status) self.type_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.label_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.status_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.label_var.set(selected_object.label) elif selected_object_type == 'edge': self.type_label2.config(text="Edge") self.type_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.label_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.weight_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.label_var.set(selected_object.label) self.weight_var.set(selected_object.weight) else: print('dafuq is going on') elif self.mode == "Net": if selected_object_type == 'vertex': self.type_label2.config(text="Layer") self.status_label2.config(text=selected_object.status) self.type_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.label_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.status_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.node_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.leakiness_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.bias_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.bound_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.input_output_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.label_var.set(selected_object.label) self.node_var.set(selected_object.node_count) self.activation_var.set(selected_object.status) self.leakiness_var.set(selected_object.leakiness) self.bias_var.set(selected_object.bias) self.bound_var.set(selected_object.bound) self.input_var.set(selected_object.is_input_layer) self.output_var.set(selected_object.is_output_layer) elif selected_object_type == 'edge': self.type_label2.config(text="Weights") self.type_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.label_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.weight_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.noise_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding) self.label_var.set(selected_object.label) self.weight_var.set(selected_object.weight) self.noise_var.set(selected_object.noise) else: print('This will never happen.') # nothing is selected def set_unselected(self): self.type_frame.pack_forget() self.label_frame.pack_forget() self.status_frame.pack_forget() self.weight_frame.pack_forget() self.node_frame.pack_forget() self.bias_frame.pack_forget() self.bound_frame.pack_forget() self.noise_frame.pack_forget() self.input_output_frame.pack_forget() self.leakiness_frame.pack_forget() self.selected = None self.selected_type = None # set label of selected object def set_selected_label(self, *args): self.selected.set_label(self.label_var.get()) # set weight of selected object def set_selected_weight(self, *args): self.selected.set_weight(self.weight_var.get()) def set_selected_activation(self, *args): self.selected.set_status(self.activation_var.get()) def set_selected_node_count(self, *args): self.selected.set_node_count(self.node_var.get()) def set_selected_bias(self, *args): self.selected.set_bias(self.bias_var.get()) def set_selected_bound(self, *args): self.selected.set_bound(self.bound_var.get()) def set_selected_noise(self, *args): self.selected.set_noise(self.noise_var.get()) def set_input(self, *args): self.selected.set_input_layer(self.input_var.get()) def set_output(self, *args): self.selected.set_output_layer(self.output_var.get()) def set_selected_leakiness(self, *args): self.selected.set_leakiness(self.leakiness_var.get()) def update(self): if self.selected: selected = self.selected type = self.selected_type self.set_unselected() self.set_selected(selected, type) def select_label_text(self, event): if event: # delay so the default click doesn't undo selection, then recall and fall through to "else" self.parent.tk.after(50, self.select_label_text, False) else: self.label_entry.select_range(0, 'end') self.label_entry.icursor(0) def select_weight_text(self, event): if event: # delay so the default click doesn't undo selection, then recall and fall through to "else" self.parent.tk.after(50, self.select_weight_text, False) else: self.weight_entry.select_range(0, 'end') self.weight_entry.icursor(0) def select_node_text(self, event): if event: self.parent.tk.after(50, self.select_node_text, False) else: self.node_entry.select_range(0, 'end') self.node_entry.icursor(0) def select_bias_text(self, event): if event: self.parent.tk.after(50, self.select_bias_text, False) else: self.bias_entry.select_range(0, 'end') self.bias_entry.icursor(0) def select_noise_text(self, event): if event: self.parent.tk.after(50, self.select_noise_text, False) else: self.noise_entry.select_range(0, 'end') self.noise_entry.icursor(0) def select_bound_text(self, event): if event: self.parent.tk.after(50, self.select_bound_text, False) else: self.bound_entry.select_range(0, 'end') self.bound_entry.icursor(0) def select_leakiness_text(self, event): if event: self.parent.tk.after(50, self.select_leakiness_text, False) else: self.leakiness_entry.select_range(0, 'end') self.leakiness_entry.icursor(0) def drop_widget_focus(self, event): self.frame.focus() def set_mode(self, mode): if mode == "Graph": self.mode = mode self.weight_label.config(text="Weight:") self.status_label1.config(text="Status:") self.activation_menu.pack_forget() self.input_output_frame.pack_forget() self.status_label2.pack(side='right', padx=self.padding, pady=self.padding) elif mode == "Net": self.mode = mode self.weight_label.config(text="Start Weight:") self.status_label1.config(text="Activation:") self.status_label2.pack_forget() self.activation_menu.pack(side='right', padx=self.padding, pady=self.padding) else: print("This will never happen.")
class SettingsFrame(Frame): """ Frame inheritance class for application settings and controls. """ def __init__(self, app, *args, **kwargs): """ Constructor """ self.__app = app # Reference to main application class self.__master = self.__app.get_master() # Reference to root class (Tk) Frame.__init__(self, self.__master, *args, **kwargs) # Initialise up key variables self._image_num = 0 self._image_name = "image" self._settype = StringVar() self._zoom = DoubleVar() self._radius = DoubleVar() self._exponent = IntVar() self._zx_off = DoubleVar() self._zy_off = DoubleVar() self._cx_off = DoubleVar() self._cy_off = DoubleVar() self._maxiter = IntVar() self._zx_coord = DoubleVar() self._zy_coord = DoubleVar() self._theme = StringVar() self._shift = IntVar() self._themes = None self._filename = StringVar() self._filepath = None self._frames = IntVar() self._zoominc = DoubleVar() self._autoiter = IntVar() self._autosave = IntVar() self._validsettings = True self.body() def body(self): """ Set up frame and widgets. """ # Create settings panel widgets # pylint: disable=W0108 self.lbl_settype = Label(self, text=LBLMODE) self.spn_settype = Spinbox( self, values=("BurningShip", "Tricorn", "Julia", "Mandelbrot"), width=8, bg=GOOD, wrap=True, textvariable=self._settype, ) self.lbl_zoom = Label(self, text=LBLZOOM) self.ent_zoom = Entry( self, border=2, relief="sunken", width=12, bg=GOOD, justify=RIGHT, textvariable=self._zoom, ) self.lbl_zoominc = Label(self, text=LBLZOOMINC, justify=LEFT) self.ent_zoominc = Entry(self, width=5, border=2, bg=GOOD, justify=RIGHT, textvariable=self._zoominc) self.lbl_zx_off = Label(self, text=LBLZXOFF) self.ent_zx_off = Entry( self, border=2, relief="sunken", width=12, bg=GOOD, justify=RIGHT, textvariable=self._zx_off, ) self.lbl_zy_off = Label(self, text=LBLZYOFF) self.ent_zy_off = Entry( self, border=2, relief="sunken", width=12, bg=GOOD, justify=RIGHT, textvariable=self._zy_off, ) self.lbl_cx_off = Label(self, text=LBLCX) self.ent_cx_off = Entry( self, border=2, relief="sunken", width=12, bg=GOOD, justify=RIGHT, textvariable=self._cx_off, state=DISABLED, ) self.lbl_cy_off = Label(self, text=LBLCY) self.ent_cy_off = Entry( self, border=2, relief="sunken", width=12, bg=GOOD, justify=RIGHT, textvariable=self._cy_off, state=DISABLED, ) self.lbl_niter = Label(self, text=LBLITER, justify=LEFT) self.ent_maxiter = Entry( self, border=2, relief="sunken", bg=GOOD, width=8, justify=RIGHT, textvariable=self._maxiter, ) self.chk_autoiter = Checkbutton(self, text="Auto", variable=self._autoiter, onvalue=1, offvalue=0) self.lbl_theme = Label(self, text=LBLTHEME, justify=LEFT) self.lbl_radius = Label(self, text=LBLRAD, justify=LEFT) self.ent_radius = Entry( self, border=2, relief="sunken", bg=GOOD, width=8, justify=RIGHT, textvariable=self._radius, ) self.lbl_exp = Label(self, text=LBLEXP) self.spn_exp = Spinbox( self, border=2, relief="sunken", bg=GOOD, width=4, from_=2, to=20, wrap=True, textvariable=self._exponent, ) self.sep_1 = ttk.Separator( self, orient=HORIZONTAL, ) self.lbx_theme = Listbox( self, border=2, relief="sunken", bg=GOOD, width=6, height=5, justify=LEFT, exportselection=False, ) self.lbl_shift = Label(self, text=LBLSHIFT, justify=LEFT) self.scl_shift = Scale( self, from_=0, to=100, orient=HORIZONTAL, variable=self._shift, border=2, relief="sunken", sliderlength=20, troughcolor=GOOD, ) self.scrollbar = Scrollbar(self, orient=VERTICAL) self.lbx_theme.config(yscrollcommand=self.scrollbar.set) self.scrollbar.config(command=self.lbx_theme.yview) self.lbx_theme.select_set(0) self.lbx_theme.event_generate("<<ListboxSelect>>") self.lbl_coords = Label(self, text="Re, Im", fg="grey") self.btn_plot = Button( self, text=BTNPLOT, width=8, fg="green", command=lambda: self.__app.frm_fractal.plot(), ) self.btn_cancel = Button( self, text=BTNCAN, width=8, command=lambda: self.__app.frm_fractal.cancel_press(), ) self.btn_reset = Button(self, text=BTNRST, width=8, command=self.reset) self.ent_save = Entry( self, textvariable=self._filename, width=6, border=2, relief="sunken", bg=GOOD, justify=LEFT, ) self._filename.set(self._image_name + str(self._image_num)) self.btn_save = Button(self, text=BTNSAVE, width=8, command=self.save_image) self.lbl_auto = Label(self, text=LBLAUTO, justify=LEFT) self.btn_autozoom = Button( self, text=BTNZOOM, width=8, command=lambda: self.__app.frm_fractal.animate_zoom(), ) self.btn_autospin = Button( self, text=BTNSPIN, width=8, command=lambda: self.__app.frm_fractal.animate_spin(), state=DISABLED, ) self.chk_autosave = Checkbutton(self, text=BTNSAVE, variable=self._autosave, onvalue=1, offvalue=0) self.lbl_frames = Label(self, text=FRMSTXT) self.ent_frames = Entry(self, width=5, border=2, bg=GOOD, justify=RIGHT, textvariable=self._frames) # Get list of available themes for idx, theme in enumerate(THEMES): self.lbx_theme.insert(idx, theme) self.body_arrange() # Position all widgets in frame self.reset() # Reset all settings to their defaults self.set_traces( ) # Trace entry variables for validation and event handling def body_arrange(self): """ Position widgets in frame """ # Position all widgets in their parent frames self.btn_plot.grid(column=0, row=1, ipadx=3, ipady=3, sticky=(W), padx=3, pady=3) self.btn_cancel.grid(column=1, row=1, ipadx=3, ipady=3, sticky=(W), padx=3, pady=3) self.btn_reset.grid(column=2, row=1, ipadx=3, ipady=3, sticky=(W), padx=3, pady=3) self.ent_save.grid(column=0, row=2, columnspan=2, sticky=(W, E), padx=3, pady=3) self.btn_save.grid(column=2, row=2, ipadx=3, ipady=3, sticky=(W), padx=3, pady=3) self.lbl_auto.grid(column=0, row=3, sticky=(W)) self.btn_autozoom.grid(column=1, row=3, ipadx=3, ipady=3, sticky=(W), padx=3, pady=3) self.btn_autospin.grid(column=2, row=3, ipadx=3, ipady=3, sticky=(W), padx=3, pady=3) self.lbl_frames.grid(column=0, row=4, sticky=(W)) self.ent_frames.grid(column=1, row=4, sticky=(W), padx=3, pady=3) self.chk_autosave.grid(column=2, row=4, sticky=(W), padx=3, pady=3) self.sep_1.grid(column=0, row=5, columnspan=3, pady=5, sticky=(W, E)) self.lbl_settype.grid(column=0, row=6, sticky=(W)) self.spn_settype.grid(column=1, row=6, columnspan=2, sticky=(W, E), padx=3, pady=3) self.lbl_zoom.grid(column=0, row=7, sticky=(W)) self.ent_zoom.grid(column=1, row=7, columnspan=2, sticky=(W, E), padx=3, pady=3) self.lbl_zoominc.grid(column=0, row=8, sticky=(W)) self.ent_zoominc.grid(column=1, row=8, sticky=(W), padx=3, pady=3) self.lbl_zx_off.grid(column=0, row=9, sticky=(W)) self.ent_zx_off.grid(column=1, row=9, columnspan=2, sticky=(W, E), padx=3, pady=3) self.lbl_zy_off.grid(column=0, row=10, sticky=(W)) self.ent_zy_off.grid(column=1, row=10, columnspan=2, sticky=(W, E), padx=3, pady=3) self.lbl_cx_off.grid(column=0, row=11, sticky=(W)) self.ent_cx_off.grid(column=1, row=11, columnspan=2, sticky=(W, E), padx=3, pady=3) self.lbl_cy_off.grid(column=0, row=12, sticky=(W)) self.ent_cy_off.grid(column=1, row=12, columnspan=2, sticky=(W, E), padx=3, pady=3) self.lbl_niter.grid(column=0, row=13, sticky=(W)) self.ent_maxiter.grid(column=1, row=13, sticky=(W), padx=3, pady=3) self.chk_autoiter.grid(column=2, row=13, sticky=(W), padx=3, pady=3) self.lbl_radius.grid(column=0, row=14, sticky=(W)) self.ent_radius.grid(column=1, row=14, sticky=(W), padx=3, pady=3) self.lbl_exp.grid(column=0, row=15, sticky=(W)) self.spn_exp.grid(column=1, row=15, sticky=(W), padx=3, pady=3) self.lbl_theme.grid(column=0, row=16, sticky=(W)) self.lbx_theme.grid(column=1, row=16, padx=3, pady=3, columnspan=2, sticky=(N, S, W, E)) self.scrollbar.grid(column=2, row=16, sticky=(N, S, E)) self.lbl_shift.grid(column=0, row=17, sticky=(W)) self.scl_shift.grid(column=1, row=17, columnspan=2, padx=3, pady=3, sticky=(W, E)) self.lbx_theme.bind("<<ListboxSelect>>", self.get_sel_theme) def set_traces(self): """ Set up entry variable traces for validation and event handling """ self._validsettings = True self._settype.trace("w", self.val_settings) self._zoom.trace("w", self.val_settings) self._zx_off.trace("w", self.val_settings) self._zy_off.trace("w", self.val_settings) self._cx_off.trace("w", self.val_settings) self._cy_off.trace("w", self.val_settings) self._maxiter.trace("w", self.val_settings) self._radius.trace("w", self.val_settings) self._exponent.trace("w", self.val_settings) self._filename.trace("w", self.val_settings) self._frames.trace("w", self.val_settings) self._zoominc.trace("w", self.val_settings) def val_settings(self, *args, **kwargs): """ Validate all user-entered settings. (A personal choice but I find this user experience more intuitive than the standard validatecommand method for Entry widgets) """ self._validsettings = True self.__app.set_status("") if self.is_float(self.ent_zoom.get()) and self._zoom.get() > 0: flg = GOOD else: flg = BAD self.flag_entry(self.ent_zoom, flg) if self.is_float(self.ent_zx_off.get()): flg = GOOD else: flg = BAD self.flag_entry(self.ent_zx_off, flg) if self.is_float(self.ent_zy_off.get()): flg = GOOD else: flg = BAD self.flag_entry(self.ent_zy_off, flg) if self.is_float(self.ent_cx_off.get()): flg = GOOD else: flg = BAD self.flag_entry(self.ent_cx_off, flg) if self.is_float(self.ent_cy_off.get()): flg = GOOD else: flg = BAD self.flag_entry(self.ent_cy_off, flg) if self.is_integer(self.ent_maxiter.get()) and self._maxiter.get() > 0: flg = GOOD else: flg = BAD self.flag_entry(self.ent_maxiter, flg) if self.is_float(self.ent_radius.get()) and self._radius.get() > 0: flg = GOOD else: flg = BAD self.flag_entry(self.ent_radius, flg) if self.is_integer(self.spn_exp.get()) and self._exponent.get() > 1: flg = GOOD else: flg = BAD self.flag_entry(self.spn_exp, flg) if self.is_integer(self.ent_frames.get()) and self._frames.get() > 0: flg = GOOD else: flg = BAD self.flag_entry(self.ent_frames, flg) if self.is_float(self.ent_zoominc.get()) and self._zoominc.get() > 0: flg = GOOD else: flg = BAD self.flag_entry(self.ent_zoominc, flg) if self.is_filename(self.ent_save.get()): flg = GOOD else: flg = BAD self.flag_entry(self.ent_save, flg) if self.spn_settype.get() in {"Mandelbrot", "Tricorn", "BurningShip"}: self.btn_autospin.config(state=DISABLED) self.ent_cx_off.config(state=DISABLED) self.ent_cy_off.config(state=DISABLED) self._cx_off.set(0) self._cy_off.set(0) flg = GOOD elif self.spn_settype.get() == "Julia": self.btn_autospin.config(state=NORMAL) self.ent_cx_off.config(state=NORMAL) self.ent_cy_off.config(state=NORMAL) flg = GOOD else: flg = BAD self.flag_entry(self.spn_settype, flg) def flag_entry(self, ent, flag): """ Flag entry field as valid or invalid and set global validity status flag. This flag is used throughout to determine whether functions can proceed or not. """ ent.config(bg=flag) if flag == BAD: self._validsettings = False self.__app.set_status(VALERROR, "red") def is_float(self, flag): """ Validate if entry is a float. """ try: float(flag) return True except ValueError: return False def is_integer(self, flag): """ Validate if entry is a positive integer. """ try: int(flag) if int(flag) > 0: return True return False except ValueError: return False def is_filename(self, flag): """ Validate if entry represents a valid filename using a regexp. """ return match("^[\w\-. ]+$", flag) and flag != "" def reset(self): """ Reset settings to defaults. """ self._settype.set("Mandelbrot") self._zoom.set(0.75) self._zx_off.set(-0.5) self._zy_off.set(0.0) self._cx_off.set(0.0) self._cy_off.set(0.0) self._maxiter.set(128) self._radius.set(2.0) self._exponent.set(2) self._frames.set(10) self._zoominc.set(2.0) self._autoiter.set(1) self._autosave.set(0) self._theme.set("Default") self._filename.set("image0") self._shift.set(0) self.set_sel_theme() self.__app.set_status(SETINITTXT) def get_sel_theme(self, *args, **kwargs): """ Get selected theme from listbox and set global variable. """ idx = self.lbx_theme.curselection() if idx == "": idx = 0 self._theme.set(self.lbx_theme.get(idx)) def set_sel_theme(self): """ Lookup index of selected theme and highlight that listbox position. NB: this requires 'exportselection=False' option to be set on listbox to work properly. """ for idx, theme in enumerate(THEMES): if theme == self._theme.get(): self.lbx_theme.activate(idx) self.lbx_theme.see(idx) break def get_settings(self): """ Return all current settings as a dict. """ if not self._validsettings: settings = {"valid": self._validsettings} return settings settings = { "settype": self._settype.get(), "zoom": self._zoom.get(), "zxoffset": self._zx_off.get(), "zyoffset": self._zy_off.get(), "cxoffset": self._cx_off.get(), "cyoffset": self._cy_off.get(), "maxiter": self._maxiter.get(), "autoiter": self._autoiter.get(), "autosave": self._autosave.get(), "radius": self._radius.get(), "exponent": self._exponent.get(), "theme": self._theme.get(), "shift": self._shift.get(), "filepath": self._filepath, "filename": self._filename.get(), "frames": self._frames.get(), "zoominc": self._zoominc.get(), "valid": self._validsettings, } return settings def update_settings(self, **kwargs): """ Update settings from keyword parms. """ if "settype" in kwargs: self._settype.set(kwargs["settype"]) if "zoom" in kwargs: self._zoom.set(kwargs["zoom"]) if "zxoffset" in kwargs: self._zx_off.set(kwargs["zxoffset"]) if "zyoffset" in kwargs: self._zy_off.set(kwargs["zyoffset"]) if "cxoffset" in kwargs: self._cx_off.set(kwargs["cxoffset"]) if "cyoffset" in kwargs: self._cy_off.set(kwargs["cyoffset"]) if "maxiter" in kwargs: self._maxiter.set(kwargs["maxiter"]) if "autoiter" in kwargs: self._autoiter.set(kwargs["autoiter"]) if "autosave" in kwargs: self._autosave.set(kwargs["autosave"]) if "radius" in kwargs: self._radius.set(kwargs["radius"]) if "exponent" in kwargs: self._exponent.set(kwargs["exponent"]) if "filepath" in kwargs: self._filepath.set(kwargs["filepath"]) if "filename" in kwargs: self._filename.set(kwargs["filename"]) if "frames" in kwargs: self._frames.set(kwargs["frames"]) if "zoominc" in kwargs: self._zoominc.set(kwargs["zoominc"]) if "theme" in kwargs: self._theme.set(kwargs["theme"]) self.set_sel_theme() if "shift" in kwargs: self._shift.set(kwargs["shift"]) def set_filepath(self): """ Sets filepath for saved files for the duration of this session. """ default = os.getcwd() # Default _filepath is current working directory if self._filepath is None: self._filepath = filedialog.askdirectory(title=SAVETITLE, initialdir=default, mustexist=True) if self._filepath == "": self._filepath = None # User cancelled return self._filepath def save_image(self): """ Save image as PNG file to selected filepath and automatically increment default image name. NB: currently this will overwrite any existing file of the same name without warning. """ # Bug out if the settings are invalid settings = self.__app.frm_settings.get_settings() if not settings["valid"]: return # Check if image has been created image = self.__app.frm_fractal.mandelbrot.get_image() if image is None: self.__app.set_status(NOIMGERROR, "red") return # Set _filename and path if self.set_filepath() is None: # User cancelled return fname = self._filename.get() fqname = self._filepath + "/" + fname # Save the image along with its metadata try: # image.write(fqname + ".png", format="png") image.save(fqname + ".png", format="png") self.save_metadata() except OSError: self.__app.set_status(SAVEERROR, "red") self._filepath = None return self._image_num += 1 self._filename.set(self._image_name + str(self._image_num)) self.__app.set_status(IMGSAVETXT + fqname + ".png", "green") # Return focus to image frame self.__app.frm_fractal.focus_set() def save_metadata(self): """ Save json file containing meta data associated with image, allowing it to be imported and reproduced. """ if self._filepath is None: if self.set_filepath() is None: # User cancelled return fname = self._filename.get() fqname = self._filepath + "/" + fname filename = fqname + ".json" createtime = strftime("%b %d %Y %H:%M:%S %Z", gmtime()) jsondata = { MODULENAME: { "filename": fqname + ".png", "created": createtime, "settype": self._settype.get(), "zoom": self._zoom.get(), "zoominc": self._zoominc.get(), "frames": self._frames.get(), "escradius": self._radius.get(), "exponent": self._exponent.get(), "maxiter": self._maxiter.get(), "zxoffset": self._zx_off.get(), "zyoffset": self._zy_off.get(), "cxoffset": self._cx_off.get(), "cyoffset": self._cy_off.get(), "theme": self._theme.get(), "shift": self._shift.get(), } } try: with open(filename, "w") as outfile: dump(jsondata, outfile) except OSError: self.__app.set_status(METASAVEERROR, "red") self._filepath = None # Return focus to image frame self.__app.frm_fractal.focus_set() def import_metadata(self): """ Update settings from imported json metadata file. """ # Select and read file try: default = os.getcwd() filepath = filedialog.askopenfilename( initialdir=default, title=SELTITLE, filetypes=(("json files", "*.json"), ("all files", "*.*")), ) if filepath == "": # User cancelled return with open(filepath, "r") as infile: jsondata = infile.read() except OSError: self.__app.set_status(OPENFILEERROR, "red") return # Parse file try: settings = loads(jsondata).get(MODULENAME) # Set plot parameters self._settype.set(settings.get("settype", "Mandelbrot")) self._zoom.set(settings.get("zoom", 1)) self._zoominc.set(settings.get("zoominc", 2.0)) self._frames.set(settings.get("frames", 10)) self._radius.set(settings.get("escradius", 2.0)) self._exponent.set(settings.get("exponent", 2)) self._maxiter.set(settings.get("maxiter", 256)) self._zx_off.set(settings.get("zxoffset", 0)) self._zy_off.set(settings.get("zyoffset", 0)) self._cx_off.set(settings.get("cxoffset", 0)) self._cy_off.set(settings.get("cyoffset", 0)) self._theme.set(settings.get("theme", "Default")) self._shift.set(settings.get("shift", 0)) except OSError: self.__app.set_status(BADJSONERROR, "red") return self.set_sel_theme() fbase = os.path.basename(filepath) filename, fileext = os.path.splitext(fbase) self.__app.set_status( "Metadata file " + filename + fileext + METAPROMPTTXT, "green") # Return focus to image frame self.__app.frm_fractal.focus_set()
class Gui(Frame): def __init__(self, control, *args, **kwargs): Frame.__init__(self, *args, **kwargs) self.config(padx=2) self.queue = Queue() self.control = control self.disabledWhileRunning = [] self.formulae = list(map(lambda t: StringVar(self, t), ["x/22.5+4", "50-x*50/180"])) self.executionTime = DoubleVar(self, "360") self.programSpeed = IntVar(self, "292") self.maxTravel = IntVar(self, "-200000") self.loadSettings() self.createWidgets() self.thread = None def compileFormulae(self): rv = [] for f in self.formulae: body = "def formula5480750923(x):\n return " + f.get() l = {} try: exec(body, {}, l) except: rv.append(None) continue compiled = l["formula5480750923"] compiled(0) rv.append(compiled) return rv def plotFormulae(self): try: compiled = self.compileFormulae() except: return for g in self.graphs: g.points = [] self.canvas.x.end = self.executionTime.get() self.canvas.clear() for x in range(self.canvas.x.start, int(self.canvas.x.end)): point = [] for c in range(len(compiled)): v = None if compiled[c]: v = compiled[c](x) assert isinstance(v, float) point.append(v) self.__addPoint__(x, point) self.canvas.update() def __start__(self): self.canvas.x.end = self.executionTime.get() pumps = self.compileFormulae() self.setValues() self.control.mover.setSpeed(abs(int(self.programSpeed.get()))) start_time = float(self.current_time.get()) def calcPumpValues(time): values = list(map(lambda x: x(time), pumps)) self.__addPoint__(time, values) self.current_time.set(time) return values def thFunc(): try: for g in self.graphs: g.points = [] self.control.executeProgram(start_time, calcPumpValues) finally: self.invoke(self.__enableControls__) self.__disableControls__() self.canvas.clear() self.thread = Thread(target=thFunc, name="Control") self.thread.start() def __enableControls__(self): for e in self.disabledWhileRunning: e.config(state=NORMAL) def __disableControls__(self): for e in self.disabledWhileRunning: e.config(state="disabled") def __addPoint__(self, x, values): for v in values: assert isinstance(v, float) def c(): for i in range(len(self.canvas.graphs)): self.canvas.graphs[i].addPoint(x, values[i]) self.invoke(c) def invoke(self, callable): self.after_idle(callable) def __stop__(self): self.control.stop() def __quit__(self): def quitting(): self.__stop__() if self.thread and self.thread.is_alive(): print("Thread is active") return False self.quit() return True run_repeating(self, quitting) def __move__(self, steps): speed = int(self.speed.get()) if speed < 0: speed *= -1 self.speed.set(speed) self.control.mover.setSpeed(speed) self.control.mover.go(steps) def __up__(self): steps = int(self.steps.get()) self.__move__(steps) def __down__(self): steps = int(self.steps.get()) self.__move__(-steps) def showValues(self): self.maxTravel.set(self.control.mover.maxTravel) self.executionTime.set(self.control.fullTime) self.programSpeed.set(self.control.mover.getSpeed()) def setValues(self): self.control.mover.maxTravel = int(self.maxTravel.get()) self.control.fullTime = float(self.executionTime.get()) self.control.mover.setSpeed(abs(int(self.programSpeed.get()))) def loadSettings(self): config = Config() try: config.read() except KeyError: pass config.configureControl(self.control) for i in range(len(self.formulae)): self.formulae[i].set(config.formulae[i]) self.showValues() def saveSettings(self): self.setValues() config = Config() config.getFromControl(self.control) for i in range(len(self.formulae)): config.formulae[i] = self.formulae[i].get() config.write() def createWidgets(self): panel = Frame(self, name="mainMenu") panel.grid(sticky=W) Button(panel, name="quit", text="Выход", command=self.__quit__).grid(row=0, column=0) Button(panel, name="reconnect", text="Пересоединение", command=self.control.reconnect).grid(row=0, column=1) b = Button(panel, text="Загрузить", command=self.loadSettings) b.grid(row=0, column=2) self.disabledWhileRunning.append(b) b = Button(panel, text="Сохранить", command=self.saveSettings) b.grid(row=0, column=3) self.disabledWhileRunning.append(b) panel = LabelFrame(self, text="Прямое управление стаканом", name="motor") panel.grid(sticky=W) b = Button(panel, text="Вверх", command=self.__up__, name="up") b.grid(row=0, column=0) self.disabledWhileRunning.append(b) b = Button(panel, text="Вниз", command=self.__down__, name="down") b.grid(row=1, column=0) self.disabledWhileRunning.append(b) Label(panel, text="Шаг:").grid(sticky=E, row=0, column=1) self.steps = IntVar(self, "10000") Entry(panel, textvariable=self.steps, width=6).grid(sticky=W, row=0, column=2) Label(panel, text="Скорость:").grid(sticky=E, row=1, column=1) self.speed = IntVar(self, "2000") Entry(panel, textvariable=self.speed, width=6).grid(sticky=W, row=1, column=2) self.position = IntVar(self, "1000") def readPosition(): try: self.position.set(self.control.mover.getPosition()) except (ConnectionResetError, Timeout): pass run_repeating(self, readPosition, 10000) b = Button(panel, text="Прочитать положение", command=readPosition) b.grid(row=0, column=3, columnspan=2) self.disabledWhileRunning.append(b) Label(panel, text="Положение:").grid(sticky=E, row=1, column=3) Entry(panel, textvariable=self.position, width=8, state="disabled").grid(sticky=W, row=1, column=4) panel = LabelFrame(self, text="Программа", name="program") program = panel panel.grid(sticky=W + E) panel.columnconfigure(1, weight=1) row = 0 for f in self.formulae: columns, rows = self.grid_size() Label(panel, text="Насос %d:" % (row + 1)).grid(row=row, column=0, sticky=E) e = Entry(panel, textvariable=f) e.grid(sticky=E + W, row=row, column=1) self.disabledWhileRunning.append(e) f.trace("w", lambda *x: self.after_idle(self.plotFormulae)) row += 1 panel = Frame(program, name="mover") panel.grid(columnspan=2, sticky=W) Label(panel, text="Максимальное смещение:").grid(sticky=E) Entry(panel, textvariable=self.maxTravel).grid(sticky=W, row=0, column=1) Label(panel, text="Скорость:").grid(sticky=E) Entry(panel, textvariable=self.programSpeed).grid(sticky=W, row=1, column=1) Label(panel, text="Время выполнения (в секундах):").grid(sticky=E) e = Entry(panel, textvariable=self.executionTime) e.grid(sticky=W, row=2, column=1) self.current_time = DoubleVar(self, "0") Label(panel, text="Текущее время:").grid(sticky=E) e = Entry(panel, textvariable=self.current_time) e.grid(sticky=W, row=3, column=1) self.disabledWhileRunning.append(e) self.executionTime.trace("w", lambda *x: self.plotFormulae()) panel = Frame(program, name="bottom") panel.grid(columnspan=2, sticky=W) row = 0 startButton = Button(panel, name="start", text="Старт", command=self.__start__) startButton.grid(row=row, column=0) self.disabledWhileRunning.append(startButton) Button(panel, text="Стоп", command=self.__stop__).grid(row=row, column=1) self.canvas = GraphCanvas(self) self.graphs = (Graph(self.canvas), Graph(self.canvas)) self.canvas.x.end = 100 self.canvas.y.end = 24 self.plotFormulae() self.canvas.grid(sticky=E + W + S + N) columns, rows = self.grid_size() self.columnconfigure(columns - 1, weight=1) self.rowconfigure(rows - 1, weight=1)
def init_sidebar(self): self.cached_function = eval('lambda x: ' + DEFAULT_EXPRESSION) self.expr = StringVar(self) self.expr.set(DEFAULT_EXPRESSION) self.expr.trace_variable('w', self.var_debounce(self.expression_input)) # Динамические переменные для входных полей start_v = DoubleVar(self, value=self.st) end = DoubleVar(self, value=self.en) epsilon = DoubleVar(self, value=self.eps) divs = IntVar(self, value=self.div) lin_space_var = DoubleVar(self, value=math.log(self.lin_space_size, LOG_BASE)) variables = ((start_v, 'st'), (end, 'en'), (epsilon, 'eps'), (divs, 'div')) # Функция обертка для сигнализирования о смене переменной. def outer(var, var_name): def inner(*_args): try: self.params_input(var.get(), var_name) except Exception: pass return inner for (v, name) in variables: v.trace('w', self.debounce(outer(v, name), 250)) lin_debouncer = self.debounce(self.modify_lin_space_size, 150) lin_space_var.trace( 'w', lambda *_args: self.modify_lin_space_size_callback( lin_space_var.get(), lin_debouncer)) self.frame.columnconfigure(1, weight=2) Label(self.frame, text='Выражение:').grid(column=0, row=0, columnspan=2, sticky='EW') Entry(self.frame, textvariable=self.expr).grid(column=0, row=1, columnspan=2, sticky='EW') self.frame.rowconfigure(2, minsize=25) Label(self.frame, text='Начало').grid(column=0, row=3, sticky='W') Entry(self.frame, textvariable=start_v).grid(column=1, row=3, sticky='EW') Label(self.frame, text='Конец').grid(column=0, row=4, sticky='W') Entry(self.frame, textvariable=end).grid(column=1, row=4, sticky='EW') Label(self.frame, text='Точность').grid(column=0, row=5, sticky='W') Entry(self.frame, textvariable=epsilon).grid(column=1, row=5, sticky='EW') Label(self.frame, text='Разделение').grid(column=0, row=6, sticky='W') Entry(self.frame, textvariable=divs).grid(column=1, row=6, sticky='EW') self.frame.rowconfigure(7, minsize=25) self.lin_space_label = Label( self.frame, text=f'Количество точек графика: {self.lin_space_size}') self.lin_space_label.grid(column=0, row=8, columnspan=2, sticky='W') w = Scale(self.frame, from_=math.log(5, LOG_BASE), to=math.log(MAX_LINE_SPACE_SIZE, LOG_BASE), resolution=0.1 / LOG_BASE, orient=HORIZONTAL, variable=lin_space_var) w.grid(column=0, row=9, columnspan=2, sticky='EW') self.tree = Treeview(self.frame) self.tree['columns'] = (1, 2, 3, 4, 5) self.tree.column('#0', width=35) self.tree.column(1, width=130, anchor='center') self.tree.column(2, width=80, anchor='center') self.tree.column(3, width=80, anchor='center') self.tree.column(4, width=80, anchor='center') self.tree.column(5, width=80, anchor='center') self.tree.heading('#0', text='№') self.tree.heading(1, text='Интервал') self.tree.heading(2, text='Корень') self.tree.heading(3, text='Значение') self.tree.heading(4, text='Итераций') self.tree.heading(5, text='Ошибка') self.tree.grid(column=0, row=10, columnspan=2, sticky='EWSN') self.STEP_MODE = IntVar(self, value=0) self.SHOW_INFLECTION_POINTS = IntVar(self, value=1) self.SHOW_INFLECTION_POINTS.trace( 'w', lambda *_args: self.redraw_main_plot(True)) Checkbutton(self.frame, text='Пошаговый режим', variable=self.STEP_MODE).grid(column=0, row=11, sticky='WS') Checkbutton(self.frame, text='Показывать точка перегиба', variable=self.SHOW_INFLECTION_POINTS)\ .grid(column=0, row=12, sticky='WS')
class SettingsPopup(Frame): def __init__(self, parent, controller): Frame.__init__(self, parent, background="#bbb", bd=1) self.controller = controller self.place(anchor="ne", relx=1, y=50) # self.geometry(str(400) + "x" + str(400)) whiteframe = Frame(self) whiteframe.pack(fill="both", expand=2, padx=1, pady=1) self.closeBtn = ImageTk.PhotoImage( PILImage.open("./close_btn.png").resize((8, 8))) buttonClose = Button(whiteframe, image=self.closeBtn, command=self.closeSettings) buttonClose.pack(anchor="w") # buttonClose.place(anchor="nw") bottomframe1 = Frame(whiteframe) bottomframe1.pack(side=BOTTOM) CameraLabel = Label(bottomframe1, text='Camera Number') CameraLabel.grid(row=1, column=0) self.camNumber = IntVar() entryCam = Entry(bottomframe1, textvariable=self.camNumber) entryCam.grid(row=1, column=1) self.camNumber.set(self.controller.get("camera")) self.camNumber.trace("w", self.setCamera) ComLabel = Label(bottomframe1, text='COM Port') ComLabel.grid(row=2, column=0) self.comNumber = IntVar() entryCom = Entry(bottomframe1, textvariable=self.comNumber) entryCom.grid(row=2, column=1) self.comNumber.set(self.controller.get("comPort")) self.comNumber.trace("w", self.setComPort) labelLat = Label(bottomframe1, text='Latitude (N+)') labelLat.grid(row=3, column=0) self.latVal = DoubleVar() self.latVal.set(self.controller.get("Lat")) self.latVal.trace("w", self.setLat) entryLat = Entry(bottomframe1, textvariable=self.latVal) entryLat.grid(row=3, column=1) labelLon = Label(bottomframe1, text='Longitude (E+)') labelLon.grid(row=4, column=0) self.lonVal = DoubleVar() self.lonVal.set(self.controller.get("Lon")) self.lonVal.trace("w", self.setLon) entryLon = Entry(bottomframe1, textvariable=self.lonVal) entryLon.grid(row=4, column=1) rotationLabel = Label(bottomframe1, text='Rotation') rotationLabel.grid(row=5, column=0) self.rotationAngle = IntVar() self.rotationAngle.set(self.controller.get("rotate")) self.rotationAngle.trace("w", self.setRot) entryRot = Entry(bottomframe1, textvariable=self.rotationAngle) entryRot.grid(row=5, column=1) horFlip = Button(bottomframe1, text='Horizontal Flip', command=self.setHorFlip) horFlip.grid(row=6, column=0) verFlip = Button(bottomframe1, text='Vertical Flip', command=self.setVerFlip) verFlip.grid(row=6, column=1) def getExposureStr(strValue): value = float(strValue) if value > 0: return "{:.3f}".format(pow(2, value)) else: return "1/{:.3f}".format(pow(2, abs(value))) def setExposureValue(strValue): value = float(strValue) self.controller.set("exposure", value) self.labelExposureVal.config(text=getExposureStr(value)) labelExposure = Label(bottomframe1, text="Exposure (s)") labelExposure.grid(row=7, column=0) self.labelExposureVal = Label(bottomframe1, text=getExposureStr( self.controller.get("exposure"))) self.labelExposureVal.grid(row=7, column=1) exposure = Scale(bottomframe1, from_=-15, to=5, resolution=.1, orient="horizontal", showvalue=0, command=setExposureValue) exposure.grid(row=8, column=0, columnspan=2, sticky="nesw") exposure.set(self.controller.get("exposure")) def setGainValue(strValue): value = int(strValue) self.controller.set("gain", value) self.labelGainVal.config(text=str(value)) labelGain = Label(bottomframe1, text="Gain") labelGain.grid(row=9, column=0) self.labelGainVal = Label(bottomframe1, text=str(self.controller.get("gain"))) self.labelGainVal.grid(row=9, column=1) gain = Scale(bottomframe1, from_=0, to=300, orient="horizontal", showvalue=0, command=setGainValue) gain.grid(row=10, column=0, columnspan=2, sticky="nesw") gain.set(self.controller.get("gain")) def setRefreshRate(strValue): value = int(strValue) self.controller.set("refreshRate", value) self.labelRefreshRateVal.config(text=str(value)) labelRefresh = Label(bottomframe1, text="Refresh Rate (FPS)") labelRefresh.grid(row=11, column=0) self.labelRefreshRateVal = Label( bottomframe1, text=str(self.controller.get("refreshRate"))) self.labelRefreshRateVal.grid(row=11, column=1) refreshRate = Scale(bottomframe1, from_=1, to=60, orient="horizontal", showvalue=0, command=setRefreshRate) refreshRate.grid(row=12, column=0, columnspan=2, sticky="nesw") refreshRate.set(self.controller.get("refreshRate")) def closeSettings(self): self.destroy() # noinspection PyUnusedLocal def setLat(self, *args): self.controller.set("Lat", varGetOrDefault(self.latVal, 0.0)) # noinspection PyUnusedLocal def setLon(self, *args): self.controller.set("Lon", varGetOrDefault(self.lonVal, 0.0)) # noinspection PyUnusedLocal def setComPort(self, *args): self.controller.set("comPort", varGetOrDefault(self.comNumber, 0)) # noinspection PyUnusedLocal def setCamera(self, *args): self.controller.set("camera", varGetOrDefault(self.camNumber, 0)) # noinspection PyUnusedLocal def setRot(self, *args): self.controller.set("rotate", varGetOrDefault(self.rotationAngle, 0)) # noinspection PyUnusedLocal def setHorFlip(self, *args): self.controller.set("flipHorizontal", not self.controller.get("flipHorizontal")) # noinspection PyUnusedLocal def setVerFlip(self, *args): self.controller.set("flipVertical", not self.controller.get("flipVertical"))
def __init__(self, master, par=False): """ GUI for selecting default parameters - will write parameters to file \ of users choosing. :type master: Tk :param master: Tkinter window :type par: EQcorrscanParameters :param par: Default parameters to start-up with. """ from tkinter import Label, Button, Entry, DoubleVar, StringVar, IntVar from tkinter import BooleanVar, OptionMenu, Checkbutton import tkMessageBox from eqcorrscan.utils import parameters from obspy import UTCDateTime import warnings # Set the default par, only if they don't already exist. if not par: par = parameters.EQcorrscanParameters([''], 2, 10, 4, 100, 2, '1900-01-01', '2300-01-01', '', 'seishub', 4, False, '', 'jpg', False, 8, 'MAD', 6) # Callback functions for all variables (ugly) def update_template_names(*args): par.template_names = [name.strip() for name in template_names.get().split(',')] template_names.set(', '.join(par.template_names)) def update_lowcut(*args): par.lowcut = lowcut.get() lowcut.set(par.lowcut) def update_highcut(*args): par.highcut = highcut.get() if par.highcut >= 0.5 * par.samp_rate: msg = ('Highcut must be less than the Nyquist, setting to ' + str((par.samp_rate / 2.0) - 1)) tkMessageBox.showwarning(title="Nyquist error", message=msg) par.highcut = (par.samp_rate / 2.0) - 1 highcut.set(par.highcut) def update_filt_order(*args): par.filt_order = filt_order.get() filt_order.set(par.filt_order) def update_samp_rate(*args): par.samp_rate = samp_rate.get() if par.highcut >= 0.5 * par.samp_rate: msg = ('Highcut must be less than the Nyquist, setting to ' + str((par.samp_rate / 2.0) - 1)) tkMessageBox.showwarning(title="Nyquist error", message=msg) par.highcut = (par.samp_rate / 2.0) - 1 highcut.set(par.highcut) samp_rate.set(par.samp_rate) def update_debug(*args): par.debug = debug.get() debug.set(par.debug) def update_startdate(*args): par.startdate = UTCDateTime(startdate.get()) startdate.set(str(par.startdate)) def update_enddate(*args): par.enddate = UTCDateTime(enddate.get()) enddate.set(str(par.enddate)) def update_archive(*args): par.archive = archive.get() archive.set(par.archive) def update_arc_type(*args): par.arc_type = arc_type.get() arc_type.set(par.arc_type) def update_cores(*args): par.cores = cores.get() cores.set(par.cores) def update_plotvar(*args): par.plotvar = plotvar.get() plotvar.set(par.plotvar) def update_plot_format(*args): par.plot_format = plot_format.get() plot_format.set(par.plot_format) def update_tempdir(*args): par.tempdir = tempdir.get() tempdir.set(par.tempdir) def update_threshold(*args): par.threshold = threshold.get() threshold.set(par.threshold) def update_threshold_type(*args): par.threshold_type = threshold_type.get() threshold_type.set(par.threshold_type) def update_plotdir(*args): par.plotdir = plotdir.get() plotdir.set(par.plotdir) def update_trigger_interval(*args): par.trigger_interval = trigger_interval.get() trigger_interval.set(par.trigger_interval) # Set some grid parameters nrows = 25 ncolumns = 3 self.master = master master.title("EQcorrscan parameter setup") self.label = Label(master, text="Alpha GUI for default setup") self.label.grid(column=0, columnspan=ncolumns, row=0) # Set up parameter input self.t_names_label = Label(master, text="Template names", anchor='e') self.t_names_label.grid(column=0, row=1, sticky='e') template_names = StringVar() template_names.set(', '.join(par.template_names)) self.t_names_box = Entry(master, bd=2, textvariable=template_names) self.t_names_box.grid(column=1, row=1) template_names.trace("w", update_template_names) self.t_names_lookup = Button(master, text="Lookup", command=lambda: self.get_template_names(par)) self.t_names_lookup.grid(column=2, row=1) self.lowcut_label = Label(master, text="Lowcut (Hz)", anchor='e') self.lowcut_label.grid(column=0, row=2, sticky='e') lowcut = DoubleVar() lowcut.set(par.lowcut) self.lowcut_box = Entry(master, bd=2, textvariable=lowcut) self.lowcut_box.grid(column=1, row=2) lowcut.trace("w", update_lowcut) self.highcut_label = Label(master, text="Highcut (Hz)", anchor='e') self.highcut_label.grid(column=0, row=3, sticky='e') highcut = DoubleVar() highcut.set(par.highcut) self.highcut_box = Entry(master, bd=2, textvariable=highcut) self.highcut_box.grid(column=1, row=3) highcut.trace("w", update_highcut) self.filt_order_label = Label(master, text="Filter order") self.filt_order_label.grid(column=0, row=4, sticky='e') filt_order = DoubleVar() filt_order.set(par.filt_order) self.filt_order_box = Entry(master, bd=2, textvariable=filt_order) self.filt_order_box.grid(column=1, row=4) filt_order.trace("w", update_filt_order) self.samp_rate_label = Label(master, text="Sample rate (Hz)") self.samp_rate_label.grid(column=0, row=5, sticky='e') samp_rate = DoubleVar() samp_rate.set(par.samp_rate) self.samp_rate_box = Entry(master, bd=2, textvariable=samp_rate) self.samp_rate_box.grid(column=1, row=5) samp_rate.trace("w", update_samp_rate) self.debug_label = Label(master, text="Debug") self.debug_label.grid(column=0, row=6, sticky='e') debug = IntVar() debug.set(par.debug) self.debug_box = Entry(master, bd=2, textvariable=debug) self.debug_box.grid(column=1, row=6) debug.trace("w", update_debug) self.startdate_label = Label(master, text="Start date (yyyy-mm-dd)") self.startdate_label.grid(column=0, row=6, sticky='e') startdate = StringVar() startdate.set(par.startdate) self.startdate_box = Entry(master, bd=2, textvariable=startdate) self.startdate_box.grid(column=1, row=6) startdate.trace("w", update_startdate) self.enddate_label = Label(master, text="End date (yyyy-mm-dd)") self.enddate_label.grid(column=0, row=8, sticky='e') enddate = StringVar() enddate.set(par.enddate) self.enddate_box = Entry(master, bd=2, textvariable=enddate) self.enddate_box.grid(column=1, row=8) enddate.trace("w", update_enddate) self.archive_label = Label(master, text="Archive") self.archive_label.grid(column=0, row=9, sticky='e') archive = StringVar() archive.set(par.archive) self.archive_box = Entry(master, bd=2, textvariable=archive) self.archive_box.grid(column=1, row=9) archive.trace("w", update_archive) self.archive_lookup = Button(master, text="Lookup", command=lambda: self.get_archive(par)) self.archive_lookup.grid(column=2, row=9) self.arc_type_label = Label(master, text="Archive type") self.arc_type_label.grid(column=0, row=10, sticky='e') arc_type = StringVar() arc_type.set(par.arc_type) self.arc_type_box = OptionMenu(master, arc_type, "seishub", "fdsn", "day_vols") self.arc_type_box.grid(column=1, row=10, sticky='w,e') arc_type.trace("w", update_arc_type) self.cores_label = Label(master, text="Number of cores") self.cores_label.grid(column=0, row=11, sticky='e') cores = IntVar() cores.set(par.cores) self.cores_box = Entry(master, bd=2, textvariable=cores) self.cores_box.grid(column=1, row=11) cores.trace("w", update_cores) self.plotvar_label = Label(master, text="Plotting on/off") self.plotvar_label.grid(column=0, row=12, sticky='e') plotvar = BooleanVar() plotvar.set(par.plotvar) self.plotvar_box = Checkbutton(master, text='Plot on', var=plotvar, onvalue=True, offvalue=False) self.plotvar_box.grid(column=1, row=12) plotvar.trace("w", update_plotvar) self.plotdir_label = Label(master, text="Plot directory") self.plotdir_label.grid(column=0, row=13, sticky='e') plotdir = StringVar() plotdir.set(par.plotdir) self.plotdir_box = Entry(master, bd=2, textvariable=plotdir) self.plotdir_box.grid(column=1, row=13) plotdir.trace("w", update_plotdir) self.plotdir_lookup = Button(master, text="Lookup", command=lambda: self.get_plotdir(par)) self.plotdir_lookup.grid(column=2, row=13) self.plot_format_label = Label(master, text="Plot format") self.plot_format_label.grid(column=0, row=14, sticky='e') plot_format = StringVar() plot_format.set(par.plot_format) self.plot_format_box = OptionMenu(master, plot_format, "jpg", "eps", "pdf", "png") self.plot_format_box.grid(column=1, row=14, sticky='w,e') plot_format.trace("w", update_plot_format) self.tempdir_label = Label(master, text="Temporary directory") self.tempdir_label.grid(column=0, row=15, sticky='e') tempdir = StringVar() tempdir.set(par.tempdir) self.tempdir_box = Entry(master, bd=2, textvariable=tempdir) self.tempdir_box.grid(column=1, row=15) tempdir.trace("w", update_tempdir) self.tempdir_lookup = Button(master, text="Lookup", command=lambda: self.get_tempdir(par)) self.tempdir_lookup.grid(column=2, row=15) self.threshold_label = Label(master, text="Threshold") self.threshold_label.grid(column=0, row=16, sticky='e') threshold = DoubleVar() threshold.set(par.threshold) self.threshold_box = Entry(master, bd=2, textvariable=threshold) self.threshold_box.grid(column=1, row=16) threshold.trace("w", update_threshold) self.threshold_type_label = Label(master, text="Threshold type") self.threshold_type_label.grid(column=0, row=17, sticky='e') threshold_type = StringVar() threshold_type.set(par.threshold_type) self.threshold_type_box = OptionMenu(master, threshold_type, "MAD", "absolute", "av_chan_corr") self.threshold_type_box.grid(column=1, row=17, sticky='w,e') threshold_type.trace("w", update_threshold_type) self.trigger_interval_label = Label(master, text="Minimum trigger " + "interval (s)") self.trigger_interval_label.grid(column=0, row=18, sticky='e') trigger_interval = DoubleVar() trigger_interval.set(par.trigger_interval) self.trigger_interval_box = Entry(master, bd=2, textvariable=trigger_interval) self.trigger_interval_box.grid(column=1, row=18) trigger_interval.trace("w", update_trigger_interval) # End of user editable section, now we have read/write buttons self.read_button = Button(master, text="Read parameters", command=lambda: self.read_par(master)) self.read_button.grid(column=0, row=nrows-2, sticky='w,e') self.write_button = Button(master, text="Write parameters", command=lambda: self.write_par(par)) self.write_button.grid(column=1, row=nrows-2, sticky='w,e')
class lFrame3(cFrame): def __init__(self, parent, pos, name, spring): super().__init__(parent, pos, name, spring) self.cycles = DoubleVar() self.cycles.trace('w', self.solve) self.frame.grid_columnconfigure(1, minsize=1, weight=1) self.frame.grid_columnconfigure(2, minsize=1, weight=1) self.labels = {} self.defUnit = 'mm' self.entries = OrderedDict([('10\u2075', { 'value': 1e5, 'entry': None }), ('10\u2076', { 'value': 1e6, 'entry': None }), ('10\u2077', { 'value': 1e7, 'entry': None })]) def init_widget(self): Label(self.frame, text='Ciclos:').grid(column=0, row=0, sticky='we', columnspan=1) i = 1 for k in self.entries.keys(): rb = Radiobutton(self.frame, text=k, variable=self.cycles, value=self.entries[k]['value'], state='disabled') rb.grid(sticky='ew', column=0, row=i, columnspan=1) self.entries[k]['entry'] = rb i += 1 Label(self.frame, text='Deflexión máxima:').grid(column=1, row=0, sticky='w', columnspan=2, pady=2, padx=5) Label(self.frame, text='Frecuencia máxima:').grid(column=1, row=2, sticky='w', columnspan=2, pady=2, padx=5) self.labels['x'] = Label(self.frame, text='-') self.labels['x'].grid(column=1, row=1, sticky='n') self.labels['fmax'] = Label(self.frame, text='-') self.labels['fmax'].grid(column=1, row=3, sticky='n') self.cycles.set(1e6) def solve(self, *args): if self.spring.isSolved: res = self.spring.verifyDynamic(cycles=self.cycles.get()) self.labels['x']['text'] = "{:.2f} {}".format( res['x'], self.defUnit) self.labels['fmax']['text'] = "{:.2f} ciclos / min".\ format(res['fmax']) def enaButtons(self, event): super().enaButtons(event) self.cycles.set(self.cycles.get()) def disButtons(self, event): for k in self.labels.keys(): self.labels[k]['text'] = '-' super().disButtons(event)