def test_get_from_int(self): v = DoubleVar(self.root, 1.23, 'name') self.assertAlmostEqual(1.23, v.get()) self.root.globalsetvar('name', '3.45') self.assertAlmostEqual(3.45, v.get()) self.root.globalsetvar('name', '456') self.assertAlmostEqual(456, v.get())
def test_get_from_int(self): v = DoubleVar(self.root, 1.23, "name") self.assertAlmostEqual(1.23, v.get()) self.root.globalsetvar("name", "3.45") self.assertAlmostEqual(3.45, v.get()) self.root.globalsetvar("name", "456") self.assertAlmostEqual(456, v.get())
def getView(self, window): view = Frame(window) Label(view, text=self.question).pack() if (self.screentype == "Scale"): var = DoubleVar() slider = Scale(view, from_=0, to=100, orient=HORIZONTAL, variable=var, command=self.updateButtonText) slider.pack() self.btn = Button( master=view, text="Your Answer = " + str(slider.get()), command=lambda *args: self.check(str(slider.get()), view)) self.btn.pack() elif (self.screentype == "Radio"): var = StringVar() Radiobutton( view, text=self.answers[0], value="A", variable=var, command=lambda *args: self.check(var.get(), view)).pack() Radiobutton( view, text=self.answers[1], value="B", variable=var, command=lambda *args: self.check(var.get(), view)).pack() Radiobutton( view, text=self.answers[2], value="C", variable=var, command=lambda *args: self.check(var.get(), view)).pack() Radiobutton( view, text=self.answers[3], value="D", variable=var, command=lambda *args: self.check(var.get(), view)).pack() var.set(None) else: Button(view, text=self.answers[0], command=lambda *args: self.check("A", view)).pack() Button(view, text=self.answers[1], command=lambda *args: self.check("B", view)).pack() Button(view, text=self.answers[2], command=lambda *args: self.check("C", view)).pack() Button(view, text=self.answers[3], command=lambda *args: self.check("D", view)).pack() return view
class Window: def __init__(self, master): log("class inited") self.a = DoubleVar() self.b = DoubleVar() self.c = DoubleVar() self.input_a = Entry() self.input_b = Entry() self.input_c = Entry() self.calc_button = Button() self.input_box(master, self.input_a, self.a, 1, 1, 2) self.input_box(master, self.input_b, self.b, 2, 1, 1) self.input_box(master, self.input_c, self.c, 2, 2, 1) self.a_button(master, self.calc_button, "Calculate!", self.get_calculate, 3, 1, 2) #master.mainloop() def get_calculate(self): self.a = self.a.get() self.b = self.b.get() self.c = self.c.get() #input_b.insert(0, a) print(self.a) print(self.b) print(self.c) print("read2") def input_box(self, master, widget_name, txt_var, grid_row, grid_col, col_span): log("box") widget_name = Entry(master, width=5, justify="center", textvariable=txt_var) widget_name.grid(row=grid_row, column=grid_col, columnspan=col_span) def a_button(self, master, widget_name, text, command, grid_row, grid_col, col_span): widget_name = Button(master, text=text, command=command, justify="center") widget_name.grid(row=grid_row, column=grid_col, columnspan=col_span)
def show_entries(_, title: str, temperature: tk.DoubleVar, values_entry: tk.Text): title_str = title.format(temperature.get()) try: mbox.showinfo( "Extra Point Viewer", "{}\n{}".format( title_str, "\n".join("{}. {}".format(i + 1, x.strip()) for i, x in enumerate( values_entry.get(1.0, tk.END).split(","))))) except ValueError: mbox.showwarning( title_str, "Text in the field is malformed, please update the values.")
class Parameter: def __init__(self, name, var): self.name = name self.var = var self.val = float(var.get()) self.doublevar = DoubleVar(value=self.val) def getVal(self): try: val = float(self.var.get()) if val == 0 and cantBeZero(self.name): return self.doublevar.get() self.doublevar.set(val) return val except ValueError: return self.doublevar.get() def udv(self, *args): self.setVal(self.doublevar.get()) def setVal(self, value): self.var.set(value) self.doublevar.set(value)
class Spectrogram(Module): def __init__(self,app): info( ' - initializing module: Spectrogram' ) self.app = app self.frame = Frame(self.app.BOTTOM) self.frame.grid( row=0, column=1, pady=(self.app.pady*2,self.app.pady/2) ) self.axis_frame = Frame(self.app.BOTTOM) self.axis_frame.grid( row=0, column=0, sticky='e', pady=(self.app.pady*2,self.app.pady/2) ) self.canvas_width = self.app.TextGrid.canvas_width self.canvas_height = 106 self.canvas = Canvas(self.frame, width=self.canvas_width, height=self.canvas_height, background='gray', highlightthickness=0) self.spectrogram = None self.spec_freq_max = DoubleVar() self.wl = DoubleVar() self.dyn_range = DoubleVar() self.clicktime = -1 self.specClick = False self.oldSelected = None self.doDefaults() #make spinboxes & buttons for spectrogram specs self.spinwin = Frame(self.axis_frame) #spinboxes axis_ceil_box = Spinbox(self.spinwin, textvariable=self.spec_freq_max, command=self.drawSpectrogram, width=7, increment=100, from_=0, to_=100000) axis_ceil_box.bind('<Return>',self.drawSpectrogram) axis_ceil_box.bind('<Escape>',lambda ev: self.spinwin.focus()) wl_box = Spinbox(self.spinwin, textvariable=self.wl, command=self.drawSpectrogram, width=7, increment=0.0005, from_=0, to_=1) wl_box.bind('<Return>',self.drawSpectrogram) wl_box.bind('<Escape>',lambda ev: self.spinwin.focus()) dyn_range_box = Spinbox(self.spinwin, textvariable=self.dyn_range, command=self.drawSpectrogram, width=7, increment=10, from_=0, to_=10000) dyn_range_box.bind('<Return>',self.drawSpectrogram) dyn_range_box.bind('<Escape>',lambda ev: self.spinwin.focus()) #buttons default_btn = Button(self.spinwin, text='Standards', command=self.restoreDefaults, takefocus=0) apply_btn = Button(self.spinwin, text='Apply', command=self.drawSpectrogram, takefocus=0, width=6) # self.axis_frame.create_window(wwidth,self.canvas_height, window=self.spinwin, anchor='ne') #grid spinboxes & buttons on subframe axis_ceil_box.grid(row=0, columnspan=2, sticky='ne') wl_box.grid(row=1, columnspan=2, sticky='ne') dyn_range_box.grid(row=2, columnspan=2, sticky='ne') default_btn.grid(row=3) apply_btn.grid(row=3, column=1) self.grid() self.canvas.bind('<Button-1>', self.jumpToFrame) # self.canvas.bind('<Shift-Button-1>', self.jumpToFrame) def doDefaults(self): self.spec_freq_max.set(5000.0) self.wl.set(0.005) self.dyn_range.set(90) def restoreDefaults(self): self.doDefaults() self.drawSpectrogram() def update(self): ''' Removes and redraws lines on top of Spectrogram corresponding to selected interval(s) ''' self.canvas.delete('line') self.drawInterval() def reset(self): self.drawSpectrogram() self.drawInterval() def drawSpectrogram(self, event=None): ''' Extracts spectrogram data from sound, and draws it to canvas ''' if not LIBS_INSTALLED: return if self.app.Audio.current: sound = parselmouth.Sound(self.app.Audio.current) self.canvas.delete('all') ts_fac = 10000.0 wl = self.wl.get() screen_start = self.app.TextGrid.start screen_end = self.app.TextGrid.end screen_duration = screen_end - screen_start audio_start = 0 audio_end = sound.get_total_duration() real_start = max(screen_start, audio_start) real_end = min(screen_end, audio_end) duration = real_end - real_start if duration <= 0: return self.ts = duration / ts_fac # the amount taken off in spectrogram creation seems to be # ( 2 * ts * floor( wl / ts ) ) + ( duration % ts ) # but we've defined ts as duration / 10000, so duration % ts = 0 # so the amount to increase the length by is ts * floor( wl / ts ) # at either end - D.S. extra = self.ts * math.floor( wl / self.ts ) start_time = max(0, real_start - extra) end_time = min(real_end + extra, sound.get_total_duration()) sound_clip = sound.extract_part(from_time=start_time, to_time=end_time) spec = sound_clip.to_spectrogram(window_length=wl, time_step=self.ts, maximum_frequency=self.spec_freq_max.get()) self.spectrogram = 10 * np.log10(np.flip(spec.values, 0)) # self.spectrogram += self.spectrogram.min() # self.spectrogram *= (60.0 / self.spectrogram.max()) mx = self.spectrogram.max() dyn = self.dyn_range.get() # debug(self.spectrogram.min(), self.spectrogram.max()) self.spectrogram = self.spectrogram.clip(mx-dyn, mx) - mx # debug(self.spectrogram.min(), self.spectrogram.max()) self.spectrogram *= (-255.0 / dyn) # self.spectrogram += 60 # debug(self.spectrogram.min(), self.spectrogram.max()) img = PIL.Image.fromarray(self.spectrogram) if img.mode != 'RGB': img = img.convert('RGB') # contrast = ImageEnhance.Contrast(img) # img = contrast.enhance(5) # self.canvas_height = img.height img = img.resize((int(self.canvas_width*(duration / screen_duration)), self.canvas_height)) photo_img = ImageTk.PhotoImage(img) self.canvas.config(height=self.canvas_height) # self.canvas.create_image(0,0, anchor='nw', image=photo_img) # self.canvas.create_image(self.canvas_width/2,self.canvas_height/2, image=photo_img) if self.app.TextGrid.selectedItem: tags = self.app.TextGrid.selectedItem[0].gettags(self.app.TextGrid.selectedItem[1]) coord = self.canvas_width coord *= 1 - ((screen_end - real_end) / screen_duration) img = self.canvas.create_image(coord, self.canvas_height, anchor='se', image=photo_img) self.img = photo_img #pass on selected-ness if self.app.TextGrid.selectedItem: if self.app.TextGrid.selectedItem[0] == self.canvas: self.app.TextGrid.selectedItem = (self.canvas, img) #pass on tags for tag in tags: self.canvas.addtag_all(tag) def drawInterval(self): ''' Adapted with permission from https://courses.engr.illinois.edu/ece590sip/sp2018/spectrograms1_wideband_narrowband.html by Mark Hasegawa-Johnson ''' if self.app.TextGrid.selectedItem: widg = self.app.TextGrid.selectedItem[0] itm = self.app.TextGrid.selectedItem[1] if widg in self.app.TextGrid.tier_pairs: #if widg is label itvl_canvas = self.app.TextGrid.tier_pairs[widg] for i in itvl_canvas.find_withtag('line'): loc = itvl_canvas.coords(i)[0] self.canvas.create_line(loc, 0, loc, self.canvas_height, tags='line', fill='blue') elif widg in self.app.TextGrid.tier_pairs.values(): #if widg is textgrid canvas if itm-1 in widg.find_all(): l_loc = widg.coords(itm-1)[0] self.canvas.create_line(l_loc, 0, l_loc, self.canvas_height, tags='line', fill='blue') if itm+1 in widg.find_all(): r_loc = widg.coords(itm+1)[0] self.canvas.create_line(r_loc, 0, r_loc, self.canvas_height, tags='line', fill='blue') elif widg == self.canvas: l_time, r_time = self.app.TextGrid.getMinMaxTime() l_loc = self.timeToX(float(l_time)) r_loc = self.timeToX(float(r_time)) self.canvas.create_line(l_loc, 0, l_loc, self.canvas_height, tags='line', fill='blue') self.canvas.create_line(r_loc, 0, r_loc, self.canvas_height, tags='line', fill='blue') #draw selected frame if self.app.TextGrid.firstFrame <= self.app.frame <= self.app.TextGrid.lastFrame : xcoord = self.app.TextGrid.frames_canvas.coords(self.app.TextGrid.highlighted_frame)[0] self.canvas.create_line(xcoord,0,xcoord,self.canvas_height, tags='line', fill='red') #draw line where user last clicked on spectrogram if self.clicktime != -1 and self.specClick == False: x = self.timeToX(self.clicktime) self.canvas.create_line(x,0,x,self.canvas_height, tags='line', fill='green') def jumpToFrame(self, event): ''' ''' #restore textgrid selected interval between clicks if not self.app.TextGrid.selectedItem: key = next(iter(self.app.TextGrid.tier_pairs)) wdg = self.app.TextGrid.tier_pairs[key] self.app.TextGrid.selectedItem = (wdg,wdg.find_all()[0]) self.app.TextGrid.setSelectedIntvlFrames(self.app.TextGrid.selectedItem) if self.app.TextGrid.selectedItem[0] == self.canvas: self.app.TextGrid.selectedItem = self.oldSelected self.app.TextGrid.setSelectedIntvlFrames(self.app.TextGrid.selectedItem) #prevents wiping of canvases because of mouse click # self.app.resized = False # draw line at click location x = self.canvas.canvasx(event.x) self.clicktime = self.xToTime(x) #jump to new frame frame = self.app.TextGrid.my_find_closest(self.app.TextGrid.frames_canvas, self.canvas.canvasx(event.x)) framenum = self.app.TextGrid.frames_canvas.gettags(frame)[0][5:] self.app.frame=int(framenum) self.app.framesUpdate() #remember which interval was selected before specgram click if event.state==1: self.oldSelected = self.app.TextGrid.selectedItem #for selecting & zooming interval (w/ shift) self.specClick = True def xToTime(self, x): ''' converts from a x coordinate (relative to the canvas) to the timestamp at that coordinate''' return (x*float(self.app.TextGrid.end - self.app.TextGrid.start)/self.canvas_width) + float(self.app.TextGrid.start) def timeToX(self,time): ''' converts from a time to the x coordinate on a canvas representing that time''' return self.canvas_width*(time - float(self.app.TextGrid.start))/float(self.app.TextGrid.end - self.app.TextGrid.start) def grid(self): ''' Put tkinter items on app ''' self.canvas.grid(row=0, column=0, sticky='news') self.spinwin.grid(row=0,column=0,sticky='ne') # self.axis_canvas.grid(row=0,column=0,sticky='se') def grid_remove(self): self.canvas.grid_remove() self.spinwin.grid_remove()
class dpph_measurement: ''' ''' def __init__(self, pype, toplevel=False, **runargs): ''' ''' self.pype = pype self.runargs = runargs self.toplevel = toplevel self.sweep_result = {} self.powerVar = DoubleVar(value=20) #dBm self.set_power_BoolVar = BooleanVar(value=True) self.start_freq_Var = DoubleVar(value=26350) #MHz self.stop_freq_Var = DoubleVar(value=26600) #MHz self.start_search_freq_Var = DoubleVar(value=26450) #MHz self.stop_search_freq_Var = DoubleVar(value=26510) #MHz self.sweep_time_Var = DoubleVar(value=15) #s self.num_points_Var = IntVar(value=400) #ms self.spanVar = DoubleVar(value=100) self.stepVar = DoubleVar(value=4) #self.fit_channel_Var = StringVar(value='xdata') self.result_str_Var = StringVar(value='') self._BuildGui() def _BuildGui(self): ''' Dpph popup window ''' row = 0 ################################################################## # Lockin Scan Label(self.toplevel, text='Input Power' ).grid(row=row, column=0, sticky='ew') Entry(self.toplevel, textvariable=self.powerVar ).grid(row=row, column=1, sticky='ew') Label(self.toplevel, text='[dBm]', justify='left' ).grid(row=row, column=2, sticky='w') Checkbutton(self.toplevel, text="Don't Change", variable=self.set_power_BoolVar).grid(row=row, column=3) row += 1 Label(self.toplevel, text='Scan Frequency Range' ).grid(row=row, column=0, sticky='ew') Entry(self.toplevel, textvariable=self.start_freq_Var ).grid(row=row, column=1, sticky='ew') Entry(self.toplevel, textvariable=self.stop_freq_Var ).grid(row=row, column=2, columnspan=2, sticky='ew') Label(self.toplevel, text='[MHz]').grid(row=row, column=4, sticky='w') row += 1 Label(self.toplevel, text='Sweep Time' ).grid(row=row, column=0, sticky='ew') Entry(self.toplevel, textvariable=self.sweep_time_Var ).grid(row=row, column=1, sticky='ew') Label(self.toplevel, text='[s]').grid(row=row, column=2, sticky='w') row += 1 Label(self.toplevel, text='Number of Points' ).grid(row=row, column=0, sticky='ew') Entry(self.toplevel, textvariable=self.num_points_Var ).grid(row=row, column=1, sticky='ew') row += 1 Button(self.toplevel, text='take data', command=self._CollectSweep ).grid(row=row, column=0) row += 1 Label(self.toplevel, text='-'*50).grid(row=row, column=0, columnspan=4, sticky='ew') row += 1 ################################################################## # Resonance Search Label(self.toplevel, text='Search Frequency Range' ).grid(row=row, column=0, sticky='ew') Entry(self.toplevel, textvariable=self.start_search_freq_Var ).grid(row=row, column=1, sticky='ew') Entry(self.toplevel, textvariable=self.stop_search_freq_Var ).grid(row=row, column=2, columnspan=2, sticky='ew') Label(self.toplevel, text='[MHz]').grid(row=row, column=4, sticky='w') row += 1 #ch_options = ['xdata', 'ydata'] #OptionMenu(self.toplevel, self.fit_channel_Var, *ch_options # ).grid(row=row, column=0, rowspan=2, sticky='ew') Button(self.toplevel, text='find resonance', command=self._FindResonance ).grid(row=row, column=1, rowspan=2, sticky='ew') Label(self.toplevel, textvariable=self.result_str_Var ).grid(row=row, column=2, rowspan=2, columnspan=3, sticky='ew') row += 2 Button(self.toplevel, text='Dump To json', command=self._SaveJson ).grid(row=row, column=0) Button(self.toplevel, text='Save Image', command=self._SaveFigure ).grid(row=row, column=1) Button(self.toplevel, text='Log DPPH', command=self._LogDPPH ).grid(row=row, column=2) self._SetupPlot(row=0, column=5) def _SetupPlot(self, row, column): ''' Initialize the plot in the gui ''' self.figure = Figure() self.figure.subplots_adjust(left=0.15, bottom=0.2) self.subfigure = self.figure.add_subplot(1, 1, 1) self.subfigure.plot([0], [0]) self.subfigure.plot([0], [0]) self.subfigure.set_xlabel('Freq [MHz]') self.canvas = FigureCanvasTkAgg(self.figure, master=self.toplevel) self.canvas.show() self.canvas.get_tk_widget().grid(row=row, column=column, rowspan=10) def _CollectSweep(self): ''' ''' tmp_power = self.powerVar.get() if self.set_power_BoolVar.get(): tmp_power = False while True: sweep = _GetSweptVoltages(pype=self.pype, start_freq=self.start_freq_Var.get(), stop_freq=self.stop_freq_Var.get(), sweep_time=self.sweep_time_Var.get(), power=tmp_power, num_points=self.num_points_Var.get()) self.sweep_result = sweep.copy() freqdata = array(sweep['frequency_curve']) magdata = sweep['amplitude_curve'] if type(magdata[0]) is unicode: print('Warning: _GetSweptVoltages failed;') print('magdata:') print(magdata) print('Acquiring data again...') elif type(magdata[0]) is int: break if not sweep['frequencies_confirmed']: showwarning('Warning', 'Communication with lockin amp failed. Frequencies data may be wrong') magdata = magdata - mean(magdata) #ydata = sweep['y_curve'] print('freq range is ', min(freqdata), ' to ', max(freqdata)) #xdata = sweep['x_curve'] y_del = max((max(magdata) - min(magdata)) * .05, 1) self.subfigure.set_xlim(left=freqdata[0], right=freqdata[-1]) self.subfigure.set_ylim(bottom=(min(magdata) - y_del), top=(max(magdata) + y_del)) line = self.subfigure.get_lines()[0] line.set_xdata(array(freqdata)) line.set_ydata(array(magdata)) line.set_label('lockin output') #line = self.subfigure.get_lines()[1] #line.set_xdata(array(freqdata)) #line.set_ydata(array(ydata)) #line.set_label('y output') self.figure.legends = [] self.figure.legend(*self.subfigure.get_legend_handles_labels()) self.figure.legends[0].draggable(True) self.canvas.draw() self.canvas.show() print('Searching for resonance...') self._FindResonance() def _FindResonance(self): ''' ''' #if self.fit_channel_Var.get() == 'xdata': # line = self.subfigure.get_lines()[0] #elif self.fit_channel_Var.get() == 'ydata': # line = self.subfigure.get_lines()[1] line = self.subfigure.get_lines()[0] #else: # raise ValueError('not a valid dataset selection') xdata = line.get_xdata() ydata = line.get_ydata() fit = _FindFieldFFT(min_freq=self.start_search_freq_Var.get(), max_freq=self.stop_search_freq_Var.get(), freq_data=xdata, volts_data=ydata) outline = self.subfigure.get_lines()[1] factor = max(ydata) / max(fit['result']) scaled_data = [val * factor for val in fit['result']] scaled_data = scaled_data - mean(scaled_data) outline.set_xdata(fit['freqs']) outline.set_ydata(scaled_data) outline.set_label('filter result') self.figure.legends = [] self.figure.legend(*self.subfigure.get_legend_handles_labels()) self.figure.legends[0].draggable(True) self.canvas.draw() self.canvas.show() res_freq = max(zip(fit['result'], fit['freqs']))[1] res_unct = fit['freqs'][1] - fit['freqs'][0] print('resonance found at:', res_freq, 'MHz') print('err is:', res_unct) geff = 2.0036 chargemass = 1.758e11 freq_to_field = 4 * pi * 10 ** 7 / (geff * chargemass) res_field = freq_to_field * res_freq res_field_unct = freq_to_field * res_unct print('for a field of', res_field) print('field unct of', res_field_unct) self.result_str_Var.set('{:.4E} +/- {:.1E} MHz \n({:.4E} +/- {:.1E} kG)'.format( res_freq, res_unct, res_field, res_field_unct)) self.sweep_result.update({'res_freq': res_freq, 'res_freq_unct': res_unct, 'res_field': res_field, 'res_field_unct': res_field_unct}) def _SaveJson(self): ''' ''' if not self.sweep_result: print('no result stored') return outfile = asksaveasfile(defaultextension='.json') dump(self.sweep_result, outfile, indent=4) outfile.close() def _SaveFigure(self): ''' ''' file_extensions = [('vectorized', '.eps'), ('adobe', '.pdf'), ('image', '.png'), ('all', '.*')] outfile = asksaveasfilename(defaultextension='.pdf', filetypes=file_extensions) self.figure.savefig(outfile) def _LogDPPH(self): if not self.sweep_result: print('no dpph_result stored') return result = { 'uncal': self.sweep_result['res_freq'], 'uncal_err': self.sweep_result['res_freq_unct'], 'uncal_units': 'MHz', 'cal': self.sweep_result['res_field'], 'cal_err': self.sweep_result['res_field_unct'], 'cal_units': 'kG', } dpph_result = {'uncal_val': ' '.join([str(result['uncal']), '+/-', str(result['uncal_err']), result['uncal_units']]), 'cal_val': ' '.join([str(result['cal']), '+/-', str(result['cal_err']), result['cal_units']]), 'timestamp': datetime.utcnow()} self.pype.LogValue(sensor='dpph_field', **dpph_result) print('dpph_result stored')
class TkMainGui(ttk.Frame): def __init__(self, root, default_folder=""): ttk.Frame.__init__(self, root, padding="3 3 12 12") self.default_folder = default_folder logger.debug("Create main frame") self.grid(column=0, row=0, sticky=(N, W, E, S)) self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) logger.debug("Create variable") self.program_path = StringVar() file_path = os.path.join(self.default_folder, "30kV ElementsView.exe") self.program_path.set(file_path) self.basename = StringVar() self.basename.set("test") self.acquisition_mode = StringVar() self.acquisition_mode.set(ACQUISITION_MODE_MANUAL) self.number_spectra = IntVar() self.number_spectra.set(100) self.delay_spectrum_s = DoubleVar() self.delay_spectrum_s.set(1) self.overwrite = BooleanVar() self.overwrite.set(False) self.fast_acquisition = BooleanVar() self.fast_acquisition.set(False) self.is_top_window = BooleanVar() self.is_top_window.set(False) self.is_manual_acquisition_button = BooleanVar() self.is_manual_acquisition_button.set(False) self.is_save_as = BooleanVar() self.is_save_as.set(False) self.results_text = StringVar() widget_width = 40 logger.debug("Create program button") row_id = 1 file_path_entry = ttk.Entry(self, width=widget_width, textvariable=self.program_path) file_path_entry.grid(column=2, row=row_id, sticky=(W, E)) ttk.Button(self, width=widget_width, text="Select ElementView program file", command=self.open_element_view_program).grid(column=3, row=row_id, sticky=W) logger.debug("Create basename label and edit entry") row_id += 1 basename_label = ttk.Label(self, width=widget_width, text="basename: ", state="readonly") basename_label.grid(column=2, row=row_id, sticky=(W, E)) basename_entry = ttk.Entry(self, width=widget_width, textvariable=self.basename) basename_entry.grid(column=3, row=row_id, sticky=(W, E)) row_id += 1 acquisition_mode_label = ttk.Label(self, width=widget_width, text="Acquisition mode: ", state="readonly") acquisition_mode_label.grid(column=2, row=row_id, sticky=(W, E)) acquisition_mode_entry = ttk.Combobox( self, width=widget_width, textvariable=self.acquisition_mode, values=[ACQUISITION_MODE_LIVE, ACQUISITION_MODE_MANUAL]) acquisition_mode_entry.grid(column=3, row=row_id, sticky=(W, E)) row_id += 1 number_spectra_label = ttk.Label(self, width=widget_width, text="Number of spectra: ", state="readonly") number_spectra_label.grid(column=2, row=row_id, sticky=(W, E)) number_spectra_entry = ttk.Entry(self, width=widget_width, textvariable=self.number_spectra) number_spectra_entry.grid(column=3, row=row_id, sticky=(W, E)) row_id += 1 delay_spectrum_label = ttk.Label( self, width=widget_width, text="Delay between of spectrum (s): ", state="readonly") delay_spectrum_label.grid(column=2, row=row_id, sticky=(W, E)) delay_spectrum_entry = ttk.Entry(self, width=widget_width, textvariable=self.delay_spectrum_s) delay_spectrum_entry.grid(column=3, row=row_id, sticky=(W, E)) row_id += 1 ttk.Checkbutton(self, width=widget_width, text="Overwrite file", variable=self.overwrite).grid(column=3, row=row_id, sticky=(W, E)) row_id += 1 ttk.Checkbutton(self, width=widget_width, text="Fast acquisition", variable=self.fast_acquisition).grid(column=3, row=row_id, sticky=(W, E)) row_id += 1 ttk.Button(self, width=widget_width, text="Find ElementView", command=self.find_element_view).grid(column=3, row=row_id, sticky=W) logger.debug("ElementView elements") row_id += 1 ttk.Checkbutton(self, width=widget_width, text="Top window", variable=self.is_top_window, state=DISABLED).grid(column=3, row=row_id, sticky=(W, E)) row_id += 1 ttk.Checkbutton(self, width=widget_width, text="Manual acquisition", variable=self.is_manual_acquisition_button, state=DISABLED).grid(column=3, row=row_id, sticky=(W, E)) row_id += 1 ttk.Checkbutton(self, width=widget_width, text="Save as", variable=self.is_save_as, state=DISABLED).grid(column=3, row=row_id, sticky=(W, E)) row_id += 1 self.start_button = ttk.Button(self, width=widget_width, text="Start script", command=self.start_script, state=DISABLED) self.start_button.grid(column=3, row=row_id, sticky=W) row_id += 1 results_label = ttk.Label(self, textvariable=self.results_text, state="readonly") results_label.grid(column=2, row=row_id, sticky=(W, E)) for child in self.winfo_children(): child.grid_configure(padx=5, pady=5) basename_entry.focus() self.results_text.set("Start") def open_element_view_program(self): logger.debug("open_element_view_program") file_path = filedialog.askopenfilename(filetypes=(("executable file", "*.exe"), ), initialdir=self.default_folder) logger.debug(file_path) self.program_path.set(file_path) def find_element_view(self): try: app = Application(backend="win32").connect( path=self.program_path.get()) logger.info("Application connected") # logger.info("app: {}".format(app.print_control_identifiers(depth=1))) try: top_window = app.top_window() top_window.wait("exists enabled visible ready") self.is_top_window.set(True) logger.info("top_window: {}".format( top_window.print_control_identifiers(depth=1))) try: logger.info("Button2: {}".format( top_window.Button2.print_control_identifiers(depth=1))) self.is_manual_acquisition_button.set(True) except Exception as message: logger.error(message) self.is_manual_acquisition_button.set(False) try: top_window.menu_select("File -> Save") logger.info("File->Save") app.Comment.wait("exists enabled visible ready") logger.info(app.Comment.print_control_identifiers()) # app.CommentEdit.Edit.SetEditText("auto script") app.Comment.OK.click() logger.info("Comment") app['Save As'].wait("exists enabled visible ready") logger.info( app['Save As'].print_control_identifiers(depth=2)) app['Save As'].Cancel.click() logger.info("Cancel") self.is_save_as.set(True) except Exception as message: logger.error(message) self.is_save_as.set(False) except Exception as message: logger.errror(message) self.is_top_window.set(False) self.is_manual_acquisition_button.set(False) self.is_save_as.set(False) except (TimeoutError, AppNotConnected, ProcessNotFoundError) as message: logger.error(message) self.is_top_window.set(False) self.is_manual_acquisition_button.set(False) self.is_save_as.set(False) if self.is_top_window.get() and self.is_manual_acquisition_button.get( ) and self.is_save_as.get(): self.results_text.set("ElementView elements found") self.start_button.config(state=NORMAL) else: self.results_text.set("ElementView elements NOT found") self.start_button.config(state=DISABLED) def start_script(self): self.save_spectra() def save_spectra(self): acquisition_mode = self.acquisition_mode.get() safe_acquisition = not self.fast_acquisition.get() overwrite = self.overwrite.get() if self.fast_acquisition.get(): Timings.Fast() Timings.window_find_timeout = 2 if acquisition_mode == ACQUISITION_MODE_MANUAL: self.results_text.set("Manual save") if acquisition_mode == ACQUISITION_MODE_LIVE: self.results_text.set("Live save") app = Application(backend="win32").connect( path=self.program_path.get()) logger.info("Application connected") top_window = app.window(title_re=".*ElementsView.*") if safe_acquisition: top_window.wait("exists enabled visible ready") for spectrum_id in range(1, self.number_spectra.get() + 1): logger.info("Spectrum id: {:d}".format(spectrum_id)) if safe_acquisition: top_window.wait("exists enabled visible ready") if acquisition_mode == ACQUISITION_MODE_MANUAL: top_window.Button2.click() time.sleep(self.delay_spectrum_s.get()) if safe_acquisition: top_window.wait("exists enabled visible ready") top_window.menu_select("File -> Save") if safe_acquisition: app.Comment.wait("exists enabled visible ready") app.CommentEdit.Edit.SetEditText("auto script") app.Comment.OK.click() save_as_window = app['Save As'] if safe_acquisition: save_as_window.wait("exists enabled visible ready") file_name = "%s_%i.elv" % (self.basename.get(), spectrum_id) save_as_window.Edit.SetEditText(file_name) save_as_window.Save.click() if overwrite: try: window_confirm = app['Confirm Save As'] if safe_acquisition: window_confirm.wait("exists enabled visible ready") if self.overwrite.get(): window_confirm.Yes.click() else: window_confirm.No.click() save_as_window.Cancel.click() self.results_text.set("Cancel save file already exist") return except Exception as message: logger.error(message) logger.info("Done") self.results_text.set("Done")
class App: def __init__(self, master): self.initDone = False self.initGuiData() self.master = master self.master.title("Hot wire cutter (version 0.1.f)") self.nb = ttk.Notebook(self.master) self.nb.enable_traversal() self.queueTkSendMsg = queue.Queue() self._thread_cmd = threading.Thread(target=self.execCmd, args=(self.queueTkSendMsg, "rien")) self._thread_cmd.setDaemon( True ) #added by mstrens in order to kill automatically the thread when program close self._thread_cmd.start() self.queueTkGetMsg = queue.Queue() self.tGrbl = Grbl( self.nb, self, self.queueTkGetMsg ) #create an instance of Gerbil in order to communicate with GRBL # queue is used to get message back from interface self.tProfil = Profil(self.nb, self) #add a tab for selecting the profile self.tTransform = Transform(self.nb, self) #add a tab to modify the profile self.tBloc = Bloc(self.nb, self) #add a tab to design the wing and the bloc self.tMargin = Margin(self.nb, self) #add a tab to design the vertical margin self.tMaterial = Material(self.nb, self) #add a tab to specify the material self.tGuillotine = Guillotine( self.nb, self, self.queueTkSendMsg) #add a tab to make guillotine self.tCut = Cut(self.nb, self) #add a tab to cut self.tTable = Table(self.nb, self) #add a tab to define the Table (size) self.nb.pack() atexit.register(self.tGrbl.disconnectToGrbl) self.initDone = True self.running = True self.periodicCall() self.validateAllOn = True self.validateAll(0) #validate all #self.tBloc.toTableRight.set(self.tTable.dY.get() - self.tTable.lG.get() - self.tTable.lD.get() - self.tBloc.toTableLeft.get() - self.tBloc.lX.get() ) #print (self.tBloc.toTableRight.get()) def execCmd(self, queue, rien): """ thread in order to execute task outside the main tkhtread (when they can take to much time e.g.) get Cmd via a queue queueTkSendMsg used e.g. when a button is clicked in Thinker not sure it is really requested for this application """ while True: msg = queue.get() if msg == "Connect": self.tGrbl.connectToGrbl() self.tGuillotine.updateBtnState() elif msg == "Disconnect": self.tGrbl.disconnectToGrbl() self.tGuillotine.updateBtnState() def processIncoming(self): """Handle all messages currently in the queue, if any.""" while self.queueTkGetMsg.qsize(): try: msg = self.queueTkGetMsg.get(0) + "\n" # Check contents of message and do whatever is needed. As a # simple test, print it (in real life, you would # suitably update the GUI's display in a richer fashion). #print("getting a message in queue",msg) self.tGuillotine.msgBox.insert(END, msg) except queue.Empty: # just on general principles, although we don't # expect this branch to be taken in this case pass def periodicCall(self): """ Check every 200 ms if there is something new in the queue. execute it when tkinter is sleeping """ self.processIncoming() if not self.running: # This is the brutal stop of the system. You may want to do # some cleanup before actually shutting it down. #import sys #sys.exit(1) pass self.master.after(200, self.periodicCall) #def calback(self, a , b, c): # print("do something") def initGuiData(self): #not saved with config self.validateAllOn = False self.warningMsg = StringVar(value="") self.cutMsg = StringVar(value="") self.limMinX = DoubleVar( value='0.0') # min value to plot on X axis (not saved in .ini) self.limMinY = DoubleVar( value='0.0') # min value to plot on Y axis (not saved in .ini) self.zoom = StringVar(value="1X") #self.zoom.trace('w', self.calback) self.configUploadFileName = None self.tableUploadFileName = None self.tableSaveFileName = None self.materialUploadFileName = None self.materialSaveFileName = None self.connected = StringVar(value="OFF") self.grblStatus = StringVar(value="Not connected") self.grblXG = DoubleVar(value="0") #grbl horizontal left pos self.grblYG = DoubleVar(value="0") #grbl vertical left pos self.grblXD = DoubleVar(value="0") #grbl horizontal right pos self.grblYD = DoubleVar(value="0") #grbl vertical right pos self.grblF = DoubleVar(value="0") #grbl feed rate self.grblS = DoubleVar(value="0") #grbl heating self.gMoveAxis = StringVar( value="Both") # grbl axis to move (left,right) self.gMoveDist = DoubleVar(value="10") #grbl mistance to move # Transformed profil based on original (filled by validateTransform) ; is an numpy array and not a usual List #take care of Chord, but not of position of block and margins... self.tRootX = np.array([]) self.tRootY = np.array([]) self.tRootS = [] self.tTipX = np.array([]) self.tTipY = np.array([]) self.tTipS = [] # Position profil (in a numpy array) based on "t" profile and position of block and margins... self.pRootX = np.array([]) self.pRootY = np.array([]) self.pRootS = [] self.pTipX = np.array([]) self.pTipY = np.array([]) self.pTipS = [] #guillotine self.gVSpeedNoCut = DoubleVar(value='5') self.gHSpeedNoCut = DoubleVar(value='5') self.gCuttingSpeed = DoubleVar(value='5') self.gApplyCalculatedHeating = IntVar(value='1') self.gHeating = DoubleVar(value='50') self.gType = StringVar(value="Vertical") self.gCuttingWhile = StringVar(value="Both") #self.gHeatWhileArming = IntVar(value='1') self.gVDist = DoubleVar(value='10') self.gHDist = DoubleVar(value='10') #saved in config #profil self.oRootX = [ ] # original profil : usual python List ; saved in the files self.oRootY = [] self.oRootS = [] # synchro points self.oTipX = [] self.oTipY = [] self.oTipS = [] self.nameRoot = StringVar(value="") self.nameTip = StringVar(value="") #transform self.cRoot = DoubleVar(value='200.0') #chord self.cTip = DoubleVar(value='150.0') #chord self.incidenceRoot = DoubleVar(value='0.0') self.thicknessRoot = DoubleVar(value='100.0') self.vInvertRoot = IntVar(value='0') self.incidenceTip = DoubleVar(value='0.0') self.thicknessTip = DoubleVar(value='100.0') self.vInvertTip = IntVar(value='0') self.covering = DoubleVar(value='0.0') self.keepChord = IntVar(value='0') self.smooth = IntVar(value='0') self.nbrPoints = IntVar(value='50') self.repartition = DoubleVar(value='2.0') self.reducePoints = IntVar(value='0') #bloc self.blocLX = DoubleVar(value='600.0') #Length = envergure self.blocHZ = DoubleVar(value='50.0') #height of the bloc self.fLeading = DoubleVar(value='10.0') #fleche self.fTrailing = DoubleVar( value='-30' ) #self.cRoot.get() - self.cTip.get() - self.fLeading.get()) #calculated self.mLeading = DoubleVar(value='5.0') self.mTrailingRoot = DoubleVar(value='10.0') self.mTrailingTip = DoubleVar(value='10.0') self.leftRightWing = StringVar(value='Left') self.blocPosition = StringVar(value='Left') #Left or Right position self.blocToTableLeft = DoubleVar( value='100.0') #calculated but depend on bloc position self.blocToTableRight = DoubleVar( value='10.0') #calculated but depend on bloc position self.blocToTableTrailingRoot = IntVar(value='50') self.blocToTableTrailingTip = IntVar(value='50') #calculated self.blocToTableLeadingRoot = IntVar(value='50') #calculated self.blocToTableLeadingTip = IntVar(value='50') #calculated #margin self.hTrailingRoot = DoubleVar(value='10.0') self.hTrailingTip = DoubleVar(value='10.0') #calculated self.hLeadingRoot = DoubleVar(value='10.0') #calculated self.hLeadingTip = DoubleVar(value='10.0') #calculated self.hMaxRoot = DoubleVar(value='10.0') #calculated self.hMaxTip = DoubleVar(value='10.0') #calculated self.hMinRoot = DoubleVar(value='10.0') #calculated self.hMinTip = DoubleVar(value='10.0') #calculated self.hOffset = DoubleVar(value='10.0') #heigh of the base of the bloc self.alignProfil = StringVar(value="Trailing") self.hProfil = DoubleVar( value='20.0') #heigh of the profile in the bloc self.angleInRoot = DoubleVar(value='0.0') self.angleInTip = DoubleVar(value='0.0') self.angleOutRoot = DoubleVar(value='0.0') self.angleOutTip = DoubleVar(value='0.0') """ self.hMaxRootNorm = 0 self.hMinRootNorm = 0 self.hLeadingRootNorm = 0 self.hMaxTipNorm = 0 self.hMinTipNorm = 0 self.hLeadingTipNorm = 0 """ #Material self.mSpeedHigh = DoubleVar(value='10.0') #speed max self.mSpeedHalf = DoubleVar(value='5.0') #speed min self.mSpeedLow = DoubleVar(value='1.0') #speed min self.mRadSpHigh = DoubleVar(value='0.9') #Radiance at high max self.mRadSpHalf = DoubleVar(value='1.5') #Radiance at half speed self.mHeatSpHigh = IntVar(value='90') #Heat at High speed self.mHeatSpLow = IntVar(value='40') #Heat at low speed self.mName = StringVar(value="No material name") #table self.tableYY = DoubleVar(value='1000.0') # distance between 2 axis self.tableYG = DoubleVar( value='20.0') #distance between left Y axis and left table edge self.tableYD = DoubleVar(value='20.0') # same on the rigth side self.cMaxY = DoubleVar(value='500.0') # max course in Y self.cMaxZ = DoubleVar(value='200.0') # max course in Z (height) self.vMaxY = DoubleVar(value='10.0') # max speed in Y self.vMaxZ = DoubleVar(value='5.0') # max speed in Z (height) self.tHeatingMax = DoubleVar(value='100.0') # max heating self.tName = StringVar(value="No table name") #self.tComPort = StringVar(value="Select a Com port") self.tComPort = StringVar(value="COM6") self.tBaudrate = StringVar(value="115200") self.tPreHeat = DoubleVar(value='5.0') # delay between Heat and move self.tPostHeat = DoubleVar(value='5.0') # delay between Move and Heat #cut self.vCut = DoubleVar( value='2.0' ) # max speed for cutting (on root or tip depending the longest) self.gCodeStart1 = StringVar(value="") self.gCodeStart2 = StringVar(value="") self.gCodeStart3 = StringVar(value="") self.gCodeStart4 = StringVar(value="") self.gCodeEnd1 = StringVar(value="") self.gCodeEnd2 = StringVar(value="") self.gCodeEnd3 = StringVar(value="") self.gCodeEnd4 = StringVar(value="") self.gCodeLetters = StringVar(value="XYZA") #self.validatePart() def uploadConfig(self): #global configUploadFileName #configUploadFileName = filedialog.askopenfilename(initialdir="C:/Data/", self.configUploadFileName = filedialog.askopenfilename(\ filetypes =(("Ini files", "*.ini"),("All files","*.*")), title = "Choose a file." ) if len(self.configUploadFileName) > 0: self.validateAllOn = False #config.read('config.ini') config = configparser.ConfigParser() config.add_section("Profil") config.add_section("Transform") config.add_section("Bloc") config.add_section("Material") config.add_section("Table") config.add_section("Cut") config.add_section("Guillotine") config.read(self.configUploadFileName) self.oRootX = stringToListOfFloat(config.get("Profil", "RootX")) self.oRootY = stringToListOfFloat(config.get("Profil", "RootY")) self.oRootS = stringToListOfFloat(config.get("Profil", "RootS")) self.oTipX = stringToListOfFloat(config.get("Profil", "TipX")) self.oTipY = stringToListOfFloat(config.get("Profil", "TipY")) self.oTipS = stringToListOfFloat(config.get("Profil", "TipS")) self.nameRoot.set(value=config.get("Profil", "nameRoot")) self.nameTip.set(value=config.get("Profil", "nameTip")) self.cRoot.set(value=config.getfloat("Transform", "cRoot")) self.cTip.set(value=config.getfloat("Transform", "cTip")) self.incidenceRoot.set( value=config.getfloat("Transform", "incidenceRoot")) self.thicknessRoot.set( value=config.getfloat("Transform", "thicknessRoot")) self.vInvertRoot.set( value=config.getint("Transform", "vInvertRoot")) self.incidenceTip.set( value=config.getfloat("Transform", "incidenceTip")) self.thicknessTip.set( value=config.getfloat("Transform", "thicknessTip")) self.vInvertTip.set(value=config.getint("Transform", "vInvertTip")) self.covering.set(value=config.getfloat("Transform", "covering")) self.keepChord.set(value=config.getint("Transform", "keepChord")) self.smooth.set(value=config.getint("Transform", "smooth")) self.nbrPoints.set(value=config.getint("Transform", "nbrPoints")) self.repartition.set( value=config.getfloat("Transform", "repartition")) self.reducePoints.set( value=config.getint("Transform", "reducePoints")) self.blocLX.set(value=config.getfloat("Bloc", "blocLX")) self.blocHZ.set(value=config.getfloat("Bloc", "blocHZ")) self.fLeading.set(value=config.getfloat("Bloc", "fLeading")) self.mLeading.set(value=config.getfloat("Bloc", "mLeading")) self.mTrailingRoot.set( value=config.getfloat("Bloc", "mTrailingRoot")) self.mTrailingTip.set( value=config.getfloat("Bloc", "mTrailingTip")) self.leftRightWing.set(value=config.get("Bloc", "leftRightWing")) self.blocPosition.set(value=config.get("Bloc", "blocPosition")) self.blocToTableLeft.set( value=config.getfloat("Bloc", "blocToTableLeft")) self.blocToTableRight.set( value=config.getfloat("Bloc", "blocToTableRight")) self.blocToTableTrailingRoot.set( value=config.getint("Bloc", "blocToTableTrailingRoot")) self.blocToTableTrailingTip.set( value=config.getint("Bloc", "blocToTableTrailingTip")) self.blocToTableLeadingRoot.set( value=config.getint("Bloc", "blocToTableLeadingRoot")) self.blocToTableLeadingTip.set( value=config.getint("Bloc", "blocToTableLeadingTip")) self.hTrailingRoot.set( value=config.getfloat("Bloc", "hTrailingRoot")) self.hTrailingTip.set( value=config.getfloat("Bloc", "hTrailingTip")) self.hLeadingRoot.set( value=config.getfloat("Bloc", "hLeadingRoot")) self.hLeadingTip.set(value=config.getfloat("Bloc", "hLeadingTip")) self.hMaxRoot.set(value=config.getfloat("Bloc", "hMaxRoot")) self.hMaxTip.set(value=config.getfloat("Bloc", "hMaxTip")) self.hMinRoot.set(value=config.getfloat("Bloc", "hMinRoot")) self.hMinTip.set(value=config.getfloat("Bloc", "hMinTip")) self.hOffset.set(value=config.getfloat("Bloc", "hOffset")) self.alignProfil.set(value=config.get("Bloc", "alignProfil")) self.hProfil.set(value=config.get("Bloc", "hProfil")) try: self.angleInRoot.set( value=config.getfloat("Bloc", "angleInRoot")) self.angleInTip.set( value=config.getfloat("Bloc", "angleInTip")) self.angleOutRoot.set( value=config.getfloat("Bloc", "angleOutRoot")) self.angleOutTip.set( value=config.getfloat("Bloc", "angleOutTip")) except: pass """ self.hMaxRootNorm = config.get("Bloc", "hMaxRootNorm") self.hMinRootNorm = config.get("Bloc", "hMinRootNorm") self.hLeadingRootNorm = config.get("Bloc", "hLeadingRootNorm") self.hMaxTipNorm = config.get("Bloc", "hMaxTipNorm") self.hMinTipNorm = config.get("Bloc", "hMinTipNorm") self.hLeadingTipNorm = config.get("Bloc", "hLeadingTipNorm") """ self.mSpeedHigh.set( value=config.getfloat("Material", "mSpeedHigh")) self.mSpeedHalf.set( value=config.getfloat("Material", "mSpeedHalf")) self.mSpeedLow.set(value=config.getfloat("Material", "mSpeedLow")) self.mRadSpHigh.set( value=config.getfloat("Material", "mRadSpHigh")) self.mRadSpHalf.set( value=config.getfloat("Material", "mRadSpHalf")) self.mHeatSpHigh.set( value=config.getfloat("Material", "mHeatSpHigh")) self.mHeatSpLow.set( value=config.getfloat("Material", "mHeatSpLow")) self.mName.set(value=config.get("Material", "mName")) self.tableYY.set(value=config.getfloat("Table", "tableYY")) self.tableYG.set(value=config.getfloat("Table", "tableYG")) self.tableYD.set(value=config.getfloat("Table", "tableYD")) self.cMaxY.set(value=config.getfloat("Table", "cMaxY")) self.cMaxZ.set(value=config.getfloat("Table", "cMaxZ")) self.vMaxY.set(value=config.getfloat("Table", "vMaxY")) self.vMaxZ.set(value=config.getfloat("Table", "vMaxZ")) self.tHeatingMax.set(value=config.getfloat("Table", "tHeatingMax")) self.tName.set(value=config.get("Table", "tName")) self.tComPort.set(value=config.get("Table", "tComPort")) self.tBaudrate.set(value=config.get("Table", "tBaudrate")) self.tPreHeat.set(value=config.getfloat("Table", "tPreHeat")) self.tPostHeat.set(value=config.getfloat("Table", "tPostHeat")) self.vCut.set(value=config.getfloat("Cut", "vCut")) self.gCodeStart1.set(value=config.get("Cut", "gCodeStart1")) self.gCodeStart2.set(value=config.get("Cut", "gCodeStart2")) self.gCodeStart3.set(value=config.get("Cut", "gCodeStart3")) self.gCodeStart4.set(value=config.get("Cut", "gCodeStart4")) self.gCodeEnd1.set(value=config.get("Cut", "gCodeEnd1")) self.gCodeEnd2.set(value=config.get("Cut", "gCodeEnd2")) self.gCodeEnd3.set(value=config.get("Cut", "gCodeEnd3")) self.gCodeEnd4.set(value=config.get("Cut", "gCodeEnd4")) self.gCodeLetters.set(value=config.get("Cut", "gCodeLetters")) self.gVSpeedNoCut.set( value=config.getfloat("Guillotine", "gVSpeedNoCut")) self.gHSpeedNoCut.set( value=config.getfloat("Guillotine", "gHSpeedNoCut")) self.gCuttingSpeed.set( value=config.getfloat("Guillotine", "gCuttingSpeed")) self.gApplyCalculatedHeating.set( value=config.getint("Guillotine", "gApplyCalculatedHeating")) self.gHeating.set(value=config.getfloat("Guillotine", "gHeating")) self.gType.set(value=config.get("Guillotine", "gType")) self.gCuttingWhile.set( value=config.get("Guillotine", "gCuttingWhile")) self.gVDist.set(value=config.getfloat("Guillotine", "gVDist")) self.gHDist.set(value=config.getfloat("Guillotine", "gHDist")) """ x ,y , self.hMaxRootNorm, self.hMinRootNorm , self.hLeadingRootNorm = self.normaliseProfil( self.oRootX, self.oRootY, self.cRoot.get(), 0, 0) x ,y , self.hMaxTipNorm, self.hMinTipNorm , self.hLeadingTipNorm = self.normaliseProfil( self.oTipX, self.oTipY, self.cTip.get(), 0, 0) """ self.validateAllOn = True self.validateAll(0) self.tProfil.updatePlotRoot() self.tProfil.updatePlotTip() def uploadTable(self): self.tableUploadFileName = filedialog.askopenfilename(\ filetypes =(("Table files", "*.tab"),("All files","*.*")), title = "Choose a file to upload a table." ) if len(self.tableUploadFileName) > 0: #config.read('config.ini') config = configparser.ConfigParser() config.add_section("Table") config.add_section("Cut") config.read(self.tableUploadFileName) self.tableYY.set(value=config.getfloat("Table", "tableYY")) self.tableYG.set(value=config.getfloat("Table", "tableYG")) self.tableYD.set(value=config.getfloat("Table", "tableYD")) self.cMaxY.set(value=config.getfloat("Table", "cMaxY")) self.cMaxZ.set(value=config.getfloat("Table", "cMaxZ")) self.vMaxY.set(value=config.getfloat("Table", "vMaxY")) self.vMaxZ.set(value=config.getfloat("Table", "vMaxZ")) self.tHeatingMax.set(value=config.getfloat("Table", "tHeatingMax")) self.tName.set(value=config.get("Table", "tName")) self.tComPort.set(value=config.get("Table", "tComPort")) self.tBaudrate.set(value=config.get("Table", "tBaudrate")) self.tPreHeat.set(value=config.getfloat("Table", "tPreHeat")) self.tPostHeat.set(value=config.getfloat("Table", "tPostHeat")) self.vCut.set(value=config.getfloat("Cut", "vCut")) self.gCodeStart1.set(value=config.get("Cut", "gCodeStart1")) self.gCodeStart2.set(value=config.get("Cut", "gCodeStart2")) self.gCodeStart3.set(value=config.get("Cut", "gCodeStart3")) self.gCodeStart4.set(value=config.get("Cut", "gCodeStart4")) self.gCodeEnd1.set(value=config.get("Cut", "gCodeEnd1")) self.gCodeEnd2.set(value=config.get("Cut", "gCodeEnd2")) self.gCodeEnd3.set(value=config.get("Cut", "gCodeEnd3")) self.gCodeEnd4.set(value=config.get("Cut", "gCodeEnd4")) self.gCodeLetters.set(value=config.get("Cut", "gCodeLetters")) self.validateAll( 20) # recalculate and redraw bloc, margin and after def uploadMaterial(self): self.materialUploadFileName = filedialog.askopenfilename(\ filetypes =(("Material", "*.mat"),("All files","*.*")), title = "Choose a file to upload a material" ) if len(self.materialUploadFileName) > 0: #config.read('config.ini') config = configparser.ConfigParser() config.add_section("Material") config.read(self.materialUploadFileName) self.mSpeedHigh.set( value=config.getfloat("Material", "mSpeedHigh")) self.mSpeedHalf.set( value=config.getfloat("Material", "mSpeedHalf")) self.mSpeedLow.set(value=config.getfloat("Material", "mSpeedLow")) self.mRadSpHigh.set( value=config.getfloat("Material", "mRadSpHigh")) self.mRadSpHalf.set( value=config.getfloat("Material", "mRadSpHalf")) self.mHeatSpHigh.set( value=config.getfloat("Material", "mHeatSpHigh")) self.mHeatSpLow.set( value=config.getfloat("Material", "mHeatSpLow")) self.mName.set(value=config.get("Material", "mName")) self.validateAll(30) # recalculate and redraw cutting def saveConfig(self): config = configparser.ConfigParser() config.add_section("Profil") config.add_section("Transform") config.add_section("Bloc") config.add_section("Material") config.add_section("Table") config.add_section("Cut") config.add_section("Guillotine") #save all paramaters config.set( "Profil", "RootX", str('[{:s}]'.format(', '.join( ['{}'.format(x) for x in self.oRootX])))) config.set( "Profil", "RootY", str('[{:s}]'.format(', '.join( ['{}'.format(x) for x in self.oRootY])))) config.set( "Profil", "RootS", str('[{:s}]'.format(', '.join( ['{}'.format(x) for x in self.oRootS])))) config.set( "Profil", "TipX", str('[{:s}]'.format(', '.join(['{}'.format(x) for x in self.oTipX])))) config.set( "Profil", "TipY", str('[{:s}]'.format(', '.join(['{}'.format(x) for x in self.oTipY])))) config.set( "Profil", "TipS", str('[{:s}]'.format(', '.join(['{}'.format(x) for x in self.oTipS])))) config.set("Profil", "nameRoot", self.nameRoot.get()) config.set("Profil", "nameTip", self.nameTip.get()) config.set("Transform", "cRoot", str(self.cRoot.get())) config.set("Transform", "cTip", str(self.cTip.get())) config.set("Transform", "incidenceRoot", str(self.incidenceRoot.get())) config.set("Transform", "thicknessRoot", str(self.thicknessRoot.get())) config.set("Transform", "vInvertRoot", str(self.vInvertRoot.get())) config.set("Transform", "incidenceTip", str(self.incidenceTip.get())) config.set("Transform", "thicknessTip", str(self.thicknessTip.get())) config.set("Transform", "vInvertTip", str(self.vInvertTip.get())) config.set("Transform", "covering", str(self.covering.get())) config.set("Transform", "keepChord", str(self.keepChord.get())) config.set("Transform", "smooth", str(self.smooth.get())) config.set("Transform", "nbrPoints", str(self.nbrPoints.get())) config.set("Transform", "repartition", str(self.repartition.get())) config.set("Transform", "reducePoints", str(self.reducePoints.get())) config.set("Bloc", "blocLX", str(self.blocLX.get())) config.set("Bloc", "blocHZ", str(self.blocHZ.get())) config.set("Bloc", "fLeading", str(self.fLeading.get())) config.set("Bloc", "fTrailing", str(self.fTrailing.get())) config.set("Bloc", "mLeading", str(self.mLeading.get())) config.set("Bloc", "mTrailingRoot", str(self.mTrailingRoot.get())) config.set("Bloc", "mTrailingTip", str(self.mTrailingTip.get())) config.set("Bloc", "leftRightWing", self.leftRightWing.get()) config.set("Bloc", "blocPosition", self.blocPosition.get()) config.set("Bloc", "blocToTableLeft", str(self.blocToTableLeft.get())) config.set("Bloc", "blocToTableRight", str(self.blocToTableRight.get())) config.set("Bloc", "blocToTableTrailingRoot", str(self.blocToTableTrailingRoot.get())) config.set("Bloc", "blocToTableTrailingTip", str(self.blocToTableTrailingTip.get())) config.set("Bloc", "blocToTableLeadingRoot", str(self.blocToTableLeadingRoot.get())) config.set("Bloc", "blocToTableLeadingTip", str(self.blocToTableLeadingTip.get())) config.set("Bloc", "hTrailingRoot", str(self.hTrailingRoot.get())) config.set("Bloc", "hTrailingTip", str(self.hTrailingTip.get())) config.set("Bloc", "hLeadingRoot", str(self.hLeadingRoot.get())) config.set("Bloc", "hLeadingTip", str(self.hLeadingTip.get())) config.set("Bloc", "hMaxRoot", str(self.hMaxRoot.get())) config.set("Bloc", "hMaxTip", str(self.hMaxTip.get())) config.set("Bloc", "hMinRoot", str(self.hMinRoot.get())) config.set("Bloc", "hMinTip", str(self.hMinTip.get())) config.set("Bloc", "hOffset", str(self.hOffset.get())) config.set("Bloc", "alignProfil", self.alignProfil.get()) config.set("Bloc", "hProfil", str(self.hProfil.get())) config.set("Bloc", "angleInRoot", str(self.angleInRoot.get())) config.set("Bloc", "angleInTip", str(self.angleInTip.get())) config.set("Bloc", "angleOutRoot", str(self.angleOutRoot.get())) config.set("Bloc", "angleOutTip", str(self.angleOutTip.get())) config.set("Material", "mSpeedHigh", str(self.mSpeedHigh.get())) config.set("Material", "mSpeedHalf", str(self.mSpeedHalf.get())) config.set("Material", "mSpeedLow", str(self.mSpeedLow.get())) config.set("Material", "mRadSpHigh", str(self.mRadSpHigh.get())) config.set("Material", "mRadSpHalf", str(self.mRadSpHalf.get())) config.set("Material", "mHeatSpHigh", str(self.mHeatSpHigh.get())) config.set("Material", "mHeatSpLow", str(self.mHeatSpLow.get())) config.set("Material", "mName", self.mName.get()) config.set("Table", "tableYY", str(self.tableYY.get())) config.set("Table", "tableYG", str(self.tableYG.get())) config.set("Table", "tableYD", str(self.tableYD.get())) config.set("Table", "cMaxY", str(self.cMaxY.get())) config.set("Table", "cMaxZ", str(self.cMaxZ.get())) config.set("Table", "vMaxY", str(self.vMaxY.get())) config.set("Table", "vMaxZ", str(self.vMaxZ.get())) config.set("Table", "tHeatingMax", str(self.tHeatingMax.get())) config.set("Table", "tName", self.tName.get()) config.set("Table", "tComPort", self.tComPort.get()) config.set("Table", "tBaudrate", self.tBaudrate.get()) config.set("Table", "tPreHeat", str(self.tPreHeat.get())) config.set("Table", "tPostHeat", str(self.tPostHeat.get())) config.set("Cut", "vCut", str(self.vCut.get())) config.set("Cut", "gCodeStart1", self.gCodeStart1.get()) config.set("Cut", "gCodeStart2", self.gCodeStart2.get()) config.set("Cut", "gCodeStart3", self.gCodeStart3.get()) config.set("Cut", "gCodeStart4", self.gCodeStart4.get()) config.set("Cut", "gCodeEnd1", self.gCodeEnd1.get()) config.set("Cut", "gCodeEnd2", self.gCodeEnd2.get()) config.set("Cut", "gCodeEnd3", self.gCodeEnd3.get()) config.set("Cut", "gCodeEnd4", self.gCodeEnd4.get()) config.set("Cut", "gCodeLetters", self.gCodeLetters.get()) config.set("Guillotine", "gVSpeedNoCut", str(self.gVSpeedNoCut.get())) config.set("Guillotine", "gHSpeedNoCut", str(self.gHSpeedNoCut.get())) config.set("Guillotine", "gCuttingSpeed", str(self.gCuttingSpeed.get())) config.set("Guillotine", "gApplyCalculatedHeating", str(self.gApplyCalculatedHeating.get())) config.set("Guillotine", "gHeating", str(self.gHeating.get())) config.set("Guillotine", "gType", self.gType.get()) config.set("Guillotine", "gCuttingWhile", self.gCuttingWhile.get()) config.set("Guillotine", "gVDist", str(self.gVDist.get())) config.set("Guillotine", "gHDist", str(self.gHDist.get())) configSaveFileName = filedialog.asksaveasfilename(title="Save as...", defaultextension="*.ini",\ filetypes=[("Ini files","*.ini"),("All files", "*")], initialfile=self.configUploadFileName) if len(configSaveFileName) > 0: config.write(open(configSaveFileName, 'w')) def saveTable(self): config = configparser.ConfigParser() config.add_section("Table") config.add_section("Cut") config.set("Table", "tableYY", str(self.tableYY.get())) config.set("Table", "tableYG", str(self.tableYG.get())) config.set("Table", "tableYD", str(self.tableYD.get())) config.set("Table", "cMaxY", str(self.cMaxY.get())) config.set("Table", "cMaxZ", str(self.cMaxZ.get())) config.set("Table", "vMaxY", str(self.vMaxY.get())) config.set("Table", "vMaxZ", str(self.vMaxZ.get())) config.set("Table", "tHeatingMax", str(self.tHeatingMax.get())) config.set("Table", "tName", self.tName.get()) config.set("Table", "tComPort", self.tComPort.get()) config.set("Table", "tBaudrate", self.tBaudrate.get()) config.set("Table", "tPreHeat", str(self.tPreHeat.get())) config.set("Table", "tPostHeat", str(self.tPostHeat.get())) config.set("Cut", "vCut", str(self.vCut.get())) config.set("Cut", "gCodeStart1", self.gCodeStart1.get()) config.set("Cut", "gCodeStart2", self.gCodeStart2.get()) config.set("Cut", "gCodeStart3", self.gCodeStart3.get()) config.set("Cut", "gCodeStart4", self.gCodeStart4.get()) config.set("Cut", "gCodeEnd1", self.gCodeEnd1.get()) config.set("Cut", "gCodeEnd2", self.gCodeEnd2.get()) config.set("Cut", "gCodeEnd3", self.gCodeEnd3.get()) config.set("Cut", "gCodeEnd4", self.gCodeEnd4.get()) config.set("Cut", "gCodeLetters", self.gCodeLetters.get()) if self.tableSaveFileName == None: self.tableSaveFileName = self.tableUploadFileName self.tableSaveFileName = filedialog.asksaveasfilename(title="Save table as...", defaultextension="*.tab",\ filetypes=[("Table files","*.tab"),("All files", "*")], initialfile=self.tableSaveFileName) if len(self.tableSaveFileName) > 0: config.write(open(self.tableSaveFileName, 'w')) def saveMaterial(self): config = configparser.ConfigParser() config.add_section("Material") config.set("Material", "mSpeedHigh", str(self.mSpeedHigh.get())) config.set("Material", "mSpeedHalf", str(self.mSpeedHalf.get())) config.set("Material", "mSpeedLow", str(self.mSpeedLow.get())) config.set("Material", "mRadSpHigh", str(self.mRadSpHigh.get())) config.set("Material", "mRadSpHalf", str(self.mRadSpHalf.get())) config.set("Material", "mHeatSpHigh", str(self.mHeatSpHigh.get())) config.set("Material", "mHeatSpLow", str(self.mHeatSpLow.get())) config.set("Material", "mName", self.mName.get()) if self.materialSaveFileName == None: self.materialSaveFileName = self.materialUploadFileName self.materialSaveFileName = filedialog.asksaveasfilename(title="Save material as...", defaultextension="*.material",\ filetypes=[("Material files","*.material"),("All files", "*")], initialfile=self.materialSaveFileName) if len(self.materialSaveFileName) > 0: config.write(open(self.materialSaveFileName, 'w')) def validatePart(self): self.fTrailing.set(-(self.cRoot.get() - self.cTip.get() - self.fLeading.get())) if self.blocPosition.get() == "Left": self.tBloc.blocToTableRightBox[ 'validate'] = 'none' # disable validate, otherwise we call validate inside validate self.blocToTableRight.set(self.tableYY.get() - self.tableYG.get() - self.tableYD.get() - self.blocToTableLeft.get() - self.blocLX.get()) self.tBloc.blocToTableRightBox[ 'validate'] = 'focusout' #enable after the update else: self.tBloc.blocToTableRightBox[ 'validate'] = 'none' # disable validate, otherwise we call validate inside validate self.blocToTableLeft.set(self.tableYY.get() - self.tableYG.get() - self.tableYD.get() - self.blocToTableRight.get() - self.blocLX.get()) self.tBloc.blocToTableRightBox['validate'] = 'focusout' self.blocToTableTrailingTip.set(self.blocToTableTrailingRoot.get() - self.fTrailing.get()) self.blocToTableLeadingRoot.set(self.blocToTableTrailingRoot.get() + self.cRoot.get() + self.mTrailingRoot.get() + self.mLeading.get()) self.blocToTableLeadingTip.set(self.blocToTableTrailingTip.get() + self.cTip.get() + self.mTrailingTip.get() + self.mLeading.get()) #self.mSpeedHalf.set(self.mSpeedHigh.get() / 2) #half speed = high speed /2 def validateAll(self, level): # level is used to avoid to recalculate some data when not needed # 0 = calculate all (original profil change) # 10 = calculate Transform and after (Transform profil: chord, incidence...) # 20 = calculate Bloc/margin and after (change table or bloc position) # 30 = calculate cutting (change speed, material) if self.initDone and self.validateAllOn: #avoid validate during the set up of tkinter widgets and when validateAll is disabled #try: if level == 0: self.tProfil.updatePlotRoot() self.tProfil.updatePlotTip() if level <= 10: #create tRoot and tTipX based on oRoot and oTip and chords but not based on bloc and margin # draw the view in Transform (= tRoot and tTip) if (len(self.oRootX) > 0) and (len(self.oTipX) > 0): #create tRoot and tTipX based on oRoot and oTip and chords but not based on bloc and margin self.tTransform.validateTransform() self.tTransform.updatePlotRoot() self.tTransform.updatePlotTip() if level <= 20: pass #create pRoot and pTipX based on tRoot and tTip and based on Table, bloc and margin self.validatePart() #print("validatePart is done") self.calculatePositions() #print("calculatepositions is done") # draw the bloc () self.tBloc.updatePlotBloc() #print("updatePlotBloc is done") #draw the margins self.tMargin.updatePlotMargin() #print("updatePlotMargin is done") #update heating for guillotine self.tGuillotine.updateGuillotineHeating() #print("updateGuillotineHeating is done") if level <= 30: # calculate Cut based on Material self.mSpeedHalf.set(self.mSpeedHigh.get() / 2) #half speed = high speed /2 if (len(self.pRootX) > 0) and (len(self.pTipX) > 0): pass #print("begin calculateRedraw") self.tCut.calculateRedraw() #print("end calculateRedraw") warningMsg = "" if (len(self.oRootX) <= 1) and (len(self.oTipX) <= 1): warningMsg = "Root and Tip profiles missing" elif len(self.oRootX) <= 1: warningMsg = "Root profile missing" elif len(self.oTipX) <= 1: warningMsg = "Tip profile missing" elif (self.tRootS.count(4) + self.tRootS.count(10)) != ( self.tTipS.count(4) + self.tTipS.count(10)): warningMsg = "Transformed root and tip profiles must have the same number of synchro points" self.warningMsg.set(warningMsg) #next 2 lines are normally as comment #except: return True def calculatePositions(self): #create bRoot and bTipX based on tRoot and tTip and based on bloc and margin #calculate Root and Tip offset to apply if (len(self.tRootX) > 0) and (len( self.tTipX) > 0): # and (len(self.tRootX) == len(self.tTipX)): #calculate relative height of max, min leading hMaxRootNorm, hMinRootNorm, hLeadingRootNorm = self.calculateRelativeHeigths( self.tRootX, self.tRootY) hMaxTipNorm, hMinTipNorm, hLeadingTipNorm = self.calculateRelativeHeigths( self.tTipX, self.tTipY) #Apply vertical aligment if self.alignProfil.get() == "Trailing": self.hTrailingRoot.set(self.hProfil.get()) self.hTrailingTip.set(self.hProfil.get()) elif self.alignProfil.get() == "Leading": self.hTrailingRoot.set(self.hProfil.get() - hLeadingRootNorm) self.hTrailingTip.set(self.hProfil.get() - hLeadingTipNorm) elif self.alignProfil.get() == "Extrados": self.hTrailingRoot.set(self.hProfil.get() - hMaxRootNorm) self.hTrailingTip.set(self.hProfil.get() - hMaxTipNorm) elif self.alignProfil.get() == "Intrados": self.hTrailingRoot.set(self.hProfil.get() - hMinRootNorm) self.hTrailingTip.set(self.hProfil.get() - hMinTipNorm) self.hLeadingRoot.set(self.hTrailingRoot.get() + hLeadingRootNorm) self.hLeadingTip.set(self.hTrailingTip.get() + hLeadingTipNorm) self.hMaxRoot.set(self.blocHZ.get() - self.hTrailingRoot.get() - hMaxRootNorm) self.hMaxTip.set(self.blocHZ.get() - self.hTrailingTip.get() - hMaxTipNorm) self.hMinRoot.set(self.hTrailingRoot.get() + hMinRootNorm) self.hMinTip.set(self.hTrailingTip.get() + hMinTipNorm) #apply offsets self.pRootX = self.tRootX + self.blocToTableTrailingRoot.get( ) + self.mTrailingRoot.get() self.pTipX = self.tTipX + self.blocToTableTrailingTip.get( ) + self.mTrailingTip.get() self.pRootY = self.tRootY + self.hOffset.get( ) + self.hTrailingRoot.get() self.pTipY = self.tTipY + self.hOffset.get( ) + self.hTrailingRoot.get() self.pRootS = list(self.tRootS) #create list of synchro self.pTipS = list(self.tTipS) #create list of synchro """ def validateFloat(self, reason, val , name , old, min , max): if reason == "focusout": try : v = float(val) if v >= float(min) and v <= float(max): return True return True except : return False elif reason == "focusout": if float(val) > float(max): print("focus out max exceeded") return False return self.validateAll() return True """ def normaliseArrayProfil(self, aX, aY, chord): #normalise the profil with chord if len(aX) > 0: minX = np.min(aX) maxX = np.max(aX) ratio = chord / (maxX - minX) aXn = aX * ratio aXn = aXn - aXn[0] aXn = -1.0 * aXn # multiply by -1 to reverse the order aYn = aY * ratio aYn = aYn - aYn[0] return aXn, aYn """ def normaliseProfil (self , pX , pY , coord , oY, oZ): #normalise the profil with coord and offset of origin if len(pX) > 0: aX = np.array(pX) aY = np.array(pY) minX = np.min(aX) idxMin = np.where(aX == minX) #return an array with indexes maxX = np.max(aX) minY = np.min(aY) maxY = np.max(aY) ratio= coord / ( maxX - minX ) aX = aX * ratio aX = aX - aX[0] aX = -1 * aX # multiply by -1 to reverse the order aX = aX + oY aY = aY * ratio aY = aY - aY[0] aY = aY + oZ maxh = (maxY / ( maxX - minX ) ) - pY[0] minh = (minY / ( maxX - minX ) ) - pY[0] if len(idxMin) > 0 and len(idxMin[0]) > 0: r = idxMin[0][0] leadingh = (pY[r] / ( maxX - minX ) ) - pY[0] else: leadingh = 0 #print("normalised aX=", aX , "aY=", aY) return aX.tolist() , aY.tolist() ,maxh ,minh, leadingh """ def calculateRelativeHeigths(self, pX, pY): maxX = np.max(pX) idxMax = np.where(pX == maxX) #return an array with indexes minY = np.min(pY) maxY = np.max(pY) maxh = maxY - pY[0] minh = minY - pY[0] if len(idxMax) > 0 and len(idxMax[0]) > 0: r = idxMax[0][0] leadingh = pY[r] - pY[0] else: leadingh = 0 return maxh, minh, leadingh
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()
class TkMainGui(ttk.Frame): def __init__(self, root, default_folder=""): ttk.Frame.__init__(self, root, padding="3 3 12 12") self.default_folder = default_folder logging.debug("Create main frame") #mainframe = ttk.Frame(root, padding="3 3 12 12") self.grid(column=0, row=0, sticky=(N, W, E, S)) self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) logging.debug("Create variable") self.filepath_ctf = StringVar() self.image_folder = StringVar() self.vh_ratio = DoubleVar(value=0.76200) self.results_text = StringVar() self.pcx = 0.0 self.pcy = 0.0 self.dd = 0.0 logging.debug("Create ctf components") ctf_entry = ttk.Entry(self, width=80, textvariable=self.filepath_ctf) ctf_entry.grid(column=2, row=1, sticky=(W, E)) ttk.Button(self, text="Select CTF file", command=self.open_ctf_file).grid(column=3, row=1, sticky=W) logging.debug("Create image folder components") image_entry = ttk.Entry(self, width=80, textvariable=self.image_folder) image_entry.grid(column=2, row=2, sticky=(W, E)) ttk.Button(self, text="Select Image folder", command=self.open_image_folder).grid(column=3, row=2, sticky=W) logging.debug("Create vh_ratio components") ttk.Label(self, text="VH Ratio").grid(column=1, row=3, sticky=(W, E)) image_entry = ttk.Entry(self, width=10, textvariable=self.vh_ratio) image_entry.grid(column=2, row=3, sticky=(W, E)) ttk.Button(self, text="Prepare data", command=self.prepare_data, width=80).grid(column=2, row=4, sticky=W) results_label = ttk.Label(self, textvariable=self.results_text, state="readonly") results_label.grid(column=2, row=5, sticky=(W, E)) for child in self.winfo_children(): child.grid_configure(padx=5, pady=5) ctf_entry.focus() def open_ctf_file(self): logging.debug("open_ctf_file") filename = filedialog.askopenfilename(filetypes=(("CTF file", "*.ctf"), ), initialdir=self.default_folder) logging.debug(filename) self.filepath_ctf.set(filename) basename = os.path.splitext(filename)[0] if os.path.isdir(basename + "Images"): self.image_folder.set(basename + "Images") elif os.path.isdir(basename + "_Images"): self.image_folder.set(basename + "_Images") def open_image_folder(self): logging.debug("open_image_folder") folder_name = filedialog.askdirectory(initialdir=self.default_folder) logging.debug(folder_name) self.image_folder.set(folder_name) def prepare_data(self): logging.debug("prepare_data") self.find_pattern_parameters() self.create_cpr_file() self.rename_image_folder() if self.pcx == 0.0 or self.pcy == 0.0 or self.dd == 0.0 or self.vh_ratio == 0.0: self.results_text.set("Error") else: self.results_text.set("Completed") def find_pattern_parameters(self): logging.debug("find_pattern_parameters") number_files = 0 extension = "" folder_name = self.image_folder.get() for filename in sorted(os.listdir(folder_name), reverse=True): try: basename, extension = os.path.splitext(filename) items = basename.split("_") number_files = int(items[-1]) break except: pass logging.debug(number_files) logging.debug(filename) start = filename.rfind("_%i" % (number_files)) image_filename = filename[:start+1] + "%0*i" % (len(str(number_files)), number_files/2) + extension logging.debug(image_filename) image_filepath = os.path.join(folder_name, image_filename) image = Image.open(image_filepath) for items in image.tag.values(): logging.debug(items) try: root = ET.fromstring(items[0]) logging.debug(root.tag) logging.debug(root.attrib) for element in root.iter('pattern-center-x-pu'): self.pcx = float(element.text) for element in root.iter('pattern-center-y-pu'): self.pcy = float(element.text) for element in root.iter('detector-distance-pu'): self.dd = float(element.text) except (TypeError, ET.ParseError): pass def create_cpr_file(self): logging.debug("create_cpr_file") lines = [] lines.append("\n") line = "VHRatio=%.5f\n" % (self.vh_ratio.get()) lines.append(line) line = "PCX=%.17f\n" % (self.pcx) lines.append(line) line = "PCY=%.17f\n" % (self.pcy) lines.append(line) line = "DD=%.17f\n" % (self.dd) lines.append(line) line = "IsFake=false;\n" lines.append(line) line = "// set isfake to true for X_Y image names and false for HLK style image names.\n" lines.append(line) filepath_ctf = self.filepath_ctf.get() filepath_cpr = os.path.splitext(filepath_ctf)[0] + ".cpr" logging.debug(filepath_cpr) with open(filepath_cpr, 'w') as file_cpr: file_cpr.writelines(lines) def rename_image_folder(self): logging.debug("rename_image_folder") folder_name = self.image_folder.get() if folder_name.endswith("_Images"): logging.debug(folder_name) start = folder_name.rfind("_Images") new_folder_name = folder_name[:start] + "Images" logging.debug(new_folder_name) try: os.replace(folder_name, new_folder_name) except OSError as message: logging.error(message)
class Nim(Tk): def __init__(self): Tk.__init__(self) self.title("Nim") self.kamen = PhotoImage(file = './kamen.ppm') self.nacin = BooleanVar() #0 is ai, 1 is human self.nacin = 0 self.zahtevnost = DoubleVar() #0, 1, 2 are (easy, medium hard) self.vnos_nacina = Entry(self, textvariable = "način") ni = Button(self, text="Nova igra", command=self.nova_igra) ni.grid(column = 2, row = 0) self.platno = Canvas(self, width=700, height = 500, bg='white') self.platno.grid(row= 3, column = 0, columnspan=4) self.vrhovi = [] self.z1 = Radiobutton(self, text = "Skoraj Nepremagljivo!", variable = self.zahtevnost, value=1) self.z2 = Radiobutton(self, text = "Srednje zahtevno ", variable = self.zahtevnost, value=2) self.z3 = Radiobutton(self, text = "Za majhne punčke ", variable = self.zahtevnost, value=3) self.z1.grid(column = 0, row = 0) self.z2.grid(column = 0, row = 1) self.z3.grid(column = 0, row = 2) self.z1.select() self.konec = Label() self.mainloop() def nova_igra(self): # print(self.zahtevnost.get()) if self.vrhovi != []: self.unici_kamne() self.k1.destroy() self.k2.destroy() self.k3.destroy() self.ligralec.destroy() # print(self.vrhovi) self.vrhovi = [randint(1, 5), randint(1, 5), randint(1, 5)] self.kamni = [[],[],[]] self.narisi_kamne(1) self.ligralec = Label(self, text='Na vrsti ste vi!', bg='white', font=("Calibri",21)) self.lracunalnik = Label(self, text='Na vrsti je računalnik', bg='white', font=("Calibri",21)) self.k1 = Label(self, text="Prvi kupček", bg='white') self.k1.place(x = 10, y=220) self.k2 = Label(self, text="Drugi kupček", bg='white') self.k2.place(x = 10, y=330) self.k3 = Label(self, text="Tretji kupček", bg='white') self.k3.place(x = 10, y=440) self.ligralec.place(x=300, y=130) self.konec.destroy() def preveri_zmagovalca(self, igralec): if max(self.vrhovi)<1: self.ligralec.destroy() self.lracunalnik.destroy() if igralec == 0: self.konec = Label(text='Čestitamo, zmagali ste!', bg = 'white', font=("Calibri", 24)) else: self.konec = Label(text = 'Več sreče prihodnjič!', bg = 'white', font=("Calibri",24)) self.konec.place(x=150, y=250) self.k1.destroy() self.k2.destroy() self.k3.destroy() def sestevek(self): s = 0 for i in range(len(self.vrhovi)): s = s^self.vrhovi[i] return s def sestevki(self): return [a^self.X < a for a in self.vrhovi] def naredi_potezo_AI(self): #Ta del kode sem dobil tako, da sem priredil kodo iz wikipedije #vir: http://en.wikipedia.org/wiki/Nim self.X = self.sestevek() S = self.sestevki() odstranjenih = 0 if self.X == 0: if max(self.vrhovi) >1: print("Can't win") for i, vrh in enumerate(self.vrhovi): if vrh>0: izbrani, odstranjenih = i, vrh else: izbrani = S.index(True) odstranjenih = self.vrhovi[izbrani] - (self.vrhovi[izbrani]^self.X) dva_alivec = 0 for i, vrh in enumerate(self.vrhovi): if i == izbrani: if vrh-odstranjenih > 1: dva_alivec += 1 else: if vrh > 1: dva_alivec += 1 if dva_alivec == 0: izbrani = self.vrhovi.index(max(self.vrhovi)) vrhov_z1 = sum(v == 1 for v in self.vrhovi) if vrhov_z1%2 == 1: odstranjenih = self.vrhovi[izbrani]-1 else: odstranjenih = self.vrhovi[izbrani] if odstranjenih == 0: odstranjenih = 1 izbrani = self.vrhovi.index(True) x = 10*(1-(1/self.zahtevnost.get())) v = randint(1, 10) if v < x: neprazni = [] for i, vr in enumerate(self.vrhovi): if vr>0: neprazni.append(i) izbrani = choice(neprazni) odstranjenih = randint(1, self.vrhovi[izbrani]) self.vrhovi[izbrani] -= odstranjenih self.unici_kamne() self.narisi_kamne(b=1) self.lracunalnik.place_forget() self.ligralec.place(x=300, y=130) self.preveri_zmagovalca(1) # print("Odstranil sem " + str(odstranjenih+1) + " kamenčkov iz " + str(izbrani+1) + " vrha.") def narisi_kamne(self, b=0): # print("narisi kamne") self.kamni = [[],[],[]] for i, j in enumerate(self.vrhovi): for k in range(j): self.kamni[i].append(Label(self, image=self.kamen, bd=0)) self.kamni[i][k].place(x=(100+110*k), y=(200+110*i)) par = (k+1, i+1) if b == 1: self.kamni[i][k].bind('<Button-1>', partial(self.izberi_kamen, par)) def unici_kamne(self): for vrh in self.kamni: for kamen in vrh: kamen.destroy() def naredi_potezo_clovek_text(self): izbrani = int(input("Izberi vrh: ")) odstranjenih = int(input("Stevilo kamenckov: ")) self.vrhovi[izbrani] -= odstranjenih # print(self.vrhovi) def izberi_kamen(self, par, j): # print("izbrali ste kamen ", par[0], " iz ", par[1], " vrha.") self.vrhovi[par[1]-1] = par[0]-1 # print(self.vrhovi) self.unici_kamne() self.narisi_kamne(0) self.ligralec.place_forget() self.lracunalnik.place(x=300, y=130) self.preveri_zmagovalca(0) self.after(1000, self.naredi_potezo_AI)
class PowerGeneration(Subsystem): """Contains all Data on Power Generation.""" def __init__(self, data): """Init the Power Generation.""" self.data = data self.powergeneration = data.powergeneration efficiency = self.powergeneration["Reactor Efficiency"] self.no_reactors = IntVar(value=1) self.power_need = QuantityVar(unit="W") self.power_reactor = DoubleVar() self.mass_reactor = QuantityVar(unit="g") self.power_overall = QuantityVar(unit="W") self.power_effective = QuantityVar(unit="W") self.waste_heat = QuantityVar(unit="W") self.mass_total_reactor = QuantityVar(unit="g") self.efficiency = DoubleVar(value=efficiency) def make_entry(self, frame): """Make the Entry Form.""" entry = { "Power per Reactor": { "value": self.power_reactor, "unit": "MW", "type": "Spinbox", "config": { "from": 50, "to": 100 * 50, "increment": 50 } } } self._make_entry(frame, "Power Generation", entry) def make_display(self, frame): """Make the Data Display.""" data = { "Power Needed": { "value": self.power_need, }, "Reactor Efficiency": { "value": self.efficiency, }, "Needed Ractors": { "value": self.no_reactors, }, "Overall Reactor Power": { "value": self.power_overall, }, "Effective Power Overall": { "value": self.power_effective, }, "Waste Heat": { "value": self.waste_heat, }, "Mass per Reactor": { "value": self.mass_reactor, }, "Total Reactor Mass": { "value": self.mass_total_reactor, }, } self._make_display(frame, "Reactor Data", data) def calculate(self): """Do the calculation.""" efficiency = self.efficiency.get() power_reactor = self.power_reactor.get() * 1e6 reactor_mass = self.powergeneration["Reactor Mass"] / 1000 power_need = 0 for _, subsystem in self.data.power.items(): power_need += subsystem power_effective = power_need power_overall = self._roundup(power_need / efficiency, power_reactor) no_reactors = power_overall / power_reactor print(power_need, ', ', power_overall, ', ', no_reactors) waste_heat = power_overall - power_effective mass_reactor = power_reactor * reactor_mass mass_total = mass_reactor * no_reactors self.data.masses["Reactors"] = mass_total self.data.wasteheat["Reactors"] = waste_heat self.data.volumes["Reactors"] = mass_total * \ self.powergeneration["Volume"] print(mass_reactor) self.power_need.set(power_need) self.no_reactors.set(no_reactors) self.power_overall.set(power_overall) self.mass_reactor.set(mass_reactor) self.power_effective.set(power_effective) self.waste_heat.set(waste_heat) self.mass_total_reactor.set(mass_total)
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()
#creating scrollbars xscrollbar = Scrollbar(root, orient=HORIZONTAL) xscrollbar.grid(row=1, column=0, sticky=E + W) yscrollbar = Scrollbar(root) yscrollbar.grid(row=0, column=1, sticky=N + S) #creating canvas canvas = Canvas(root, height=canvasHeight, width=canvasWidth, xscrollcommand=xscrollbar.set, yscrollcommand=yscrollbar.set) canvas.place(x=canvasxPosition, y=canvasyPosition) im = Image.open(imagePath.get()) im_width, im_height = im.size im = im.resize((int(im_width * imageMagnification.get()), int(im_height * imageMagnification.get())), Image.ANTIALIAS) photo = ImageTk.PhotoImage(im) image = canvas.create_image(0, 0, anchor=NW, image=photo) canvas.grid(row=0, column=0, sticky=N + S + E + W) canvas.config(scrollregion=canvas.bbox(ALL)) xscrollbar.config(command=canvas.xview) yscrollbar.config(command=canvas.yview) # ---- zoom function ---- zoomcycle = 0 zimg_id = None if operatingSystem == 2:
entsv = DoubleVar() ent0 = Entry(lf0, validate='key', validatecommand=(vcmd, '%P'), textvariable=entsv) ent0.bind("<Return>", end_input) ent0.grid(row=1, column=0, padx=10) ent0.focus() messlbl = Label(lf0, text=mess_text, style='brown.TLabel') messlbl.grid(row=2, column=0, pady=10, padx=10) if __name__ == "__main__": root = Tk() fra0 = Frame(root) fra0.grid() LFTEXT = 'Beer Strength % v/v' LLIMIT = 0.0 ULIMIT = 10.0 out_var1 = DoubleVar() MESSTEXT = 'Insert +ve or -ve float, <Return> to confirm' entry_float(fra0, LFTEXT, LLIMIT, ULIMIT, MESSTEXT, out_var1) b2 = Button(root, text='Click after selection', command=lambda: print(out_var1.get())) b2.grid(row=1, column=0) root.mainloop()
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) self._show_advanced = False self._settings = {} self._ports = () self._port = StringVar() self._port_desc = StringVar() self._baudrate = IntVar() self._databits = IntVar() self._stopbits = DoubleVar() self._parity = StringVar() self._rtscts = IntVar() self._xonxoff = IntVar() self._protocol = IntVar() self._raw = IntVar() self._autoscroll = IntVar() self._maxlines = IntVar() self._webmap = IntVar() self._mapzoom = IntVar() self._units = StringVar() self._format = StringVar() self._datalog = IntVar() self._record_track = IntVar() self._noports = True self._validsettings = True self._logpath = None self._trackpath = None self._img_conn = ImageTk.PhotoImage(Image.open(ICON_CONN)) self._img_disconn = ImageTk.PhotoImage(Image.open(ICON_DISCONN)) self._img_ubxconfig = ImageTk.PhotoImage(Image.open(ICON_UBXCONFIG)) self._img_dataread = ImageTk.PhotoImage(Image.open(ICON_LOGREAD)) self._body() self._do_layout() self._get_ports() self._reset() def _body(self): ''' Set up frame and widgets. ''' for i in range(4): self.grid_columnconfigure(i, weight=1) self.grid_rowconfigure(0, weight=1) self.option_add("*Font", self.__app.font_sm) # Serial port settings self._frm_basic = Frame(self) self._lbl_port = Label(self._frm_basic, text="Port") self._lbx_port = Listbox(self._frm_basic, border=2, relief="sunken", bg=ENTCOL, width=28, height=5, justify=LEFT, exportselection=False) self._scr_portv = Scrollbar(self._frm_basic, orient=VERTICAL) self._scr_porth = Scrollbar(self._frm_basic, orient=HORIZONTAL) self._lbx_port.config(yscrollcommand=self._scr_portv.set) self._lbx_port.config(xscrollcommand=self._scr_porth.set) self._scr_portv.config(command=self._lbx_port.yview) self._scr_porth.config(command=self._lbx_port.xview) self._lbx_port.bind("<<ListboxSelect>>", self._on_select_port) self._lbl_baudrate = Label(self._frm_basic, text="Baud rate") self._spn_baudrate = Spinbox(self._frm_basic, values=(BAUDRATES), width=8, state=READONLY, readonlybackground=ENTCOL, wrap=True, textvariable=self._baudrate) self._btn_toggle = Button(self._frm_basic, text=ADVOFF, width=3, command=self._toggle_advanced) self._frm_advanced = Frame(self) self._lbl_databits = Label(self._frm_advanced, text="Data Bits") self._spn_databits = Spinbox(self._frm_advanced, values=(8, 7, 6, 5), width=3, state=READONLY, readonlybackground=ENTCOL, wrap=True, textvariable=self._databits) self._lbl_stopbits = Label(self._frm_advanced, text="Stop Bits") self._spn_stopbits = Spinbox(self._frm_advanced, values=(2, 1.5, 1), width=3, state=READONLY, readonlybackground=ENTCOL, wrap=True, textvariable=self._stopbits) self._lbl_parity = Label(self._frm_advanced, text="Parity") self._spn_parity = Spinbox(self._frm_advanced, values=("None", "Even", "Odd", "Mark", "Space"), width=6, state=READONLY, readonlybackground=ENTCOL, wrap=True, textvariable=self._parity) self._chk_rts = Checkbutton(self._frm_advanced, text="RTS/CTS", variable=self._rtscts) self._chk_xon = Checkbutton(self._frm_advanced, text="Xon/Xoff", variable=self._xonxoff) self._frm_buttons = Frame(self) self._btn_connect = Button(self._frm_buttons, width=45, height=35, image=self._img_conn, command=lambda: self.__app.serial_handler.connect()) self._btn_disconnect = Button(self._frm_buttons, width=45, height=35, image=self._img_disconn, command=lambda: self.__app.serial_handler.disconnect(), state=DISABLED) self._btn_connect_file = Button(self._frm_buttons, width=45, height=35, image=self._img_dataread, command=lambda: self._on_data_stream()) self._lbl_status_preset = Label(self._frm_buttons, font=self.__app.font_md2, text='') # Other configuration options self._frm_options = Frame(self) self._lbl_protocol = Label(self._frm_options, text=LBLPROTDISP) self._rad_nmea = Radiobutton(self._frm_options, text="NMEA", variable=self._protocol, value=NMEA_PROTOCOL) self._rad_ubx = Radiobutton(self._frm_options, text="UBX", variable=self._protocol, value=UBX_PROTOCOL) self._rad_all = Radiobutton(self._frm_options, text="ALL", variable=self._protocol, value=MIXED_PROTOCOL) self._lbl_consoledisplay = Label(self._frm_options, text=LBLDATADISP) self._rad_parsed = Radiobutton(self._frm_options, text="Parsed", variable=self._raw, value=0) self._rad_raw = Radiobutton(self._frm_options, text="Raw", variable=self._raw, value=1) self._lbl_format = Label(self._frm_options, text="Degrees Format") self._spn_format = Spinbox(self._frm_options, values=(DDD, DMS, DMM), width=6, state=READONLY, readonlybackground=ENTCOL, wrap=True, textvariable=self._format) self._lbl_units = Label(self._frm_options, text="Units") self._spn_units = Spinbox(self._frm_options, values=(UMM, UIK, UI, UMK), width=13, state=READONLY, readonlybackground=ENTCOL, wrap=True, textvariable=self._units) self._chk_scroll = Checkbutton(self._frm_options, text="Autoscroll", variable=self._autoscroll) self._spn_maxlines = Spinbox(self._frm_options, values=("100", "200", "500", "1000", "2000"), width=6, readonlybackground=ENTCOL, wrap=True, textvariable=self._maxlines, state=READONLY) self._chk_webmap = Checkbutton(self._frm_options, text="Web Map Zoom", variable=self._webmap) self._scl_mapzoom = Scale(self._frm_options, from_=1, to=20, orient=HORIZONTAL, relief="sunken", bg=ENTCOL, variable=self._mapzoom) self._chk_datalog = Checkbutton(self._frm_options, text=LBLDATALOG, variable=self._datalog, command=lambda: self._on_data_log()) self._chk_recordtrack = Checkbutton(self._frm_options, text=LBLTRACKRECORD, variable=self._record_track, command=lambda: self._on_record_track()) self._lbl_ubxconfig = Label(self._frm_options, text=LBLUBXCONFIG) self._btn_ubxconfig = Button(self._frm_options, width=45, height=35, text='UBX', image=self._img_ubxconfig, command=lambda: self._on_ubx_config(), state=DISABLED) def _do_layout(self): ''' Position widgets in frame. ''' self._frm_basic.grid(column=0, row=0, columnspan=4, sticky=(W, E)) self._lbl_port.grid(column=0, row=0, sticky=(W)) self._lbx_port.grid(column=1, row=0, sticky=(W, E), padx=3, pady=3) self._scr_portv.grid(column=2, row=0, sticky=(N, S)) self._scr_porth.grid(column=1, row=1, sticky=(E, W)) self._lbl_baudrate.grid(column=0, row=2, sticky=(W)) self._spn_baudrate.grid(column=1, row=2, sticky=(W), padx=3, pady=3) self._btn_toggle.grid(column=2, row=2, sticky=(E)) self._frm_advanced.grid_forget() self._lbl_databits.grid(column=0, row=0, sticky=(W)) self._spn_databits.grid(column=1, row=0, sticky=(W), padx=3, pady=3) self._lbl_stopbits.grid(column=2, row=0, sticky=(W)) self._spn_stopbits.grid(column=3, row=0, sticky=(W), padx=3, pady=3) self._lbl_parity.grid(column=0, row=1, sticky=(W)) self._spn_parity.grid(column=1, row=1, sticky=(W), padx=3, pady=3) self._chk_rts.grid(column=2, row=1, sticky=(W)) self._chk_xon.grid(column=3, row=1, sticky=(W), padx=3, pady=3) ttk.Separator(self).grid(column=0, row=2, columnspan=4, padx=3, pady=3, sticky=(W, E)) self._frm_buttons.grid(column=0, row=3, columnspan=4, sticky=(W, E)) self._btn_connect.grid(column=0, row=0, padx=3, pady=3) self._btn_connect_file.grid(column=1, row=0, padx=3, pady=3) self._btn_disconnect.grid(column=3, row=0, padx=3, pady=3) ttk.Separator(self).grid(column=0, row=7, columnspan=4, padx=3, pady=3, sticky=(W, E)) self._frm_options.grid(column=0, row=8, columnspan=4, sticky=(W, E)) self._lbl_protocol.grid(column=0, row=0, padx=3, pady=3, sticky=(W)) self._rad_nmea.grid(column=1, row=0, padx=0, pady=0, sticky=(W)) self._rad_ubx.grid(column=2, row=0, padx=0, pady=0, sticky=(W)) self._rad_all.grid(column=3, row=0, padx=0, pady=0, sticky=(W)) self._lbl_consoledisplay.grid(column=0, row=1, padx=2, pady=3, sticky=(W)) self._rad_parsed.grid(column=1, row=1, padx=1, pady=3, sticky=(W)) self._rad_raw.grid(column=2, row=1, padx=2, pady=3, sticky=(W)) self._lbl_format.grid(column=0, row=2, padx=3, pady=3, sticky=(W)) self._spn_format.grid(column=1, row=2, padx=2, pady=3, sticky=(W)) self._lbl_units.grid(column=0, row=3, padx=3, pady=3, sticky=(W)) self._spn_units.grid(column=1, row=3, columnspan=3, padx=2, pady=3, sticky=(W)) self._chk_scroll.grid(column=0, row=4, padx=3, pady=3, sticky=(W)) self._spn_maxlines.grid(column=1, row=4, columnspan=3, padx=3, pady=3, sticky=(W)) self._chk_webmap.grid(column=0, row=5, sticky=(W)) self._scl_mapzoom.grid(column=1, row=5, columnspan=3, sticky=(W)) self._chk_datalog.grid(column=0, row=6, padx=3, pady=3, sticky=(W)) self._chk_recordtrack.grid(column=0, row=7, padx=3, pady=3, sticky=(W)) ttk.Separator(self._frm_options).grid(column=0, row=8, columnspan=4, padx=3, pady=3, sticky=(W, E)) self._lbl_ubxconfig.grid(column=0, row=9, padx=3, pady=3, sticky=(W)) self._btn_ubxconfig.grid(column=1, row=9, padx=3, pady=3, sticky=(W)) def _on_select_port(self, *args, **kwargs): ''' Get selected port from listbox and set global variable. ''' idx = self._lbx_port.curselection() if idx == "": idx = 0 port_orig = self._lbx_port.get(idx) port = port_orig[0:port_orig.find(":")] desc = port_orig[port_orig.find(":") + 1:] if desc == '': desc = "device" self._port.set(port) self._port_desc.set(desc) def _on_ubx_config(self, *args, **kwargs): ''' Open UBX configuration dialog panel. ''' self.__app.ubxconfig() def _on_data_log(self): ''' Start or stop data logger ''' if self._datalog.get() == 1: self._logpath = self.__app.file_handler.set_logfile_path() if self._logpath is not None: self.__app.set_status("Data logging enabled: " + self._logpath, "green") else: self._datalog.set(False) else: self._logpath = None self._datalog.set(False) # self.__app.file_handler.close_logfile() self.__app.set_status("Data logging disabled", "blue") def _on_record_track(self): ''' Start or stop track recorder ''' if self._record_track.get() == 1: self._trackpath = self.__app.file_handler.set_trackfile_path() if self._trackpath is not None: self.__app.set_status("Track recording enabled: " + self._trackpath, "green") else: self._record_track.set(False) else: self._trackpath = None self._record_track.set(False) # self.__app.file_handler.close_trackfile() self.__app.set_status("Track recording disabled", "blue") def _on_data_stream(self): ''' Start data file streamer ''' self._logpath = self.__app.file_handler.open_logfile_input() if self._logpath is not None: self.__app.set_status("") self.__app.serial_handler.connect_file() def _toggle_advanced(self): ''' Toggle advanced serial port settings panel on or off ''' self._show_advanced = not self._show_advanced if self._show_advanced: self._frm_advanced.grid(column=0, row=1, columnspan=3, sticky=(W, E)) self._btn_toggle.config(text=ADVON) else: self._frm_advanced.grid_forget() self._btn_toggle.config(text=ADVOFF) def _get_ports(self): ''' Populate list of available serial ports using pyserial comports tool. If no ports found, disable all connection-dependent widgets. Attempt to preselect the first port that has a recognisable GPS designation in its description (usually only works on Posix platforms - Windows doesn't parse UART device desc or HWID) ''' self._ports = sorted(comports()) init_idx = 0 port = '' desc = '' if len(self._ports) > 0: for idx, (port, desc, _) in enumerate(self._ports, 1): self._lbx_port.insert(idx, port + ": " + desc) for kgp in KNOWNGPS: if kgp in desc: init_idx = idx break self._noports = False else: self._noports = True self.set_controls(NOPORTS) self._lbx_port.activate(init_idx) self._port.set(port) self._port_desc.set(desc) def _reset(self): ''' Reset settings to defaults. ''' self._baudrate.set(BAUDRATES[4]) # 9600 self._databits.set(8) self._stopbits.set(1) self._parity.set("None") self._rtscts.set(False) self._xonxoff.set(False) self._protocol.set(MIXED_PROTOCOL) self._format.set(DDD) self._units.set(UMM) self._autoscroll.set(1) self._maxlines.set(300) self._raw.set(False) self._webmap.set(False) self._mapzoom.set(10) self._datalog.set(False) self._record_track.set(False) def set_controls(self, status): ''' ...for the heart of the sun. Public method to enable and disable serial port controls depending on connection status. ''' self._lbl_port.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._lbx_port.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._lbl_baudrate.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._spn_baudrate.configure(state=(READONLY if status == DISCONNECTED else DISABLED)) self._lbl_databits.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._spn_databits.configure(state=(READONLY if status == DISCONNECTED else DISABLED)) self._lbl_stopbits.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._spn_stopbits.configure(state=(READONLY if status == DISCONNECTED else DISABLED)) self._lbl_parity.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._spn_parity.configure(state=(READONLY if status == DISCONNECTED else DISABLED)) self._chk_rts.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._chk_xon.configure(state=(NORMAL if status == DISCONNECTED else DISABLED)) self._btn_connect.config(state=(DISABLED if status in \ (CONNECTED, CONNECTED_FILE, NOPORTS) \ else NORMAL)) self._btn_disconnect.config(state=(DISABLED if status in \ (DISCONNECTED, NOPORTS) else NORMAL)) self._chk_datalog.config(state=(DISABLED if status in \ (CONNECTED, CONNECTED_FILE, NOPORTS) \ else NORMAL)) self._chk_recordtrack.config(state=(DISABLED if status in \ (CONNECTED, CONNECTED_FILE) \ else NORMAL)) self._btn_connect_file.config(state=(DISABLED if status in \ (CONNECTED, CONNECTED_FILE) \ else NORMAL)) self._btn_ubxconfig.config(state=(DISABLED if status in \ (DISCONNECTED, CONNECTED_FILE, NOPORTS) \ else NORMAL)) self.__app.menu.options_menu.entryconfig(0, state=(DISABLED if status in \ (CONNECTED_FILE, DISCONNECTED, NOPORTS) \ else NORMAL)) def get_settings(self): ''' Public method returns all settings as a dict. ''' self._settings['port'] = self._port.get() self._settings['noports'] = self._noports self._settings['port_desc'] = self._port_desc.get() self._settings['baudrate'] = self._baudrate.get() self._settings['databits'] = self._databits.get() self._settings['stopbits'] = self._stopbits.get() self._settings['parity'] = self._parity.get() self._settings['rtscts'] = self._rtscts.get() self._settings['xonxoff'] = self._xonxoff.get() self._settings['protocol'] = self._protocol.get() self._settings['raw'] = self._raw.get() self._settings['autoscroll'] = self._autoscroll.get() self._settings['maxlines'] = self._maxlines.get() self._settings['webmap'] = self._webmap.get() self._settings['mapzoom'] = self._mapzoom.get() self._settings['units'] = self._units.get() self._settings['format'] = self._format.get() self._settings['logpath'] = self._logpath self._settings['datalogging'] = self._datalog.get() self._settings['recordtrack'] = self._record_track.get() return self._settings def get_size(self): ''' Get current frame size. ''' self.update_idletasks() # Make sure we know about any resizing return (self.winfo_width(), self.winfo_height())
class HOPSFitsWindow(HOPSWidget): def __init__(self, window, input=None, input_name=None, input_options=None, figsize=None, show_nav=False, show_controls=False, show_axes=False, subplots_adjust=None, dwmax=8.0, dhmax=8.0): widget = Frame(window.main_frame) self.show_axes = show_axes if figsize: try: wpcent, hpcent, wmax, hmax, ratio, = figsize wmax, hmax = dwmax, dhmax w = min(wpcent * window.log.plt2screen_w, wmax) h = min(hpcent * window.log.plt2screen_h, hmax) if h * ratio < w: w = h * ratio else: h = w / ratio except: w, h = figsize self.figure = matplotlib.figure.Figure(figsize=(w, h)) else: self.figure = matplotlib.figure.Figure() self.figure.patch.set_facecolor('white') self.canvas = FigureCanvasTkAgg(self.figure, widget) self.ax = self.figure.add_subplot(111) self.ax.tick_params(axis='y', rotation=90) if not self.show_axes: self.ax.axis('off') self.figure.subplots_adjust(left=0.01, right=0.99, bottom=0.01, top=0.99) if subplots_adjust: self.figure.subplots_adjust(left=subplots_adjust[0], right=subplots_adjust[1], bottom=subplots_adjust[2], top=subplots_adjust[3]) self.data = None self.mean = 0 self.std = 0 self.image = None self.sqrt_vmin = DoubleVar(widget, value=0) self.vmin = IntVar(widget, value=0) self.sqrt_vmax = DoubleVar(widget, value=10000) self.vmax = IntVar(widget, value=10000) self.gamma = DoubleVar(widget, value=0) self.flip = IntVar(widget, value=0) self.mirror = IntVar(widget, value=0) self.white_sky = IntVar(widget, value=0) if input_name: if len(input_name) > 50: split = [ input_name[i:i + 50] for i in range(0, len(input_name), 50) ] input_name = '\n'.join(split) self.fits_name = StringVar(widget, value=input_name) self.fits_name_label = Label(widget, textvar=self.fits_name) # extra widgets control_frame = Frame(widget) self.control_frame = control_frame self.info_label = Label( control_frame, text= 'Scroll up/down to zoom in/out. Click & drag to move the image.') self.mouse_data = StringVar(control_frame, value=' ') self.mouse_data_label = Label(control_frame, textvar=self.mouse_data) self.black_entry = Scale(control_frame, resolution=0.1, variable=self.sqrt_vmin, orient=HORIZONTAL, showvalue=False) self.black_entry.bind("<B1-Motion>", self.contrast) self.black_entry.bind("<ButtonRelease-1>", self.contrast) self.black_entry_label_0 = Label(control_frame, text='Minimum = ', anchor=E) self.black_entry_label = Label(control_frame, textvar=self.vmin, anchor=W) self.black_entry['from_'] = 1 self.black_entry['to'] = 1000 self.white_entry = Scale(control_frame, resolution=0.1, variable=self.sqrt_vmax, orient=HORIZONTAL, showvalue=False) self.white_entry.bind("<B1-Motion>", self.contrast) self.white_entry.bind("<ButtonRelease-1>", self.contrast) self.white_entry_label_0 = Label(control_frame, text='Maximum = ', anchor=E) self.white_entry_label = Label(control_frame, textvar=self.vmax, anchor=W) self.white_entry['from_'] = 1 self.white_entry['to'] = 1000 self.gamma_entry = Scale(control_frame, resolution=0.001, variable=self.gamma, orient=HORIZONTAL, showvalue=False) self.gamma_entry.bind("<B1-Motion>", self.contrast) self.gamma_entry.bind("<ButtonRelease-1>", self.contrast) self.gamma_entry_label_0 = Label(control_frame, text='Stretch factor = ', anchor=E) self.gamma_entry_label = Label(control_frame, textvar=self.gamma, anchor=W) self.gamma_entry['from_'] = 0 self.gamma_entry['to'] = 1 self.flip_button = Checkbutton(control_frame, text='Flip', variable=self.flip, command=self.flip_fov) self.mirror_button = Checkbutton(control_frame, text='Mirror', variable=self.mirror, command=self.mirror_fov) self.reverse_color_button = Checkbutton(control_frame, text='White Sky', variable=self.white_sky, command=self.reverse_color) self.reset_button = Button(control_frame, text='RESET', command=self.reset) self.info_label.grid(row=1, column=1, columnspan=4) self.mouse_data_label.grid(row=2, column=1, columnspan=4) self.black_entry_label_0.grid(row=3, column=1, columnspan=2) self.black_entry_label.grid(row=3, column=3) self.black_entry.grid(row=4, column=1, columnspan=4, sticky=N + S + E + W) self.white_entry_label_0.grid(row=5, column=1, columnspan=2) self.white_entry_label.grid(row=5, column=3) self.white_entry.grid(row=6, column=1, columnspan=4, sticky=N + S + E + W) self.gamma_entry_label_0.grid(row=7, column=1, columnspan=2) self.gamma_entry_label.grid(row=7, column=3) self.gamma_entry.grid(row=8, column=1, columnspan=4, sticky=N + S + E + W) self.reset_button.grid(row=9, column=1) self.flip_button.grid(row=9, column=2) self.mirror_button.grid(row=9, column=3) self.reverse_color_button.grid(row=9, column=4) Label(control_frame, text=' ').grid(row=10, column=1, columnspan=4) self.picked = False if input: self.load_fits(input, input_name, input_options) self.canvas.get_tk_widget().pack(side=TOP) if show_nav: toolbar = NavigationToolbar2Tk(self.canvas, self.widget) toolbar.pack(side=BOTTOM) self.fits_name_label.pack() if show_controls: control_frame.pack() self.canvas.callbacks.connect('scroll_event', self.zoom) self.canvas.callbacks.connect('motion_notify_event', self.move) self.canvas.callbacks.connect('button_press_event', self.pick) self.canvas.callbacks.connect('button_release_event', self.pick) HOPSWidget.__init__(self, window, widget, 'FitsWindow') def load_fits(self, input, input_name=None, input_options=None, draw=True): if isinstance(input, str): fits = get_fits_data(input) input_name = os.path.split(input)[1] elif isinstance(input, pf.ImageHDU) or isinstance( input, pf.PrimaryHDU) or isinstance(input, pf.CompImageHDU): fits = [input] else: raise RuntimeError('Invalid input ', type(input)) if input_name: if len(input_name) > 50: split = [ input_name[i:i + 50] for i in range(0, len(input_name), 50) ] input_name = '\n'.join(split) self.fits_name.set(input_name) self.data = fits[0].data try: self.mean = fits[0].header[self.window.log.mean_key] self.std = fits[0].header[self.window.log.std_key] except: self.mean = np.median(fits[0].data) self.std = plc.mad(fits[0].data) * 1.5 self.black_entry['from_'] = np.sqrt(max(0, np.min(self.data))) self.black_entry['to'] = np.sqrt(np.max(self.data)) self.white_entry['from_'] = np.sqrt(max(0, np.min(self.data))) self.white_entry['to'] = np.sqrt(np.max(self.data)) self.ax.cla() if not self.show_axes: self.ax.axis('off') self.ax.tick_params(axis='y', rotation=90) self.vmin.set( max(1, int(self.mean + self.window.log.frame_low_std * self.std))) self.vmax.set( max(1, int(self.mean + self.window.log.frame_upper_std * self.std))) self.gamma.set(0) if input_options: if input_options[0] != 'auto': self.vmin.set(input_options[0]) if input_options[1] != 'auto': self.vmax.set(input_options[1]) self.gamma.set(input_options[2]) self.flip.set(input_options[3]) self.mirror.set(input_options[4]) self.white_sky.set(input_options[5]) self.sqrt_vmin.set(np.sqrt(self.vmin.get())) self.sqrt_vmax.set(np.sqrt(self.vmax.get())) self.image = self.ax.imshow(self.data**(10**-self.gamma.get()), origin='lower', extent=(0, len(self.data[0]), 0, len(self.data)), cmap=Greys, vmin=self.vmin.get(), vmax=self.vmax.get()) if self.white_sky.get(): self.image.set_cmap(Greys) else: self.image.set_cmap(Greys_r) if self.flip.get(): self.ax.set_ylim(len(self.data) + 5, 0) else: self.ax.set_ylim(0, len(self.data) + 5) if self.mirror.get(): self.ax.set_xlim(len(self.data[0]) + 5, 0) else: self.ax.set_xlim(0, len(self.data[0]) + 5) if draw: self.draw() def reverse_color(self): if self.white_sky.get(): self.image.set_cmap(Greys) else: self.image.set_cmap(Greys_r) self.draw() def flip_fov(self): lims = self.ax.get_ylim() if self.flip.get(): self.ax.set_ylim(max(lims), min(lims)) else: self.ax.set_ylim(min(lims), max(lims)) self.draw() def mirror_fov(self): lims = self.ax.get_xlim() if self.mirror.get(): self.ax.set_xlim(max(lims), min(lims)) else: self.ax.set_xlim(min(lims), max(lims)) self.draw() def contrast(self, event): if self.sqrt_vmin.get() >= self.sqrt_vmax.get(): self.sqrt_vmin.set(self.sqrt_vmax.get() - 1) self.vmin.set(int(self.sqrt_vmin.get()**2)) self.vmax.set(int(self.sqrt_vmax.get()**2)) self.image.set_data(np.maximum(0, self.data)**(10**-self.gamma.get())) self.image.set_clim(self.vmin.get()**(10**-self.gamma.get()), self.vmax.get()**(10**-self.gamma.get())) self.draw() def get_fov_options(self): return [ self.vmin.get(), self.vmax.get(), self.gamma.get(), self.flip.get(), self.mirror.get(), self.white_sky.get() ] def pick(self, event): if isinstance(event, matplotlib.backend_bases.MouseEvent): if event.inaxes is None: pass elif event.name == 'button_press_event': self.picked = (event.xdata, event.ydata) elif event.name == 'button_release_event': self.picked = False def move(self, event): if isinstance(event, matplotlib.backend_bases.MouseEvent): if event.inaxes is None: pass elif event.name == 'motion_notify_event': try: self.mouse_data.set( 'Mouse on: x={0:.2f}, y={1:.2f}, counts={2:.2f}'. format(event.xdata, event.ydata, self.data[int(event.ydata), int(event.xdata)])) except: self.mouse_data.set( 'Mouse on: x={0:.2f}, y={1:.2f}, counts={2}'.format( event.xdata, event.ydata, '-')) if self.picked: dx = event.xdata - self.picked[0] dy = event.ydata - self.picked[1] self.ax.set_xlim(self.ax.get_xlim()[0] - dx, self.ax.get_xlim()[1] - dx) self.ax.set_ylim(self.ax.get_ylim()[0] - dy, self.ax.get_ylim()[1] - dy) self.draw() def zoom(self, event): if isinstance(event, matplotlib.backend_bases.MouseEvent): if event.inaxes is None: pass elif event.name == 'scroll_event': zoom_factor = 1.2 scale_factor = 1.0 if event.button == 'up': scale_factor = 1 / zoom_factor elif event.button == 'down': scale_factor = zoom_factor xdata = event.xdata ydata = event.ydata cur_xlim = self.ax.get_xlim() cur_ylim = self.ax.get_ylim() cur_xrange = (cur_xlim[1] - cur_xlim[0]) cur_yrange = (cur_ylim[1] - cur_ylim[0]) new_xrange = cur_xrange * scale_factor new_yrange = cur_yrange * scale_factor new_xmin = xdata - new_xrange * (xdata - cur_xlim[0]) / cur_xrange new_ymin = ydata - new_yrange * (ydata - cur_ylim[0]) / cur_yrange self.ax.set_xlim([new_xmin, new_xmin + new_xrange]) self.ax.set_ylim([new_ymin, new_ymin + new_yrange]) self.draw() def reset(self): self.ax.set_xlim(0, len(self.data[0]) + 5) self.ax.set_ylim(0, len(self.data) + 5) if self.flip.get(): self.ax.set_ylim(self.ax.get_ylim()[1], self.ax.get_ylim()[0]) if self.mirror.get(): self.ax.set_xlim(self.ax.get_xlim()[1], self.ax.get_xlim()[0]) self.vmin.set( max(1, int(self.mean + self.window.log.frame_low_std * self.std))) self.sqrt_vmin.set(np.sqrt(self.vmin.get())) self.vmax.set( max(1, int(self.mean + self.window.log.frame_upper_std * self.std))) self.sqrt_vmax.set(np.sqrt(self.vmax.get())) self.gamma.set(0) self.image.set_data(np.maximum(0, self.data)**(10**-self.gamma.get())) self.image.set_clim(self.vmin.get()**(10**-self.gamma.get()), self.vmax.get()**(10**-self.gamma.get())) self.draw() def draw(self, update_level=1): self.canvas.draw() if update_level == 0: pass elif update_level == 1: self.window.update_idletasks() elif update_level == 2: self.window.update() def disable(self): for child in self.widget.winfo_children(): try: child.configure(state='disable') except: pass def activate(self): for child in self.widget.winfo_children(): try: child.configure(state='active') except: pass
Label(root, text="Choose mode: ").grid(row=row, column=0) button1 = Button(root, text='Mode A', width=9, command=button_1, fg="black") button2 = Button(root, text='Mode B', width=9, command=button_2, fg="gray") button1.grid(row=row, column=1, columnspan=3) button2.grid(row=row, column=5, columnspan=3) #button1.bind('<Button-1>',button1) #button2.bind('<Button-1>',button2) ## public key if choose Mode B row = 4 ## progress bar row = 5 row = 5 ratio = DoubleVar() ratio_per = StringVar() ratio_per.set("Progress: " + str(ratio.get() / 3.0)[:3] + "%") ratio_per_label = Label(root, textvariable=ratio_per) ratio_per_label.grid(row=row, column=0, columnspan=10) row = 6 file_size_int = IntVar() progress = Progressbar(orient='horizontal', length=300, mode='determinate', variable=ratio, maximum=300) progress.grid(row=row, column=0, columnspan=10) ## button OK row = 6 row = 7
class TkMainGui(ttk.Frame): def __init__(self, root, default_folder=""): ttk.Frame.__init__(self, root, padding="3 3 12 12") self.default_folder = default_folder logging.debug("Create main frame") #mainframe = ttk.Frame(root, padding="3 3 12 12") self.grid(column=0, row=0, sticky=(N, W, E, S)) self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) logging.debug("Create variable") self.filepath_ctf = StringVar() self.image_folder = StringVar() self.vh_ratio = DoubleVar(value=0.76200) self.results_text = StringVar() self.pcx = 0.0 self.pcy = 0.0 self.dd = 0.0 logging.debug("Create ctf components") ctf_entry = ttk.Entry(self, width=80, textvariable=self.filepath_ctf) ctf_entry.grid(column=2, row=1, sticky=(W, E)) ttk.Button(self, text="Select CTF file", command=self.open_ctf_file).grid(column=3, row=1, sticky=W) logging.debug("Create image folder components") image_entry = ttk.Entry(self, width=80, textvariable=self.image_folder) image_entry.grid(column=2, row=2, sticky=(W, E)) ttk.Button(self, text="Select Image folder", command=self.open_image_folder).grid(column=3, row=2, sticky=W) logging.debug("Create vh_ratio components") ttk.Label(self, text="VH Ratio").grid(column=1, row=3, sticky=(W, E)) image_entry = ttk.Entry(self, width=10, textvariable=self.vh_ratio) image_entry.grid(column=2, row=3, sticky=(W, E)) ttk.Button(self, text="Prepare data", command=self.prepare_data, width=80).grid(column=2, row=4, sticky=W) results_label = ttk.Label(self, textvariable=self.results_text, state="readonly") results_label.grid(column=2, row=5, sticky=(W, E)) for child in self.winfo_children(): child.grid_configure(padx=5, pady=5) ctf_entry.focus() def open_ctf_file(self): logging.debug("open_ctf_file") filename = filedialog.askopenfilename(filetypes=(("CTF file", "*.ctf"), ), initialdir=self.default_folder) logging.debug(filename) self.filepath_ctf.set(filename) basename = os.path.splitext(filename)[0] if os.path.isdir(basename + "Images"): self.image_folder.set(basename + "Images") elif os.path.isdir(basename + "_Images"): self.image_folder.set(basename + "_Images") def open_image_folder(self): logging.debug("open_image_folder") folder_name = filedialog.askdirectory(initialdir=self.default_folder) logging.debug(folder_name) self.image_folder.set(folder_name) def prepare_data(self): logging.debug("prepare_data") self.find_pattern_parameters() self.create_cpr_file() self.rename_image_folder() if self.pcx == 0.0 or self.pcy == 0.0 or self.dd == 0.0 or self.vh_ratio == 0.0: self.results_text.set("Error") else: self.results_text.set("Completed") def find_pattern_parameters(self): logging.debug("find_pattern_parameters") number_files = 0 extension = "" folder_name = self.image_folder.get() for filename in sorted(os.listdir(folder_name), reverse=True): try: basename, extension = os.path.splitext(filename) items = basename.split("_") number_files = int(items[-1]) break except: pass logging.debug(number_files) logging.debug(filename) start = filename.rfind("_%i" % (number_files)) image_filename = filename[:start + 1] + "%0*i" % (len( str(number_files)), number_files / 2) + extension logging.debug(image_filename) image_filepath = os.path.join(folder_name, image_filename) image = Image.open(image_filepath) for items in image.tag.values(): logging.debug(items) try: root = ET.fromstring(items[0]) logging.debug(root.tag) logging.debug(root.attrib) for element in root.iter('pattern-center-x-pu'): self.pcx = float(element.text) for element in root.iter('pattern-center-y-pu'): self.pcy = float(element.text) for element in root.iter('detector-distance-pu'): self.dd = float(element.text) except (TypeError, ET.ParseError): pass def create_cpr_file(self): logging.debug("create_cpr_file") lines = [] lines.append("\n") line = "VHRatio=%.5f\n" % (self.vh_ratio.get()) lines.append(line) line = "PCX=%.17f\n" % (self.pcx) lines.append(line) line = "PCY=%.17f\n" % (self.pcy) lines.append(line) line = "DD=%.17f\n" % (self.dd) lines.append(line) line = "IsFake=false;\n" lines.append(line) line = "// set isfake to true for X_Y image names and false for HLK style image names.\n" lines.append(line) filepath_ctf = self.filepath_ctf.get() filepath_cpr = os.path.splitext(filepath_ctf)[0] + ".cpr" logging.debug(filepath_cpr) with open(filepath_cpr, 'w') as file_cpr: file_cpr.writelines(lines) def rename_image_folder(self): logging.debug("rename_image_folder") folder_name = self.image_folder.get() if folder_name.endswith("_Images"): logging.debug(folder_name) start = folder_name.rfind("_Images") new_folder_name = folder_name[:start] + "Images" logging.debug(new_folder_name) try: os.replace(folder_name, new_folder_name) except OSError as message: logging.error(message)
class Collection_Widget(Frame): def __init__(self, parent, controller, system=None, num_channels=None, background_color=None): if system == None: self.system = controller.system if num_channels == None: num_channels = controller.channels if background_color == None: background_color = controller.widget_background font1 = font.Font(family='Calibri', size=12, weight='bold') font2 = font.Font(family='Verdana', size=8) font3 = font.Font(family='Verdana', size=10, weight='bold') Frame.__init__(self, parent) self.configure(borderwidth=3, relief="ridge") self.configure(height=8, width=5) self.configure(bg=background_color) self.button_width = 20 self.main_title = 'Collection Control' self.title_label = Label(self, text=self.main_title, bg=background_color).pack() self.samples_frame = Frame(self, bg=background_color) self.samples = IntVar() self.samples_label = Label(self.samples_frame, text="Samples", font=font1, bg=background_color, width=self.button_width).pack(side='left', fill=X) self.samples_entry = Entry(self.samples_frame, textvariable=self.samples, bg=background_color, width=self.button_width).pack(side='right', fill=X) self.samples_frame.pack(side='top') self.time = DoubleVar() self.time_frame = Frame(self, bg=background_color) self.sample_time = Label(self.time_frame, text="Sample Time (s)", font=font1, bg=background_color, width=self.button_width).pack(side='left', fill=X) self.time_entry = Entry(self.time_frame, textvariable=self.time, bg=background_color, width=self.button_width).pack(side='right', fill=X) self.time_frame.pack(side='top') self.start_collection_button = Button(self, text="Start Collection", command=self.start_coll, bg="green2", width=2 * self.button_width) self.start_collection_button.pack(side="bottom") def start_coll(self): self.system.start_collection(self.samples.get(), self.time.get()) def getVals(self): vals = [] vals.append(self.samples.get()) vals.append(self.time.get()) return vals def toggleButtons(self): if str(self.start_collection_button['state']) == 'disabled': self.start_collection_button['state'] = 'normal' elif str(self.start_collection_button['state']) == 'normal': self.start_collection_button['state'] = 'disabled'
class Calc: def __init__(self, master): self.master = master self.master.title("Calculator") #self.master.geometry("400x300") self.master.bind('<Return>', self.get_field) self.total = 0 self.total_var = DoubleVar() self.total_var.set(self.total) self.expression = '' self.exp = StringVar() self.exp_label = Label(self.master, textvariable=self.exp) self.exp_label.grid(row=0, column=0) self.total_label = Label(self.master, textvariable=self.total_var) self.total_label.grid(row=0, column=1) # optional input field self.enter = Entry(self.master) self.enter.grid(row=1, column=1) # creating operation buttons self.plus = Button(self.master, text='+', command=lambda: self.update('+')) self.plus.grid(row=4, column=3) self.minus = Button(self.master, text='-', command=lambda: self.update('-')) self.minus.grid(row=5, column=3) self.multiply = Button(self.master, text='*', command=lambda: self.update('*')) self.multiply.grid(row=2, column=3) self.divide = Button(self.master, text='/', command=lambda: self.update('/')) self.divide.grid(row=3, column=3) self.delete = Button(self.master, text='del', command=lambda: self.update('del')) self.delete.grid(row=1, column=2) self.mod = Button(self.master, text='%', command=lambda: self.update('%')) self.mod.grid(row=5, column=2) self.exponent = Button(self.master, text='^', command=lambda: self.update('**')) self.exponent.grid(row=6, column=2) self.dot = Button(self.master, text='.', command=lambda: self.update('.')) self.dot.grid(row=5, column=1) self.equal = Button(self.master, text='=', command=lambda: self.update('=')) self.equal.grid(row=6, column=3) self.reset = Button(self.master, text='C', command=lambda: self.update('C')) self.reset.grid(row=1, column=3) # start with 2 row and default column row = 2 column = 0 # create 9 integers buttons for num in range(10): # add function to every button, on press -> add number to expression number = Button(self.master, text=str(num), command=lambda num=num: self.update(str(num))) number.grid(row=row, column=column) # numbers will be in 3 columns if it's third column -> move to next row if column == 2: column = 0 row += 1 else: column += 1 def get_field(self, event): # in input field empty we use existing total if self.enter.get() == "": self.expression += str(self.total) # if input start with operation -> use existing total as first number elif self.enter.get()[0] in "+-/*%": self.expression = str(self.total_var.get()) + self.enter.get() else: self.expression += self.enter.get() self.exp.set(self.expression) self.enter.delete(0, END) def update(self, char): # clear all if char == 'C': self.expression = "" self.total = 0 # delete last element from expression elif char == "del": self.expression = self.expression[:-1] elif char == '=': try: # evaluate expression self.total = eval(self.expression) self.expression = "" except NameError: messagebox.showerror("Error", "You entered character") except ZeroDivisionError: messagebox.showerror("Error", "You cannot divide by zero") else: # add value to expression self.expression += char # if expression start with operation -> use existing total as first number if self.expression[0] in "+-/*%": self.expression = str(float( self.total_var.get())) + self.expression self.exp.set(self.expression) self.total_var.set(self.total) self.enter.delete(0, END)
class Pump_Channel(Frame): def __init__(self, parent, system, channel_number, background_color=None): font1 = font.Font(family='Calibri', size=12, weight='bold') font2 = font.Font(family='Verdana', size=8) font3 = font.Font(family='Verdana', size=10, weight='bold') Frame.__init__(self, parent) self.config(height=5, width=3) self.configure(bg=background_color) self.button_width = 5 self.ch_title = "Flowrate %s " % str(channel_number) self.ch_label = Label(self, text=self.ch_title, font=font1, bg=background_color) self.flowrate_label = Label(self, text="(uL/m)", font=font2, bg=background_color) self.flowrate = DoubleVar() self.flowrate_entry = Entry(self, textvariable=self.flowrate, width=self.button_width) # self.flowrate_entry.config(width=10) self.start_button = Button(self, text="START", width=self.button_width, bg='green2', font=font3) self.stop_button = Button(self, text="STOP", width=self.button_width, bg='red2', font=font3) #functions self.start_button['command'] = lambda: system.start_pump_channel( channel_number, self.flowrate.get()) self.stop_button['command'] = lambda: system.stop_pump_channel( channel_number) #add validation for entry using vcmd self.ch_label.pack(side="left", fill=BOTH, expand=1, padx=5) self.flowrate_entry.pack(side="left", fill=X, expand=1) self.flowrate_label.pack(side="left", fill=X, expand=1) self.start_button.pack(side="left", fill=BOTH, expand=1) self.stop_button.pack(side="left", fill=BOTH, expand=1) self.buttons = [self.start_button, self.stop_button] def getFlowRate(self): return self.flowrate.get() def toggleButtons(self): print('togglin 2') for button in self.buttons: if str(button['state']) == 'disabled': button['state'] = 'normal' elif str(button['state']) == 'normal': button['state'] = 'disabled'
def test_default(self): v = DoubleVar(self.root) self.assertEqual(0.0, v.get())
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')
def test_invalid_value(self): v = DoubleVar(self.root, name="name") self.root.globalsetvar("name", "value") with self.assertRaises((ValueError, TclError)): v.get()
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)
class SmashCalc(ttk.Frame): def __init__(self, parent): print("SmashCalc __init__") ttk.Frame.__init__(self, parent) self.parent = parent self.chars_url = "{}/characters".format(api_url) self.get_chars() self.init_ui() self.rage = 1 self.move_name = "" self.enemy_weight = -1 def init_ui(self): print("UI init") self.set_title() # charbox = ttk.Listbox() print("making frames") print(type(self.parent)) self.content = ttk.Frame(self.parent, padding=10) print(type(self.content)) self.content.grid(column=0, row=0, sticky="NSEW") # self.user_image # self.enemy_image print("making boxes") self.init_user() self.init_enemy() self.init_move() def init_user(self): self.user_frame = ttk.Frame(self.content, borderwidth=2) self.user_frame.grid(column=0, row=0) self.user_frame['padding'] = (20, 10) # self.user_frame['borderwidth'] = 2 self.user_frame['relief'] = 'sunken' self.user_label = ttk.Label(self.user_frame, text="Attacker") self.user_label.grid(column=0, row=0, columnspan=2, rowspan=1) self.userchar = StringVar() self.userchar.set('none') self.user_menu = ttk.Combobox(self.user_frame) self.user_menu.grid(column=0, row=1, columnspan=2, rowspan=1) self.user_menu['values'] = self.chars self.user_menu.bind('<<ComboboxSelected>>', self.on_user_menu_input) self.userdmg = StringVar() self.userdmg.set('') self.userdmg.trace('w', self.on_user_damage_input) self.rage_box = ttk.Label(self.user_frame, text="Rage multiplier:") self.rage_box.grid(column=0, row=5, columnspan=2, sticky="W") self.user_percentbox = ttk.Label(self.user_frame, text="%:") self.user_percentbox.grid(column=0, row=2, columnspan=1, rowspan=1, sticky="W") validate_cmd = (self.register(self.on_percent_validate), '%d', '%S', '%P') self.user_damage_entry = ttk.Entry(self.user_frame, textvariable=self.userdmg, validate="key", validatecommand=validate_cmd) self.user_damage_entry.grid(column=1, row=2, columnspan=1, rowspan=1, sticky="W") def init_enemy(self): self.enemy_frame = ttk.Frame(self.content, borderwidth=2) self.enemy_frame.grid(column=1, row=0) self.enemy_frame['padding'] = (20, 10) # self.enemy_frame['borderwidth'] = 2 self.enemy_frame['relief'] = 'sunken' self.enemy_label = ttk.Label(self.enemy_frame, text="Target") self.enemy_label.grid(column=0, row=0, columnspan=2, rowspan=1) self.enemychar = StringVar() self.enemychar.set('none') self.enemy_menu = ttk.Combobox(self.enemy_frame) self.enemy_menu.grid(column=0, row=1, columnspan=2, rowspan=1) self.enemy_menu['values'] = self.chars self.enemy_menu.bind('<<ComboboxSelected>>', self.on_enemy_menu_input) self.enemydmg = StringVar() self.enemydmg.set('') self.enemydmg.trace('w', self.on_enemy_damage_input) self.enemy_percentbox = ttk.Label(self.enemy_frame, text="%:") self.enemy_percentbox.grid(column=0, row=2, columnspan=1, rowspan=1, sticky="W") validate_cmd = (self.register(self.on_percent_validate), '%d', '%S', '%P') self.enemy_damage_entry = ttk.Entry(self.enemy_frame, textvariable=self.enemydmg, validate="key", validatecommand=validate_cmd) self.enemy_damage_entry.grid(column=1, row=2, columnspan=1, rowspan=1, sticky="W") self.weight_box = ttk.Label(self.enemy_frame, text="Weight:") self.weight_box.grid(column=0, row=3, columnspan=2, sticky="W") self.is_crouch = DoubleVar() self.is_smash = DoubleVar() self.is_meteor = DoubleVar() self.is_crouch.set(1) self.is_smash.set(1) self.is_meteor.set(1) self.crouch_check = ttk.Checkbutton(self.enemy_frame, variable=self.is_crouch, text="Crouching", command=self.on_crouch_check, offvalue=1, onvalue=0.85) self.smash_check = ttk.Checkbutton(self.enemy_frame, variable=self.is_smash, text="Charging smash", command=self.on_smash_check, offvalue=1, onvalue=1.2) self.meteor_check = ttk.Checkbutton(self.enemy_frame, variable=self.is_meteor, text="Grounded meteor", command=self.on_meteor_check, offvalue=1, onvalue=0.8) self.crouch_check.grid(column=2, row=1, sticky="W") self.smash_check.grid(column=2, row=2, sticky="W") self.meteor_check.grid(column=2, row=3, sticky="W") def init_move(self): self.move_frame = ttk.Frame(self.content, borderwidth=2) self.move_frame['padding'] = (20, 10) # self.move_frame['borderwidth'] = 2 self.move_frame['relief'] = 'sunken' self.move_frame.grid(column=0, row=1, columnspan=2, sticky="WE") self.move_label = ttk.Label(self.move_frame, text="Attacking move:") self.move_label.grid(column=0, row=0, sticky="W") self.move_menu = ttk.Combobox(self.move_frame) self.move_menu.grid(column=0, row=1, columnspan=1, rowspan=1, sticky="NSEW") self.move_menu['width'] = 40 # self.moves = [] # self.move_menu['values'] = self.moves self.move_menu.bind('<<ComboboxSelected>>', self.on_move_menu_input) self.move_info_frame = MoveFrame(self.move_frame) def get_chars(self): print("getting all char data") response = urllib.request.urlopen( self.chars_url).read().decode('utf-8') chars_data = json.loads(response) self.chars = [] self.name_to_id = {} for char in chars_data: self.chars.append(char['name']) self.name_to_id[char['name']] = char['id'] def set_title(self, title=""): if (title != ""): self.parent.title("SmashCalc - {}".format(title)) else: self.parent.title("SmashCalc") def on_user_menu_input(self, val): self.userchar = self.user_menu.get() print("user entry! {}".format(self.userchar)) moves_url = "{}/characters/{}/moves".format( api_url, self.name_to_id[self.userchar]) response = urllib.request.urlopen(moves_url).read().decode('utf-8') self.moves_data = json.loads(response) self.moves = [] self.move_to_id = {} self.moves_dict = {} for move in self.moves_data: print(type(move)) print(move) # print(type(self.move_to_id)) # print(self.move_to_id) # print("{}, {}".format(move['name'], move['id'])) self.moves.append(move['name']) # self.move_to_id[move['name']] = move['id'] self.moves_dict[move['name']] = move self.set_title(self.userchar) self.move_info_frame.clear_fields() # print(self.moves) # print(self.move_to_id) # print(self.moves_data) self.move_menu['values'] = self.moves # self.movebox = # self.move_data = {} self.update_move_fields(clear=True) def on_enemy_menu_input(self, val): self.enemychar = self.enemy_menu.get() print("enemy entry! {}".format(self.enemychar)) data_url = "{}/characters/{}/characterattributes".format( api_url, self.name_to_id[self.enemychar]) response = urllib.request.urlopen(data_url).read().decode('utf-8') attr_data = json.loads(response) # print(attr_data) for item in attr_data: print(item) print(item['name']) if (item['name'] == 'WEIGHT VALUE'): self.enemy_weight = float(item['value']) print("weight of {} is {}".format(self.enemychar, self.enemy_weight)) self.weight_box['text'] = "Weight: {}".format(int(self.enemy_weight)) self.update_kb() def on_move_menu_input(self, val): # data_url = "{}/characters/{}/characterattributes".format( # api_url, self.name_to_id[self.enemychar]) # response = urllib.request.urlopen(data_url).read().decode('utf-8') # self.move_data = json.loads(response) # print(self.name_to_id) # print(self.moves_data[0]) self.move_name = self.move_menu.get() print(self.moves_dict[self.move_menu.get()]) self.update_move_fields() # self.BKB # self.name # self. self.update_kb() def on_user_damage_input(self, *args): print("user percent changed!") # self.percent = self.userdmg.get() # print(self.percent) print(self.userdmg.get()) if (self.userdmg.get() == ''): return dmg = float(self.userdmg.get()) if (dmg < 35): self.rage = 1 elif (dmg > 150): self.rage = 1.15 else: self.rage = 1 + (dmg - 35) * (.15) / (115) print("rage is now {}".format(self.rage)) self.rage_box['text'] = "Rage multiplier: {: <4.2f}x".format(self.rage) self.update_kb() def on_enemy_damage_input(self, *args): print("enemy percent changed!") if (self.enemydmg.get() != ''): self.update_kb() # validate_cmd = (self.register(self.on_percent_validate), '%d', '%S', '%P') def on_percent_validate(self, why, change, new_value): print("validation") if (why == '1'): print("reason: insertion") elif (why == '0'): print("reason: deletion") else: print("UKNOWN REASON: {}".format(why)) if (new_value == ''): print("empty box") return True try: float(new_value) # self.percent = float(new_value) except ValueError: return False # print(self.percent) # if (self.percent < 35): # self.rage = 1 # elif (self.percent > 150): # self.rage = 1.15 # else: # self.rage = 1 + (self.percent - 35) * (.15) / (115) # print("rage is now {}".format(self.rage)) # self.rage_box['text'] = "Rage multiplier: {: <4.2f}x".format(self.rage) # self.update_kb() return True def on_crouch_check(self): print("crouch: {}".format(self.is_crouch)) self.update_kb() def on_smash_check(self): print("smash: {}".format(self.is_smash)) self.update_kb() def on_meteor_check(self): print("meteor: {}".format(self.is_meteor)) self.update_kb() def update_move_fields(self, clear=False): if (clear): self.move_name = "" self.kb = 0 return else: print(self.moves_dict) print("move name: {}".format(self.move_name)) print(self.moves_dict[self.move_name]) self.move_info_frame.set_fields(self.moves_dict[self.move_name]) self.update_kb() # set_kb(self, target_weight, target_percent, staleness=1, misc_variable=1): def update_kb(self): print("update_kb?") if (self.move_name != "" and self.move_info_frame.empty == False and self.enemy_weight > 0): print("updating") misc_var = float(self.rage) * self.is_crouch.get( ) * self.is_smash.get() * self.is_meteor.get() # Using onvalue and offvalue so don't need these. # if (self.is_crouch): # misc_var = misc_var * 0.85 # if (self.is_smash): # misc_var = misc_var * 1.2 # if (self.is_meteor): # misc_var = misc_var * 0.8 # self.move_info_frame.set_kb(self.enemy_weight, self.enemy_damage_entry.get(), staleness=1, misc_variable=misc_var) self.move_info_frame.set_kb(self.enemy_weight, float(self.enemydmg.get()), staleness=1, misc_variable=misc_var) else: print("nevermind") pass
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 PopupStrategy(Toplevel): def __init__(self, move_stop_profit_params, stop_loss_params, kdj_buy_params, kdj_sell_params, vol_price_fly_params, boll_params, title="Strategy Configturation"): Toplevel.__init__(self) self.is_ok = False self.vol_price_fly_params = vol_price_fly_params self.kdj_sell_params = kdj_sell_params self.kdj_buy_params = kdj_buy_params self.stop_loss_params = stop_loss_params self.move_stop_profit_params = move_stop_profit_params self.boll_params = boll_params self.msf_min = DoubleVar() self.msf_min.set(self.move_stop_profit_params["msf_min"]) self.msf_back = DoubleVar() self.msf_back.set(self.move_stop_profit_params["msf_back"]) self.stop_loss = DoubleVar() self.stop_loss.set(self.stop_loss_params["percent"]) self.k_buy = DoubleVar() self.k_buy.set(self.kdj_buy_params["k"]) self.d_buy = DoubleVar() self.d_buy.set(self.kdj_buy_params["d"]) self.kdj_buy_percent = DoubleVar() self.kdj_buy_percent.set(self.kdj_buy_params["buy_percent"]) self.kdj_up_percent = DoubleVar() self.kdj_up_percent.set(self.kdj_buy_params["up_percent"]) self.k_sell = DoubleVar() self.k_sell.set(self.kdj_sell_params["k"]) self.d_sell = DoubleVar() self.d_sell.set(self.kdj_sell_params["d"]) self.kdj_sell_percent = DoubleVar() self.kdj_sell_percent.set(self.kdj_sell_params["sell_percent"]) self.kdj_down_percent = DoubleVar() self.kdj_down_percent.set(self.kdj_sell_params["down_percent"]) self.vol_percent = DoubleVar() self.vol_percent.set(self.vol_price_fly_params["vol_percent"]) self.vol_buy_sell = DoubleVar() self.vol_buy_sell.set(self.vol_price_fly_params["high_than_last"]) self.price_up_limit = DoubleVar() self.price_up_limit.set(self.vol_price_fly_params["price_up_limit"]) self.vol_buy_percent = DoubleVar() self.vol_buy_percent.set(self.vol_price_fly_params["buy_percent"]) # move_stop_profit = {"msf_min": 0.02, "msf_back": 0.03} # stop_loss = {"percent": 0.03} # kdj_buy = {"k": 18, "d": 20, "buy_percent": 0.1} # kdj_sell = {"k": 85, "d": 80, "sell_percent": 0.1} # vol_price_fly = {"vol_percent": 1.1, "vol_buy_sell": 1.1, "price_up_limit": 0.03, "buy_percent": 0.2} self.setup_ui() self.title(title) def setup_ui(self): row1 = Frame(self) row1.pack(fill="x") self.ckb_stop_profit_val = IntVar( value=self.move_stop_profit_params.get("check", 1)) self.ckb_stop_profit = Checkbutton(row1, text='', variable=self.ckb_stop_profit_val, onvalue=1, offvalue=0).pack(side=LEFT) Label(row1, text="移动止盈:").pack(side=LEFT) row1 = Frame(self) row1.pack(fill="x") Label(row1, text="最小赢利: ", width=15).pack(side=LEFT) Entry(row1, textvariable=self.msf_min, width=15).pack(side=LEFT) Label(row1, text="回撤幅度: ", width=15).pack(side=LEFT) Entry(row1, textvariable=self.msf_back, width=15).pack(side=LEFT) row2 = Frame(self) row2.pack(fill="x", ipadx=1, ipady=1) self.ckb_stop_loss_val = IntVar( value=self.stop_loss_params.get("check", 1)) self.ckb_stop_loss = Checkbutton(row2, text='', variable=self.ckb_stop_loss_val, onvalue=1, offvalue=0).pack(side=LEFT) Label(row2, text="亏损风险控制: ").pack(side=LEFT) Entry(row2, textvariable=self.stop_loss, width=45).pack(side=LEFT) row3 = Frame(self) row3.pack(fill="x", ipadx=1, ipady=1) self.ckb_kdj_buy_val = IntVar( value=self.kdj_buy_params.get("check", 1)) self.ckb_kdj_buy = Checkbutton(row3, text='', variable=self.ckb_kdj_buy_val, onvalue=1, offvalue=0).pack(side=LEFT) Label(row3, text="KDJ买入参考: ").pack(side=LEFT) row4 = Frame(self) row4.pack(fill="x", ipadx=1, ipady=1) Label(row4, text="K小于等于: ", width=10).pack(side=LEFT) Entry(row4, textvariable=self.k_buy, width=5).pack(side=LEFT) Label(row4, text="D小于等于: ", width=10).pack(side=LEFT) Entry(row4, textvariable=self.d_buy, width=5).pack(side=LEFT) Label(row4, text="买入比例: ", width=10).pack(side=LEFT) Entry(row4, textvariable=self.kdj_buy_percent, width=5).pack(side=LEFT) Label(row4, text="回暖幅度: ", width=10).pack(side=LEFT) Entry(row4, textvariable=self.kdj_up_percent, width=5).pack(side=LEFT) Label(row4, text="周期: ").pack(side=LEFT) lst_trade = ['5min', '15min', '30min', '1day'] # self.trade.set(lst_trade[0]) self.kdj_buy_peroid = StringVar() self.kdj_buy_peroid.set(self.kdj_buy_params.get("peroid", "15min")) OptionMenu(row4, self.kdj_buy_peroid, *lst_trade).pack(side=LEFT) row5 = Frame(self) row5.pack(fill="x", ipadx=1, ipady=1) self.ckb_kdj_sell_val = IntVar( value=self.kdj_sell_params.get("check", 1)) self.ckb_kdj_sell = Checkbutton(row5, text='', variable=self.ckb_kdj_sell_val, onvalue=1, offvalue=0).pack(side=LEFT) Label(row5, text="KDJ卖出参考: ").pack(side=LEFT) row6 = Frame(self) row6.pack(fill="x", ipadx=1, ipady=1) Label(row6, text="K大于等于: ", width=10).pack(side=LEFT) Entry(row6, textvariable=self.k_sell, width=5).pack(side=LEFT) Label(row6, text="D大于等于: ", width=10).pack(side=LEFT) Entry(row6, textvariable=self.d_sell, width=5).pack(side=LEFT) Label(row6, text="卖出比例: ", width=10).pack(side=LEFT) Entry(row6, textvariable=self.kdj_sell_percent, width=5).pack(side=LEFT) Label(row6, text="回撤幅度: ", width=10).pack(side=LEFT) Entry(row6, textvariable=self.kdj_down_percent, width=5).pack(side=LEFT) Label(row6, text="周期: ").pack(side=LEFT) lst_trade = ['5min', '15min', '30min', '1day'] # self.trade.set(lst_trade[0]) self.kdj_sell_peroid = StringVar() self.kdj_sell_peroid.set(self.kdj_sell_params.get("peroid", "15min")) OptionMenu(row6, self.kdj_sell_peroid, *lst_trade).pack(side=LEFT) row5 = Frame(self) row5.pack(fill="x", ipadx=1, ipady=1) self.ckb_vol_price_val = IntVar( value=self.vol_price_fly_params.get("check", 1)) self.ckb_vol_price_buy = Checkbutton(row5, text='', variable=self.ckb_vol_price_val, onvalue=1, offvalue=0).pack(side=LEFT) Label(row5, text="量价齐升: ").pack(side=LEFT) row6 = Frame(self) row6.pack(fill="x", ipadx=1, ipady=1) Label(row6, text="总量0-3比3-7: ", width=12).pack(side=LEFT) Entry(row6, textvariable=self.vol_percent, width=5).pack(side=LEFT) Label(row6, text="周期量比: ", width=15).pack(side=LEFT) Entry(row6, textvariable=self.vol_buy_sell, width=5).pack(side=LEFT) Label(row6, text="风险控制: ", width=10).pack(side=LEFT) Entry(row6, textvariable=self.price_up_limit, width=5).pack(side=LEFT) Label(row6, text="买入比例: ", width=10).pack(side=LEFT) Entry(row6, textvariable=self.vol_buy_percent, width=5).pack(side=LEFT) row5 = Frame(self) row5.pack(fill="x", ipadx=1, ipady=1) self.ckb_boll_buy_val = IntVar(value=self.boll_params.get("check", 1)) self.ckb_boll_buy = Checkbutton(row5, text='', variable=self.ckb_boll_buy_val, onvalue=1, offvalue=0).pack(side=LEFT) Label(row5, text="BOLL买入参考: ").pack(side=LEFT) self.open_diff1_percent = DoubleVar() self.open_diff1_percent.set(self.boll_params["open_diff1_percent"]) self.open_diff2_percent = DoubleVar() self.open_diff2_percent.set(self.boll_params["open_diff2_percent"]) self.close_diff1_percent = DoubleVar() self.close_diff1_percent.set(self.boll_params["close_diff1_percent"]) self.close_diff2_percent = DoubleVar() self.close_diff2_percent.set(self.boll_params["close_diff2_percent"]) self.open_down_percent = DoubleVar() self.open_down_percent.set(self.boll_params["open_down_percent"]) self.open_up_percent = DoubleVar() self.open_up_percent.set(self.boll_params["open_up_percent"]) self.open_buy_percent = DoubleVar() self.open_buy_percent.set(self.boll_params["open_buy_percent"]) row6 = Frame(self) row6.pack(fill="x", ipadx=1, ipady=1) Label(row6, text="开上中轨差比例: ", width=15).pack(side=LEFT) Entry(row6, textvariable=self.open_diff1_percent, width=10).pack(side=LEFT) Label(row6, text="开中下轨差比例: ", width=15).pack(side=LEFT) Entry(row6, textvariable=self.open_diff2_percent, width=10).pack(side=LEFT) row6 = Frame(self) row6.pack(fill="x", ipadx=1, ipady=1) Label(row6, text="闭上中轨差比例: ", width=15).pack(side=LEFT) Entry(row6, textvariable=self.close_diff1_percent, width=10).pack(side=LEFT) Label(row6, text="闭中下轨差比例: ", width=15).pack(side=LEFT) Entry(row6, textvariable=self.close_diff2_percent, width=10).pack(side=LEFT) row6 = Frame(self) row6.pack(fill="x", ipadx=1, ipady=1) Label(row6, text="开口跌幅小于: ", width=15).pack(side=LEFT) Entry(row6, textvariable=self.open_down_percent, width=5).pack(side=LEFT) Label(row6, text="超跌回暖幅度大于: ", width=15).pack(side=LEFT) Entry(row6, textvariable=self.open_up_percent, width=5).pack(side=LEFT) Label(row6, text="买入比例: ", width=10).pack(side=LEFT) Entry(row6, textvariable=self.open_buy_percent, width=5).pack(side=LEFT) row3 = Frame(self) row3.pack(fill="x") # Button(row3, text="Reset", command=lambda: self.on_reset(), width=10).pack(side=RIGHT) Button(row3, text="Cancel", command=lambda: self.on_cancel(), width=10).pack(side=RIGHT) Button(row3, text="OK", command=lambda: self.on_ok(), width=10).pack(side=RIGHT) def on_ok(self): try: msf_min = float(self.msf_min.get()) msf_back = float(self.msf_back.get()) stop_loss = float(self.stop_loss.get()) k_buy = float(self.k_buy.get()) d_buy = float(self.d_buy.get()) kdj_buy_percent = float(self.kdj_buy_percent.get()) k_sell = float(self.k_sell.get()) d_sell = float(self.d_sell.get()) kdj_sell_percent = float(self.kdj_sell_percent.get()) vol_percent = float(self.vol_percent.get()) vol_buy_sell = float(self.vol_buy_sell.get()) price_up_limit = float(self.price_up_limit.get()) vol_buy_percent = float(self.vol_buy_percent.get()) open_diff1_percent = float(self.open_diff1_percent.get()) open_diff2_percent = float(self.open_diff2_percent.get()) close_diff1_percent = float(self.close_diff1_percent.get()) close_diff2_percent = float(self.close_diff2_percent.get()) open_down_percent = float(self.open_down_percent.get()) open_up_percent = float(self.open_up_percent.get()) open_buy_percent = float(self.open_buy_percent.get()) except Exception as e: messagebox.showwarning( "Warning", "All parameters must be numeric and cannot be null!" ) # 提出警告对话窗 return self.move_stop_profit_params["check"] = int( self.ckb_stop_profit_val.get()) self.move_stop_profit_params["msf_min"] = msf_min self.move_stop_profit_params["msf_back"] = msf_back self.stop_loss_params["percent"] = stop_loss self.stop_loss_params["check"] = int(self.ckb_stop_loss_val.get()) self.kdj_buy_params["check"] = int(self.ckb_kdj_buy_val.get()) self.kdj_buy_params["k"] = k_buy self.kdj_buy_params["d"] = d_buy self.kdj_buy_params["buy_percent"] = kdj_buy_percent self.kdj_buy_params["up_percent"] = float(self.kdj_up_percent.get()) self.kdj_buy_params["peroid"] = str(self.kdj_buy_peroid.get()) self.kdj_sell_params["check"] = int(self.ckb_kdj_sell_val.get()) self.kdj_sell_params["k"] = k_sell self.kdj_sell_params["d"] = d_sell self.kdj_sell_params["sell_percent"] = kdj_sell_percent self.kdj_sell_params["down_percent"] = float( self.kdj_down_percent.get()) self.kdj_sell_params["peroid"] = str(self.kdj_sell_peroid.get()) self.vol_price_fly_params["check"] = int(self.ckb_vol_price_val.get()) self.vol_price_fly_params["vol_percent"] = vol_percent self.vol_price_fly_params["high_than_last"] = vol_buy_sell self.vol_price_fly_params["price_up_limit"] = price_up_limit self.vol_price_fly_params["buy_percent"] = vol_buy_percent self.boll_params["check"] = int(self.ckb_boll_buy_val.get()) self.boll_params["open_diff1_percent"] = open_diff1_percent self.boll_params["open_diff2_percent"] = open_diff2_percent self.boll_params["close_diff1_percent"] = close_diff1_percent self.boll_params["close_diff2_percent"] = close_diff2_percent self.boll_params["open_down_percent"] = open_down_percent self.boll_params["open_up_percent"] = open_up_percent self.boll_params["open_buy_percent"] = open_buy_percent # self.value_dict["access_key"] = access_key.strip().replace("\n", "") # self.value_dict["secret_key"] = secret_key.strip().replace("\n", "") messagebox.showinfo("Info", "Strategy change have taken effect!") log_config.output2ui("Setup strategy successfully!", 8) self.destroy() def on_cancel(self): self.destroy() def on_reset(self): self.msf_back.set(0.02)
def test_invalid_value(self): v = DoubleVar(self.root, name="name") self.root.globalsetvar("name", "value") with self.assertRaises(ValueError): v.get()
class App(tk.Frame): """ La clase se encargara de crear una ventana que calculara el numero de ciclos de un horneado, con respecto a una formula y datos constantes. """ def __init__(self, master): """ Constructor """ # Variable StringVar IntVar Etc self.tanda_num = IntVar(value="00001") self.qty = StringVar(value=QTYCABLE) self.np = StringVar(value=NUMPART) self.ciclo_text = StringVar( value="Presione calcular para obtener peso y numero de ciclos") self.ciclo_value = DoubleVar(value=0.0) self.peso = StringVar(value="0 kg") self.contador_entry_enable = 0 self.peso_lista = [0, 0] self.data= 0 self.num_data = 0 self.puerto_bascula_windows = "COM19" self.archivo_nombre = None ''' try: #self.archivo_nombre = self.getdb_tanda()+1 #self.archivo_nombre = "Grafico_Tanda_"+str(self.archivo_nombre) #self.archivo_nombre=self.nombre_grafica if PLATFORM == "Linux": file = open("./graficas/"+self.archivo_nombre+".csv", "a") #se crea un archivo con la fecha y el nombre if os.stat("./graficas/"+self.archivo_nombre+".csv").st_size == 0: file.write("Fecha,Exterior,Interior,Sensor 2,Sensor 1\n") file.close() else: file = open(os.getcwd()+"\\graficas\\"+self.archivo_nombre+".csv", "a") #se crea un archivo con la fecha y el nombre if os.stat(os.getcwd()+"\\graficas\\"+self.archivo_nombre+".csv").st_size == 0: file.write("Fecha,Exterior,Interior,Sensor 2,Sensor 1\n") file.close() except Exception as e: print(e) ''' try: self.con = sqlite3.connect("testing.db", detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES) print("Base de datos Iniciada") self.c = self.con.cursor() self.con.close() except Exception as e: print(e) # ESTILOS self.estiloframe = ttk.Style() self.estiloframe.configure('my.TFrame', background=COLOR_JULIAN) self.estiloframe_ent = ttk.Style() self.estiloframe_ent.configure('ent.TFrame', background="#4285F4") self.estiloboton = ttk.Style() self.estiloboton.configure('ent.TButton', font=('Consolas', 18), background="#4285F4", justify= tk.CENTER) self.estiloboton2 = ttk.Style() self.estiloboton2.configure('sal.TButton', font=('Consolas', 18), background="#34a853") self.estiloboton3 = ttk.Style() self.estiloboton3.configure('graf.TButton', font=('Consolas', 18), background="#f65314") self.estiloframe_ent = ttk.Style() self.estiloframe_ent.configure('sal.TFrame', background="#34a853") self.estiloboton3 = ttk.Style() self.estiloboton3.configure('calc.TButton', font=('Consolas', 15), background="#ff7373", relief="sunken") self.estilolabel = ttk.Style() self.estilolabel.configure('my.Label', font=('Consolas', 50), background="azure") self.estilolabel_ent = ttk.Style() self.estilolabel_ent.configure('ent.Label', font=('Consolas', 20), background="#4285F4") self.estilolabel_ent = ttk.Style() self.estilolabel_ent.configure('sal.Label', font=('Consolas', 20), background="#34a853") self.estilolabel_ent.configure('salsubt.Label', font=('Consolas', 15), background="#34a853") self.estiloentry = ttk.Style() self.estiloentry.configure('my.TEntry', fieldbackground='gray93') self.estiloentry.map('my.TEntry', fieldbackground=[('disabled', 'gray75'), ('focus', 'white')],) self.estiloentry = ttk.Style() self.estiloentry.configure('myPeso.TEntry', fieldbackground='white') self.estiloentry.map('myPeso.TEntry', fieldbackground=[('disabled', 'white'), ('focus', 'white')], foreground=[('disabled', 'black')]) self.estilolabel_ent = ttk.Style() self.estilolabel_ent.configure('ciclo.Label', font=('Consolas', 15), background="#4285F4") tk.Frame.__init__(self) # self.grid(sticky=N+S+E+W) self.grid() top = self.winfo_toplevel() top.rowconfigure(0, weight=1) top.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) self.columnconfigure(0, weight=1) ''' self.configurar_frame() # self.maximizar() self.crear_interfaz() ''' try: self.configurar_frame() self.maximizar() self.crear_interfaz() except Exception as error: print(error) self.destroy() # Declaracion de Funciones def maximizar(self): """ El metodo maximiza la ventana dependiendo del sistema operativo por que el programa se testea en windows y linux. """ try: if PLATFORM == "Linux": print("Detectando Sistema Operativo Linux") self.master.attributes('-fullscreen', True) self.master.bind("<Escape>", lambda e: self.askstring_close()) self.master.bind("<Alt-Key-F4>", lambda e: self.askstring_close()) self.master.protocol("WM_DELETE_WINDOW", self.pass_cmd) else: print("Detectando Sistema Operativo Windows") self.master.wm_state('zoomed') #self.margen_top = int(self.master.winfo_height()/4) # print(self.margen_top) self.master.bind("<Escape>", lambda e: self.pass_cmd()) self.master.bind("<Alt-Key-F4>", lambda e: self.askstring_close()) self.master.protocol("WM_DELETE_WINDOW", self.pass_cmd) except tk.TclError as error: print("Error Detectado: ", error) self.destroy() exit(1) def configurar_frame(self): """ El metodo configura el frame, es parte del constructor """ self.master.title("FO Precondicionado - Radiall OBR") # self.master.tk_setPalette(background='#fbbc05') self.config(bg='azure') self.master.config(bg='azure') # self.master.resizable(False,False) # self.master.overrideredirect(1) if PLATFORM == "Linux": # self.master.iconbitmap("@/home/pi/fopreconditionoven/radiall.XBM") img = PhotoImage(file="./rsc/radiall.gif") self.master.call('wm', 'iconphoto', self.master._w, img) else: # self.master.iconbitmap(".\\rsc\\radiall.ico") pass def crear_interfaz(self): self.ventana_main = ttk.Frame(self, borderwidth=5, relief="groove", style='my.TFrame') self.boton_entradas = ttk.Button(self.ventana_main, style='ent.TButton', text="Nuevo Lote de \nPrecondicionado", command=self.interfaz_entradas) self.boton_salidas = ttk.Button(self.ventana_main, style='sal.TButton', text="Cargar Lote de \nPrecondicionado", command=self.interfaz_salidas) self.boton_grafica = ttk.Button(self.ventana_main, style='graf.TButton', text="Abrir Grafica \nde Temperatura", command=self.asktring_name) self.label_titulo = ttk.Label(self, style='my.Label', text="Control Precondicionado") self.ventana_main.grid(row=1, column=0, padx=20, pady=20, sticky=N+S) self.ventana_main.grid_columnconfigure(0,weight=1) # self.boton_entradas.grid(row=0, column=0, padx=25, pady=45, ipadx=20, ipady=20, # sticky=N+S+W+E) # self.boton_salidas.grid(row=0, column=1, padx=25, pady=45, ipadx=20, ipady=20, # sticky=N+S+W+E) self.boton_grafica.grid(row=0, column=0, padx=45, pady=45, ipadx=20, ipady=20, sticky=N+S+W+E) self.label_titulo.grid(row=0, column=0, pady=10, sticky=N) self.grid_rowconfigure(0, minsize=300) def interfaz_entradas(self): # Configuracion self.window_entradas = tk.Toplevel(self.master) self.window_entradas.title("Entradas de Proceso") self.window_entradas.focus_set() ent_top = self.window_entradas.winfo_toplevel() ent_top.rowconfigure(0, weight=1) ent_top.columnconfigure(0, weight=1) self.contador_entry_enable = 0 self.window_entradas.rowconfigure(0, weight=1) self.window_entradas.columnconfigure(0, weight=1) self.window_entradas.configure(background="#4285F4") # Configurar ventana para maximizar, borrar barra y quitar opcion de cerrar. try: if PLATFORM == "Linux": print("Detectando Sistema Operativo Linux") w, h = self.winfo_screenwidth(), self.winfo_screenheight() #self.window_entradas.overrideredirect(1) self.window_entradas.geometry("%dx%d+0+0" % (w, h)) self.window_entradas.focus_set() # <-- move focus to this widget self.window_entradas.bind("<Escape>", lambda e: self.window_entradas.destroy()) self.window_entradas.protocol("WM_DELETE_WINDOW", self.disable_event) else: w, h = self.winfo_screenwidth(), self.winfo_screenheight() w, h = 1366, 768 self.window_entradas.overrideredirect(1) self.window_entradas.geometry("%dx%d+0+0" % (w, h)) self.window_entradas.focus_set() # <-- move focus to this widget self.window_entradas.bind("<Escape>", lambda e: self.window_entradas.destroy()) self.window_entradas.protocol( "WM_DELETE_WINDOW", self.disable_event) except tk.TclError as error: print("Error Detectado: ", error) self.window_entradas.destroy() exit(1) # INTERFAZ DE ENTRADAS PRIMERA PARTE # Interfaz # Primera linea self.tanda_num.set(self.getdb_tanda()+1) self.entradas_frame = ttk.Frame(self.window_entradas, borderwidth=5, relief="sunken", style='ent.TFrame') self.entrada_tanda_label = ttk.Label(self.entradas_frame, text="Tanda: ", style="ent.Label") self.entrada_tanda_entry = ttk.Entry(self.entradas_frame, font=FONT, width=8, textvariable=self.tanda_num, justify="center", state='disabled', style='myPeso.TEntry') self.entrada_peso_label = ttk.Label(self.entradas_frame, text="Peso: ", style="ent.Label") self.entrada_peso_entry = ttk.Entry(self.entradas_frame, font=FONT, width=14, textvariable=self.peso, justify="center", state='disabled', style='myPeso.TEntry') self.boton_peso = ttk.Button(self.entradas_frame, text="Calcular", style="calc.TButton", cursor="hand2", command=self.calcular_peso) self.boton_enviar = ttk.Button(self.entradas_frame, text="Enviar", style="calc.TButton", cursor="hand2", command=self.enviar_db) self.ciclo_label = ttk.Label(self.entradas_frame, textvariable=self.ciclo_text, style="ciclo.Label") self.entradas_frame.grid(row=0, column=0) self.entrada_tanda_label.grid(row=0, column=0, padx=2, pady=10, sticky=E) self.entrada_tanda_entry.grid(row=0, column=1, padx=2, pady=10, sticky=W) self.entrada_peso_label.grid(row=0, column=2, padx=2, pady=10, sticky=E) self.entrada_peso_entry.grid(row=0, column=3, padx=2, pady=10, sticky=W) self.boton_peso.grid(row=0, column=4, padx=2, pady=10) self.tabla_frame = ttk.Frame(self.entradas_frame, borderwidth=5, relief="sunken", style='ent.TFrame') self.tabla_frame.grid(row=1, column=0, columnspan=5, sticky=N) self.boton_enviar.grid(row=2, column=4, sticky=E, pady=10, padx=10) self.ciclo_label.grid(row=2, column=1, columnspan=3, pady=1, padx=15) vcmd_mo_parte = (self.register(self.onValidate_mo_parte), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W') vcmd_longitud = (self.register(self.onValidate_longitud), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W') # TABLA DE ENTRADAS INTERFAZ height = 15 width = 4 self.tabla = {} self.tabla_titulos = ("MO", "Part Number", "Long_Inicial 1", "Long_Inicial 2") counter = 0 self.tabla_ent_valores = [] self.mo_valor = [] self.np_valor = [] self.lini_valor = [] self.lfin_valor = [] for k in range(4): self.ltitulo_tabla = ttk.Label(self.tabla_frame, text=str(self.tabla_titulos[k]), style="ent.Label") self.ltitulo_tabla.grid(row=0, column=k+1) for i in range(height): # Rows self.num_tabla = ttk.Label(self.tabla_frame, text=i+1, style="ent.Label") for j in range(width): # Columns if i == 0 and j == 0: self.tabla = ttk.Entry(self.tabla_frame, text="", width=25, font=FONT_TABLA, justify="center", state='enabled', style='my.TEntry') else: self.tabla = ttk.Entry(self.tabla_frame, text="", width=25, font=FONT_TABLA, justify="center", state='disabled', style='my.TEntry') self.tabla.grid(row=i+1, column=j+1, padx=1, pady=2) if counter % 4 == 0: self.tabla.configure(validate="key", validatecommand=vcmd_mo_parte) self.mo_valor.append(self.tabla) if (counter-1) % 4 == 0: self.tabla.configure(validate="key", validatecommand=vcmd_mo_parte) self.np_valor.append(self.tabla) if (counter-2) % 4 == 0: self.tabla.configure(validate="key", validatecommand=vcmd_longitud) self.lini_valor.append(self.tabla) if (counter-3) % 4 == 0: self.tabla.configure(validate="key", validatecommand=vcmd_longitud) self.lfin_valor.append(self.tabla) counter += 1 self.tabla_ent_valores.append(self.tabla) self.num_tabla.grid(row=i+1, column=0) total_entrys = len(self.tabla_ent_valores) for x in range(total_entrys): self.tabla_ent_valores[x].bind('<Return>', self.siguiente_entry) # self.mo_valor[0].configure(validate="key",validatecommand=vcmd_mo_parte) print("Se generaron {0} filas y {1} columnas".format(height, width)) ''' #Testing Getters l:278 for i in range(15): self.lfin_valor[i].insert(0,"hola") ''' def interfaz_salidas(self): # Configuracion if DEBUG == False or DEBUG == True: print("Desarrollo") self.ventana_main.lower(belowThis=None) messagebox.showwarning("Error", "Pagina en Desarrollo", parent=self.ventana_main) self.ventana_main.bell() self.ventana_main.lift(aboveThis=None) self.ventana_main.focus_set() return self.window_salidas = tk.Toplevel(self.master) self.window_salidas.title("Entradas de Proceso") self.window_salidas.focus_set() ent_top = self.window_salidas.winfo_toplevel() ent_top.rowconfigure(0, weight=1) ent_top.columnconfigure(0, weight=1) self.window_salidas.rowconfigure(0, weight=1) self.window_salidas.columnconfigure(0, weight=1) self.window_salidas.configure(background="#34a853") # Configurar ventana para maximizar, borrar barra y quitar opcion de cerrar. try: if PLATFORM == "Linux": print("Detectando Sistema Operativo Linux") w, h = self.winfo_screenwidth(), self.winfo_screenheight() self.window_salidas.overrideredirect(1) self.window_salidas.geometry("%dx%d+0+0" % (w, h)) self.window_salidas.focus_set() # <-- move focus to this widget self.window_salidas.bind("<Escape>", lambda e: self.window_salidas.destroy()) self.window_salidas.protocol( "WM_DELETE_WINDOW", self.disable_event) else: w, h = self.winfo_screenwidth(), self.winfo_screenheight() w, h = 1366, 768 self.window_salidas.overrideredirect(1) self.window_salidas.geometry("%dx%d+0+0" % (w, h)) self.window_salidas.focus_set() # <-- move focus to this widget self.window_salidas.bind("<Escape>", lambda e: self.window_salidas.destroy()) self.window_salidas.protocol( "WM_DELETE_WINDOW", self.disable_event) except tk.TclError as error: print("Error Detectado: ", error) self.window_salidas.destroy() exit(1) # Interfaz # Primera linea self.tanda_num.set("hola") self.entradas_frame = ttk.Frame(self.window_salidas, borderwidth=5, relief="sunken", style='sal.TFrame') self.entrada_tanda_label = ttk.Label(self.entradas_frame, text="Tanda: ", style="sal.Label") self.entrada_tanda_entry = ttk.Entry(self.entradas_frame, font=FONT, width=8, textvariable=self.tanda_num, justify="center") self.entrada_peso_label = ttk.Label(self.entradas_frame, text="Peso: ", style="sal.Label") self.entrada_peso_entry = ttk.Entry(self.entradas_frame, font=FONT, width=8, textvariable=self.tanda_num, justify="center") self.boton_peso = ttk.Button(self.entradas_frame, text="Calcular", style="calc.TButton", cursor="hand2", command=self.disable_event) self.boton_enviar = ttk.Button(self.entradas_frame, text="Enviar", style="calc.TButton", cursor="hand2", command=self.disable_event) self.entradas_frame.grid(row=0, column=0) self.entrada_tanda_label.grid(row=0, column=0, padx=2, pady=10, sticky=E) self.entrada_tanda_entry.grid(row=0, column=1, padx=2, pady=10, sticky=W) self.entrada_peso_label.grid(row=0, column=2, padx=2, pady=10, sticky=E) self.entrada_peso_entry.grid(row=0, column=3, padx=2, pady=10, sticky=W) self.boton_peso.grid(row=0, column=4, padx=2, pady=10) self.tabla_frame = ttk.Frame(self.entradas_frame, borderwidth=5, relief="sunken", style='sal.TFrame') self.tabla_frame.grid(row=2, column=0, columnspan=5, sticky=N) self.boton_enviar.grid(row=3, column=4, sticky=E) self.tabla = {} self.tabla_titulos = ("Ciclo 1", "Ciclo 2", "Ciclo 3") self.tabla_subtitulos = ("Long_Final 1", "Long_Final 2", "Long_Final 1", "Long_Final 2", "Long_Final 1", "Long_Final 2") for k in range(6): self.subtitulo_tabla = ttk.Label(self.tabla_frame, text=str( self.tabla_subtitulos[k]), style="salsubt.Label") self.subtitulo_tabla.grid(row=1, column=(k+1)) self.ltitulo_tabla1 = ttk.Label(self.tabla_frame, text=str(self.tabla_titulos[0]), style="sal.Label") self.ltitulo_tabla2 = ttk.Label(self.tabla_frame, text=str(self.tabla_titulos[1]), style="sal.Label") self.ltitulo_tabla3 = ttk.Label(self.tabla_frame, text=str(self.tabla_titulos[2]), style="sal.Label") self.ltitulo_tabla1.grid(row=0, column=1, columnspan=2) # Cosa curiosa no me dejo hacerlo en for loop por que esta de abajo # Requeria instanciarse asi y no se por que pero funciono. self.ltitulo_tabla2.grid(row=0, column=2, columnspan=4) self.ltitulo_tabla3.grid(row=0, column=5, columnspan=6) counter = 0 height = 15 width = 6 for i in range(height): # Rows self.num_tabla = ttk.Label(self.tabla_frame, text=i+1, style="sal.Label") for j in range(width): # Columns self.tabla[counter] = ttk.Entry(self.tabla_frame, text="", width=20, font=FONT_TABLA, justify="center") self.tabla[counter].grid(row=i+2, column=j+1, padx=1, pady=2) counter += 1 self.num_tabla.grid(row=i+2, column=0) print("Se generaron {0} filas y {1} columnas".format(height, width)) def interfaz_grafica(self): # Configuracion mpl.style.use("seaborn") #self.archivo_nombre = self.getdb_tanda()+1 #self.archivo_nombre = "Grafico_Tanda_"+str(self.archivo_nombre) self.window_grafica = tk.Toplevel(self.master) self.window_grafica.title("Grafica de Control") self.window_grafica.focus_set() ent_top = self.window_grafica.winfo_toplevel() ent_top.rowconfigure(0, weight=1) ent_top.columnconfigure(0, weight=1) self.window_grafica.rowconfigure(0, weight=1) self.window_grafica.columnconfigure(0, weight=1) #self.window_grafica.configure(background="#f65314") #red self.window_grafica.configure(background="white") #white # Configurar ventana para maximizar, borrar barra y quitar opcion de cerrar. try: if PLATFORM == "Linux": print("Detectando Sistema Operativo Linux") w, h = self.winfo_screenwidth(), self.winfo_screenheight() #self.window_grafica.overrideredirect(1) self.window_grafica.geometry("%dx%d-0-10" % (w, h+50)) self.window_grafica.resizable(0,0) self.window_grafica.focus_set() # <-- move focus to this widget self.window_grafica.bind("<Escape>", lambda e: self.askstring_close_grafica()) self.window_grafica.bind("<Alt-Key-F4>", lambda e: self.askstring_close_grafica()) self.window_grafica.protocol("WM_DELETE_WINDOW", self.pass_cmd) self.window_grafica.bind("<ButtonPress-1>", lambda e: self.pass_cmd()) self.window_grafica.bind("<Alt-Key-Tab>", lambda e: self.pass_cmd()) else: w, h = self.winfo_screenwidth(), self.winfo_screenheight() w, h = 1366, 768 #self.window_entradas.overrideredirect(1) self.window_grafica.geometry("%dx%d+0+0" % (w, h)) self.window_grafica.focus_set() # <-- move focus to this widget #self.window_grafica.bind("<Escape>", # lambda e: self.window_grafica.destroy()) self.window_grafica.bind("<Alt-Key-F4>", lambda e: self.pass_cmd()) self.window_grafica.protocol("WM_DELETE_WINDOW", self.pass_cmd) except tk.TclError as error: print("Error Detectado: ", error) self.window_grafica.destroy() exit(1) GW,GH = (w/DPI-2.5),(h/DPI-0.5) print(GW,GH) self.fig = plt.Figure(figsize=(GW,GH), dpi=DPI) canvas = FigureCanvasTkAgg(self.fig, master=self.window_grafica) canvas.get_tk_widget().config(relief=tk.FLAT,borderwidth=1) temp_frame = tk.Frame(self.window_grafica) try: if PLATFORM == "Linux": self.temp=serial_temp("/dev/ttyUSB0") else: self.temp=serial_temp("COM20") except: self.window_grafica.lower(belowThis=None) messagebox.showwarning("Error", "Conectar puerto serie", parent=self.window_grafica) self.window_grafica.bell() self.window_grafica.lift(aboveThis=None) self.window_grafica.focus_set() self.window_grafica.destroy() x = np.arange(1, 4601, 1) # Primeros 100 datos y1 = [0] *4600 #Bando de Datos, y primeros 100 ceros y2 = [0] *4600 y3 = [0] *4600 y4 = [0] *4600 #Bando de Datos, y primeros 4600 ceros ax = self.fig.add_subplot(111,ylim=[20,131], xscale='linear', xticks=arange(0,4600,500), xlabel="Tiempo",ylabel="Temperatura Precondicionado", yticks=arange(20,131,10)) ax.axis([0,4601,0,135]) line1, = ax.plot(x, y1, 'blue', label='Exterior', linestyle="-.",linewidth=1) line2, = ax.plot(x, y2, 'red', label='Interior', linestyle="-.",linewidth=1) line3, = ax.plot(x, y3, 'green', label='Sensor 1',linewidth=1) line4, = ax.plot(x, y4, 'gold', label='Sensor 2',linewidth=1) ls = lines.Line2D([0,4600], [130,130],color='black',linewidth=1) li = lines.Line2D([0,4600], [120,120],color='black',linewidth=1) ax.add_line(ls) ax.add_line(li) ax.legend() self.temp_var_ext = StringVar() self.temp_var_int = StringVar() self.temp_var_s2 = StringVar() self.temp_var_s1 = StringVar() self.titulo_var = StringVar() self.titulo_var.set(self.archivo_nombre) temp_frame.grid(column=0, row=1, sticky=N, pady=100) canvas.get_tk_widget().grid(column=1,padx=0,pady=0,row=1,sticky=N, rowspan = 20) label_temp_var_ext = tk.Label(temp_frame, text="", textvariable = self.temp_var_ext, font=("Arial", 20), bg="white").grid(column=0, row=0, sticky = E) label_temp_var_ext = tk.Label(temp_frame, text="", textvariable = self.temp_var_int, font=("Arial", 20), bg="white").grid(column=0, row=1, sticky = E) label_temp_var_ext = tk.Label(temp_frame, text="", textvariable = self.temp_var_s2, font=("Arial", 20), bg="white").grid(column=0, row=2, sticky = E) label_temp_var_ext = tk.Label(temp_frame, text="", textvariable = self.temp_var_s1, font=("Arial", 20), bg="white").grid(column=0, row=3, sticky = E) titulo = tk.Label(self.window_grafica,text="asdasdasd",textvariable= self.titulo_var, font=("Arial", 20), bg="white").grid(column=0, row=0, columnspan=2, sticky=S) def animate(i): if self.data<4600: del y1[0] del y2[0] del y3[0] del y4[0] self.temp.ser_close() self.temp.ser_open() buffer=self.temp.get_data() try: self.temp_ext=float(self.temp.get_data()[0]) self.temp_int=float(self.temp.get_data()[1]) self.temp_s2=float(self.temp.get_data()[2]) self.temp_s1=float(self.temp.get_data()[3]) except Exception as e: print(e) y1.append(self.temp_ext) y2.append(self.temp_int) y3.append(self.temp_s2) y4.append(self.temp_s1) line1.set_ydata(y1) line2.set_ydata(y2) line3.set_ydata(y3) line4.set_ydata(y4) self.temp_var_ext.set(" Exterior: "+ str("{:06.2f}".format(self.temp_ext))) self.temp_var_int.set(" Interior: "+ str("{:06.2f}".format(self.temp_int))) self.temp_var_s2.set( "Sensor 2: "+ str("{:06.2f}".format(self.temp_s2))) self.temp_var_s1.set( "Sensor 1: "+ str("{:06.2f}".format(self.temp_s1))) self.num_data +=1 print("Archivo numero: {0:07d} Nombre: {1}".format(self.num_data, self.archivo_nombre)) if PLATFORM == "Linux": file = open("./graficas/"+self.archivo_nombre+".csv", "a") file.write(str(dt.datetime.now())+","+str(self.temp_ext)+","+str(self.temp_int)+","+str(self.temp_s2)+","+str(self.temp_s1)+"\n") file.close() else: file = open(os.getcwd()+"\\graficas\\"+self.archivo_nombre+".csv", "a") file.write(str(dt.datetime.now())+","+str(self.temp_ext)+","+str(self.temp_int)+","+str(self.temp_s2)+","+str(self.temp_s1)+"\n") file.close() return line1, line2, line3, line4, self.ani = animation.FuncAnimation(self.fig, animate, frames=None, interval=30000, blit=False) def close_grafica(self): self.window_grafica.lower(belowThis=None) messagebox.showwarning("Error", "Una vez iniciada no cerrarla", parent=self.window_grafica) self.window_grafica.bell() self.window_grafica.lift(aboveThis=None) self.window_grafica.focus_set() def disable_event(self): self.window_entradas.lower(belowThis=None) messagebox.showwarning("Error", "Termine para poder cerrar", parent=self.window_entradas) self.window_entradas.bell() self.window_entradas.lift(aboveThis=None) self.window_entradas.focus_set() pass def Hora_Fecha(self): def print_sel(): print(cal.selection_get()) date_window = tk.Toplevel(self.master) date_window.title('Configurar Hora y Fecha') date_window.focus_set() actual_year = int(fechayhora.getdatetime("year")) actual_month = int(fechayhora.getdatetime("month")) actual_day = int(fechayhora.getdatetime("day")) cal = Calendar(date_window, font="Arial 14", selectmode='day', cursor="hand2", year=actual_year, month=actual_month, day=actual_day) cal.pack(fill="both", expand=True) ttk.Button(date_window, text="ok", command=print_sel).pack() def getdb_tanda(self): self.con = sqlite3.connect("precondicionado.db", detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES) self.c = self.con.cursor() cmd = "SELECT COUNT(*) FROM TANDA" self.c.execute(cmd) dato = str(self.c.fetchone()) s = int(0) for s in dato: if s.isdigit(): s = int(s) print(type(s)) return s def calcular_peso(self): if DEBUG != True: if PLATFORM == "Linux": self.pesa = bascula() else: self.pesa = bascula() self.peso_lista = self.pesa.get_peso() if (float(self.peso_lista[0]) > 0): self.peso.set(self.peso_lista[0]+" kg") ciclos = regresion.Regresion( 9514, 125, 90, float(self.peso_lista[0]), 9) ciclos = round(ciclos, 2) self.ciclo_value.set(ciclos) x = self.ciclo_value.get() texto = "Ciclos Requeridos :{0}".format(x) self.ciclo_text.set(str(texto)) self.ciclo_label.configure(style='ent.Label') else: self.window_entradas.lower(belowThis=None) messagebox.showwarning("Error de Conexion", "Coloque material en la bascula", parent=self.window_entradas) self.window_entradas.bell() self.window_entradas.lift(aboveThis=None) self.window_entradas.focus_set() else: print("Modo Debug") self.peso_lista = ("1234", "kg") self.peso.set(self.peso_lista[0]+" kg") self.ciclo_value.set(1231.23) x = self.ciclo_value.get() texto = "Ciclos Requeridos :{0}".format(x) self.ciclo_text.set(str(texto)) self.ciclo_label.configure(style='ent.Label') def onValidate_mo_parte(self, d, i, P, s, S, v, V, W): """ Metodo evalua y valida si se lee numeros de un entry. """ if S.isdigit() or S == "." or S == "-": return True else: self.window_entradas.lower(belowThis=None) messagebox.showwarning("Warning", "Solo Numeros flotantes", parent=self.window_entradas) self.window_entradas.bell() self.window_entradas.lift(aboveThis=None) self.window_entradas.focus_set() self.bell() return False def onValidate_longitud(self, d, i, P, s, S, v, V, W): """ Metodo evalua y valida si se lee numeros y puntos de un entry. """ if S.isdigit(): return True else: self.window_entradas.lower(belowThis=None) messagebox.showwarning("Warning", "Solo numeros Enteros, sin decimales", parent=self.window_entradas) self.window_entradas.bell() self.window_entradas.lift(aboveThis=None) self.window_entradas.focus_set() self.bell() return False def siguiente_entry(self, event): x = len(self.tabla_ent_valores[self.contador_entry_enable].get()) print(x) if self.contador_entry_enable != 59 and x > 0: self.contador_entry_enable += 1 self.tabla_ent_valores[self.contador_entry_enable].configure( state='enabled') self.tabla_ent_valores[self.contador_entry_enable].focus_set() def enviar_db(self): x = 0 if (float(self.peso_lista[0]) > 0): for i in range(15): if self.mo_valor[i].get() != "" and self.np_valor[i].get() != "" and self.lini_valor[i].get() != "" and self.lfin_valor[i].get() != "": ''' print(self.mo_valor[i].get()) print(self.np_valor[i].get()) print(self.lini_valor[i].get()) print(self.lfin_valor[i].get()) ''' x += 1 if x <= 0: self.window_entradas.lower(belowThis=None) messagebox.showerror("Error", "Ninguna Fila esta Completa", parent=self.window_entradas) self.window_entradas.bell() self.window_entradas.lift(aboveThis=None) self.window_entradas.focus_set() self.bell() else: self.window_entradas.lower(belowThis=None) if messagebox.askyesno("Base de datos", "Se van Agregar {} filas".format(x), parent=self.window_entradas): print("enviar a la base de datos") self.db_entrada_set(x) self.window_entradas.bell() self.window_entradas.lift(aboveThis=None) self.window_entradas.focus_set() self.bell() else: self.window_entradas.lower(belowThis=None) messagebox.showerror("Error", "Coloque las piezas y presione Calcular", parent=self.window_entradas) self.window_entradas.bell() self.window_entradas.lift(aboveThis=None) self.window_entradas.focus_set() self.bell() def pass_cmd(self): print("PASS") pass def askstring_close(self): self.contra = simpledialog.askstring("CONTRASEÑA", "DIGITE CONTRA", show='*', parent=self.master) if self.contra == "1945": self.master.destroy() exit() else: print("Error no escribio nada") return def askstring_close_grafica(self): self.window_grafica.bind("<Escape>", lambda e: self.pass_cmd()) print("tsting") self.contra = simpledialog.askstring("DENEGADO", "DIGITE CODIGO PARA SALIR DE LA GRAFICA", show='*', parent=self.window_grafica) if self.contra == "fibra": self.window_grafica.destroy() #quit() else: print("Error no escribio nada") self.window_grafica.lift(aboveThis=None) self.window_grafica.focus_set() del self.contra self.window_grafica.bind("<Escape>", lambda e: self.askstring_close_grafica()) return def asktring_name(self): self.archivo_nombre = simpledialog.askstring("NUMERO DE TABDA", "PORFAVOR INSERTE EL NUMERO DE TANDA", parent=self.master) try: self.archivo_nombre = int(self.archivo_nombre) except: self.master.lower(belowThis=None) messagebox.showerror("Error", "Solo Numeros", parent=self.master) self.master.bell() self.master.lift(aboveThis=None) self.master.focus_set() return if self.archivo_nombre != "" and self.archivo_nombre is not None and isinstance(self.archivo_nombre,int): self.archivo_nombre = "Grafica: Tanda: "+str(self.archivo_nombre) print("Nombre de la grafica ", self.archivo_nombre) print(self.archivo_nombre) self.interfaz_grafica() else: self.master.lower(belowThis=None) messagebox.showerror("Error", "Campo Vacio", parent=self.master) self.master.bell() self.master.lift(aboveThis=None) self.master.focus_set() return try: #self.archivo_nombre = self.getdb_tanda()+1 #self.archivo_nombre = "Grafico_Tanda_"+str(self.archivo_nombre) #self.archivo_nombre=self.nombre_grafica if PLATFORM == "Linux": file = open("./graficas/"+self.archivo_nombre+".csv", "a") #se crea un archivo con la fecha y el nombre if os.stat("./graficas/"+self.archivo_nombre+".csv").st_size == 0: file.write("Fecha,Exterior,Interior,Sensor 2,Sensor 1\n") file.close() else: file = open(os.getcwd()+"\\graficas\\"+self.archivo_nombre+".csv", "a") #se crea un archivo con la fecha y el nombre if os.stat(os.getcwd()+"\\graficas\\"+self.archivo_nombre+".csv").st_size == 0: file.write("Fecha,Exterior,Interior,Sensor 2,Sensor 1\n") file.close() except Exception as e: print(e) def db_entrada_set(self, x): """[summary] Arguments: x {[type]} -- [description] """ con = sqlite3.connect("precondicionado.db", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) c = con.cursor() now = datetime.datetime.now() PESO = self.peso_lista[0] TANDA = self.tanda_num.get() print(type(TANDA)) company_sql = "INSERT INTO TANDA(FECHA, PESO) VALUES (?,?)" c.execute(company_sql, (now, PESO)) con.commit() for i in range(15): if self.mo_valor[i].get() != "" and self.np_valor[i].get() != "" and self.lini_valor[i].get() != "" and self.lfin_valor[i].get() != "": MO = int(self.mo_valor[i].get()) NP = str(self.np_valor[i].get()) MEDIDA_INI1 = int(self.lini_valor[i].get()) MEDIDA_INI2 = int(self.lfin_valor[i].get()) company_sql = '''INSERT INTO CICLO( MO, NP, MEDIDA_INI1, MEDIDA_INI2, MEDIDA_FINA1, MEDIDA_FINA2, MEDIDA_FINB1, MEDIDA_FINB2, RESULTADO_A1, RESULTADO_A2, RESULTADO_B1, RESULTADO_B2, ESTADO, TANDA_ID ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)''' c.execute(company_sql, (MO, NP, MEDIDA_INI1, MEDIDA_INI2,0,0,0,0,0,0,0,0,0, TANDA)) con.commit() """
class ProcessScreen(Frame): progressBarRun = Progressbar progressBarStyle = Style progressNumber = DoubleVar TextProgressProcess = Label scanStructObject = scanStruct log = logController btProcessFinish = Button def configureScreen(self): self.bind("<Configure>", self.configureWidth) self.log = logController() self.progressNumber = DoubleVar() self.progressBarStyle = Style() self.progressBarStyle.theme_use('clam') self.progressBarStyle.configure("Horizontal.TProgressbar", troughcolor='#616161', background="#34A853", lightcolor='#34A853', darkcolor="#34A853") self.progressBarRun = Progressbar(self, style="Horizontal.TProgressbar", variable=self.progressNumber, maximum=10) self.progressBarRun.pack(fill=X, padx=10, pady=10) self.TextProgressProcess = Label(self) self.TextProgressProcess["bg"] = "#9E9E9E" self.TextProgressProcess["font"] = ("Roboto Black", "20") self.TextProgressProcess["fg"] = "white" self.TextProgressProcess.pack(padx=10, pady=15, expand=True) self.btProcessFinish = Button(self) self.btProcessFinish["font"] = ("Roboto Black", "20") self.btProcessFinish["fg"] = "white" self.btProcessFinish["relief"] = "flat" self.btProcessFinish["command"] = self.ProcessFinish def configureWidth(self, event): self.TextProgressProcess["wraplength"] = event.width - 15 def executeProcess(self, dirMainExec): self.scanStructObject = scanStruct(dirMainExec) self.ConfigScan() taskExecuteProcess = Thread(target=self.ExecuteScan, args=[]) taskExecuteProcess.start() def ExecuteScan(self): executeScanTask = Thread(target=self.scanStructObject.execute, args=[]) executeScanTask.start() while (self.scanStructObject.isExecuteProcess): taskUpdProgress = Thread(target=self.updProgressBarRun, args=[]) taskUpdProgress.start() sleep(0.5) if (self.progressNumber.get() == 10): clearTask = Thread(target=self.ClearProgressBar, args=[]) clearTask.start() if (self.scanStructObject.wasFoundSomething): if (len(self.scanStructObject.getApperservers()) > 0): self.master.appservers = self.scanStructObject.getApperservers( ) else: self.master.appservers = {} if (len(self.scanStructObject.getSmartclients()) > 0): self.master.smartclients = self.scanStructObject.getSmartclients( ) else: self.master.smartclients = {} stageTask = Thread(target=self.updExecuteProcess, args=[]) stageTask.start() self.master.resultScreen.clear() self.master.resultScreen.ShowInformationResult() self.btProcessFinish.pack(fill=X, padx=40, pady=20) self.btProcessFinish["bg"] = "#34A853" self.btProcessFinish["text"] = "Proximo >" self.TextProgressProcess[ "text"] = "Pronto, agora é só ver os resultados!! :)" else: self.btProcessFinish.pack(fill=X, padx=40, pady=20) self.btProcessFinish["bg"] = "#EA4335" self.btProcessFinish["text"] = "< Anterior" self.TextProgressProcess[ "text"] = "Não foi encontrado nada nessa pasta :(" def updExecuteProcess(self): self.TextProgressProcess["text"] = "Gerando Cards do resultado..." self.progressNumber.set(10) def ClearProgressBar(self): self.progressNumber.set(0) def updProgressBarRun(self): self.progressNumber.set(self.progressNumber.get() + 1) self.TextProgressProcess[ "text"] = self.scanStructObject.textProgressExecute def ProcessFinish(self): if (self.scanStructObject.wasFoundSomething): self.master.gotoResult() else: self.master.returnToHome() def ClearComponent(self): self.btProcessFinish.pack_forget() self.TextProgressProcess[ "text"] = "Procurando arquivos da estrutura Protheus..." self.ClearProgressBar() def ConfigScan(self): linha = '' StringErro = '' try: with open('configScan.csv', 'r') as configArqCSV: readerArq = reader(configArqCSV, delimiter=';') for linha in readerArq: if (linha[0].upper() == 'APPSERVERKEYS'): for appServerKey in linha: if (appServerKey.upper() == 'APPSERVERKEYS'): pass else: self.scanStructObject.addAppServerKey( appServerKey) if (linha[0].upper() == 'SMARTCLIENTKEYS'): for smartclientKey in linha: if (smartclientKey.upper() == 'SMARTCLIENTKEYS'): pass else: self.scanStructObject.addSmartClientKey( smartclientKey) if (linha[0].upper() == 'RPONAME'): self.scanStructObject.cNameRPO = linha[1] + ".rpo" except Exception as e: StringErro += '###########################################################\n' StringErro += "Erro no CSVConfig: \t" + str(e) + "\n" StringErro += '###########################################################\n' self.log.consoleLogAdd(StringErro)
class Propulsion(Subsystem): """Contains the Propulsion Data.""" def __init__(self, data): """Init the Propulsion.""" self.data = data self.propulsion = data.propulsion self.max_acceleration = DoubleVar() self.no_thrusters = IntVar(value=2) self.power_thruster = DoubleVar(value=750) self.power_total_thruster = QuantityVar(unit="W") self.mass_total_thruster = QuantityVar(unit="g") self.waste_power = QuantityVar(unit="W") def make_entry(self, frame): """Make the Entry Form.""" entry = { "Max Acceneration": { "value": self.max_acceleration, "unit": "m/s²" }, "Thruster Power": { "value": self.power_thruster, "unit": "GW" }, "Number of Thrusters": { "value": self.no_thrusters, "unit": "" }, } self._make_entry(frame, "Propulsion", entry) def make_display(self, frame): """Make the Data Display.""" data = { "Total Thruster Power": { "value": self.power_total_thruster, }, "Total Thruster Mass": { "value": self.mass_total_thruster, }, "Retained Waste Power": { "value": self.waste_power, } } self._make_display(frame, "Propulsion Data", data) def calculate(self): """Do the calculations.""" power_thruster = self.power_thruster.get() * 1e9 # max_acceleration = self.max_acceleration.get() no_thrusters = self.no_thrusters.get() mass_thruster = power_thruster * self.propulsion["Thruster Mass"] / 1e6 power_total_thruster = power_thruster * no_thrusters mass_total_thruster = mass_thruster * no_thrusters waste_power = power_total_thruster * self.propulsion["Waste Factor"] self.data.masses["Thrusters"] = mass_total_thruster self.data.wasteheat["Thrusters"] = waste_power self.data.volumes["Propulsion"] = mass_total_thruster * \ self.propulsion["Volume"] self.data.thruster_data["Power"] = power_total_thruster self.mass_total_thruster.set(mass_total_thruster) self.power_total_thruster.set(power_total_thruster) self.waste_power.set(waste_power)