def setLabels(self): TourLbl = Label(self.frame,text="Tour",font=("Helvetica", 16)) TourLbl.grid(row=0,column=0) TourLbl.config(width=10) TourLblFont = font.Font(self.frame, TourLbl.cget("font")) TourLblFont.configure(underline=True) TourLbl.configure(font=TourLblFont) ReasonLbl = Label(self.frame,text="Late Duration",font=("Helvetica", 16)) ReasonLbl.grid(row=0,column=1) ReasonLbl.config(width=10) ReasonLblFont = font.Font(ReasonLbl, ReasonLbl.cget("font")) ReasonLblFont.configure(underline=True) ReasonLbl.configure(font=ReasonLblFont) TourLbl2 = Label(self.frame,text="Reason",font=("Helvetica", 16)) TourLbl2.grid(row=0,column=2) TourLbl2.config(width=10) TourLbl2Font = font.Font(TourLbl2, TourLbl2.cget("font")) TourLbl2Font.configure(underline=True) TourLbl2.configure(font=TourLbl2Font) NumberLbl = Label(self.frame,text="Number",font=("Helvetica", 16)) NumberLbl.grid(row=0,column=3,columnspan=2) NumberLbl.config(width=10) NumberLblFont = font.Font(NumberLbl, NumberLbl.cget("font")) NumberLblFont.configure(underline=True) NumberLbl.configure(font=NumberLblFont,justify=RIGHT)
def return_z(z_used): try: global c var_z = z_func(z_used) if z_used == z_used: zz = Label(canvas, text=var_z, textvariable=floating_z_value, font=("Times New Roman", 10), bg="#5ae6e6", fg="#ff6b05") c = float(zz.cget("text")) if str(c) != str(z_used): zz.place(relwidth=0.05, relheight=0.02, x=1400, y=420) floating_z_value.set(c) print(zz.cget("text")) return c elif str(c) == str(z_used): print("please try again") except ValueError: messagebox.showinfo("Error", "DO NOT ENTER FOR THIS OPERATION!!!")
def return_x(x_used): try: global a var_x = x_func(x_used) if x_used == x_used: xx = Label(canvas, text=var_x, textvariable=floating_x_value, font=("Times New Roman", 10), bg="#5ae6e6", fg="#ff6b05") a = float(xx.cget("text")) if str(a) != str(x_used): xx.place(relwidth=0.05, relheight=0.02, x=1400, y=180) floating_x_value.set(a) print(xx.cget("text")) return a elif str(a) == str(x_used): print("please try again") except ValueError: messagebox.showinfo("Error", "DO NOT ENTER STRINGS FOR THIS OPERATION!!!")
def return_y(y_used): try: global b var_y = y_func(y_used) if y_used == y_used: yy = Label(canvas, text=var_y, textvariable=floating_y_value, font=("Times New Roman", 10), bg="#5ae6e6", fg="#ff6b05") b = float(yy.cget("text")) if str(b) != str(y_used): yy.place(relwidth=0.05, relheight=0.02, x=1400, y=300) floating_y_value.set(b) print(yy.cget("text")) return b elif str(b) == str(y_used): print("please try again") except ValueError: messagebox.showinfo("Error", "DO NOT ENTER STRINGS FOR THIS OPERATION!!!")
def aboutApp(): # creation about-window if there is not (85 = 9x9 + 4; 260 = 16x16 + 4; 484 = 16x32 + 4) if window.winfo_children().__len__() in (85, 260, 484): aboutWindow = Toplevel(window) aboutWindow.title("About Minesweeper") aboutWindow.geometry("270x125") aboutWindow.resizable(False, False) aboutWindow.wm_geometry("+%d+%d" % ((aboutWindow.winfo_screenwidth() / 2 - aboutWindow.winfo_reqwidth()), (aboutWindow.winfo_screenheight() / 2 - aboutWindow.winfo_reqheight()))) _ = Label(aboutWindow, text="Minesweeper by Andrew Jeus", font=("", 18)).grid(row=0, column=0, padx=10, pady=10) _ = Label(aboutWindow, text="Version 1.0 (12 July 2019)", font=("", 18)).grid(row=1, column=0) labelInfo3 = Label(aboutWindow, text="View code in GitHub", font=("", 14)) labelInfo3.grid(row=2, column=0, padx=5, pady=5) # my font for link to GitHub myfont = font.Font(labelInfo3, labelInfo3.cget("font")) myfont.configure(underline=True) labelInfo3.configure(font=myfont) labelInfo3.bind( "<Button-1>", lambda _: webbrowser.open_new( "https://github.com/MickeyMouseMouse/Minesweeper"))
def echo_func(boolean): try: global echo echoed = the_echo_function(boolean) if boolean == boolean: the_echo = Label(canvas, text=echoed, textvariable=echo_checking, font=("Times New Roman", 10), bg="white", fg="cyan") value = int(the_echo.cget("text")) if value != boolean: if int(value) % 2 != 0: echo = False the_echo = Label(canvas, text=echoed, textvariable=echo_checking, font=("Times New Roman", 10), bg="black", fg="red") the_echo.place(relwidth=0.03, relheight=0.0205, x=927, y=156) echo_checking.set(value) print(echo) return echo, value elif int(value) % 2 == 0: echo = True the_echo = Label(canvas, text=echoed, textvariable=echo_checking, font=("Times New Roman", 10), bg="white", fg="cyan") the_echo.place(relwidth=0.03, relheight=0.0205, x=927, y=156) echo_checking.set(value) print(echo) return echo, value elif value == boolean: print("please try again") except ValueError: messagebox.showinfo("Error", "Only use whole numbers for this operation...")
def aboutApp(self): # creation about-window if there is not if self.window.winfo_children().__len__() == 12: aboutWindow = Toplevel(self.window) aboutWindow.title("About Workouts") aboutWindow.geometry("260x120") aboutWindow.resizable(False, False) aboutWindow.wm_geometry("+%d+%d" % ((aboutWindow.winfo_screenwidth() / 2 - aboutWindow.winfo_reqwidth()), (aboutWindow.winfo_screenheight() / 2 - aboutWindow.winfo_reqheight()))) _ = Label(aboutWindow, text="Workouts by Andrew Jeus", font=("", 18)).grid(row=0, column=0, padx=10, pady=10) _ = Label(aboutWindow, text="Version 1.0 (14 July 2019)", font=("", 18)).grid(row=1, column=0) labelInfo3 = Label(aboutWindow, text="View code in GitHub", font=("", 14)) labelInfo3.grid(row=2, column=0, padx=5, pady=5) # my font for link to GitHub myfont = font.Font(labelInfo3, labelInfo3.cget("font")) myfont.configure(underline=True) labelInfo3.configure(font=myfont) labelInfo3.bind( "<Button-1>", lambda _: webbrowser.open_new( "https://github.com/MickeyMouseMouse/Workouts"))
def run(self): img = None try: r = requests.get(self.bing_image_obj['thumbnailUrl']) if r: data = BytesIO(r.content) img = Image.open(data) except (UnicodeError, OSError, AttributeError): pass try: if img: img.thumbnail((150, 150), Image.ANTIALIAS) tk_img = ImageTk.PhotoImage(img) lbl = Label(self.tk_obj, image=tk_img, borderwidth=5, activebackground="red") lbl.image = tk_img lbl.bind("<Button-1>", self.tk_obj.do_image) lbl.grid(row=self.row, column=self.col, padx=3, pady=3) self.tk_obj.image_dict.update({lbl.cget('image'): img}) except IOError: pass self.queue.put("Task finished")
class Image_(Widget_): def __init__(self, parent_frame, x, y): Widget_.__init__(self, parent_frame, x, y) self.label = Label(self.widget_frame) self.label.pack() self.label_bg, self.label_fg = None, None #def get_(self): # return self.picture def get_info(self): return self.label.cget('text') def settings(self, **kwargs): ''' all setting changes ''' if 'label_bg' in kwargs: self.label.config(bg=kwargs['label_bg']) if 'label_fg' in kwargs: self.label.config(fg=kwargs['label_fg']) if 'image' in kwargs: self.img_path = kwargs['image'] self.picture = Image.open(self.img_path) self.image = ImageTk.PhotoImage(self.picture) self.label.config(image=self.image) if 'resize' in kwargs: self.picture = self.picture.resize(kwargs['resize'], Image.ANTIALIAS) self.image = ImageTk.PhotoImage(self.picture) self.label.config(image=self.image) return
def z_func(zt): zz = Label(canvas, text=zt, textvariable=floating_z_value, font=("Times New Roman", 10), bg="#5ae6e6", fg="#ff6b05") z_var = float(zz.cget("text")) return z_var
def y_func(yt): yy = Label(canvas, text=yt, textvariable=floating_y_value, font=("Times New Roman", 10), bg="#5ae6e6", fg="#ff6b05") y_var = float(yy.cget("text")) return y_var
def x_func(xt): xx = Label(canvas, text=xt, textvariable=floating_x_value, font=("Times New Roman", 10), bg="#5ae6e6", fg="#ff6b05") x_var = float(xx.cget("text")) return x_var
def the_echo_function(echo_or_not): check = echo_or_not get_echo = Label(canvas, text=check, textvariable=echo_checking, font=("Times New Roman", 10), bg="#5ae6e6", fg="#ff6b05") checker = get_echo.cget("text") return checker
def token_function(token): tos = 0 tos += token Toks = Label(canvas, text=tos, textvariable=IntTokens, font=("Times New Roman", 10), bg="#5ae6e6", fg="#ff6b05") tokes = int(Toks.cget("text")) return tokes
def get_key(user): USER = "" USER += user code_entered = Label(canvas, text=USER, textvariable=key_var, font=("Times New Roman", 9), fg="orange", bg="blue") secret_key = code_entered.cget("text") return secret_key
def user_wants(intent): intention = "" intention += intent code_entered = Label(canvas, text=intention, textvariable=string, font=("Times New Roman", 9), fg="orange", bg="blue") code_used = code_entered.cget("text") return code_used
def function_number_five(num_5): S5 = 0 S5 += num_5 Number5 = Label(canvas, text=S5, textvariable=Int5, font=("Times New Roman", 10), bg="#5ae6e6", fg="#ff6b05") numit5 = int(Number5.cget("text")) return numit5
def function_number_four(num_4): f4 = 0 f4 += num_4 Number4 = Label(canvas, text=f4, textvariable=Int4, font=("Times New Roman", 10), bg="#5ae6e6", fg="#ff6b05") numit4 = int(Number4.cget("text")) return numit4
def setWrongDelivery(self): #set labels FehlLbl = Label(self.frame, text="Fehlerhafte Zuführung",font=("Helvetica",16)) FehlLbl.grid(row=9,column=0,columnspan=8) FehlLbl.config(width=20) FehlLblFont = font.Font(FehlLbl,FehlLbl.cget("font")) FehlLblFont.configure(underline=True) FehlLbl.configure(font=FehlLblFont) row = 12 self.setTableLabels(row) self.setTableOneTextFields(row)
def receive_file(self, msg): """Creates a click-able link to request a file that was send to the server""" msg = msg.decode() link = Label(self.view.top, text=msg.split()[5], fg="blue", cursor="hand2") link.pack() link.bind("<Button-1>", lambda e: self.request_file_from_server(link.cget("text"))) msg = msg.split()[1:] return msg
class StatusBar(Frame): def __init__(self, master, **opt): opt.setdefault('font', 'Consolas 8 normal') opt.setdefault('bd', 1) opt.setdefault('relief', SUNKEN) opt.setdefault('anchor', W) opt.setdefault('fg', 'black') opt.setdefault('height', 0) opt.setdefault('padx', 2) opt.setdefault('pady', 0) Frame.__init__(self, master) self.label = Label(self, opt) self.label.pack(fill=X) self.stack = [] def set(self, format, *args, **opt): opt['text'] = format % args self.label.config(**opt) self.label.update_idletasks() def append(self, chars): text = self.label.cget('text') + chars self.label.config(text=text) self.label.update_idletasks() def push(self, format, *args, **opt): delay = opt.pop('delay', 3) current_state = (self.label.cget('text'), self.label.cget('font'), self.label.cget('fg'), self.label.cget('state')) self.stack.append(current_state) self.set(format, *args, **opt) self.after(int(delay * 1000), self.pop) def pop(self): txt, font, fg, state = self.stack.pop() self.set(txt, fg=fg, font=font, stat=state) def clear(self): self.label.config(text="") self.label.update_idletasks()
def return_intention(intended): global code_des code_variable = user_wants(intended) if intended == intended: code = Label(canvas, text=code_variable, textvariable=string, font=("Times New Roman", 9), fg="orange", bg="blue") code_des = str(code.cget("text")) if code_des != intended: code.place(relwidth=0.2875, relheight=0.08, x=1065, y=60) string.set(code_des) print(code_des) return code_des elif code_des == intended: print("please try again")
def return_key(user_key): global ai_key key_needed = get_key(user_key) if user_key == user_key: Key = Label(canvas, text=key_needed, textvariable=key_var, font=("Times New Roman", 9), fg="orange", bg="blue") ai_key = str(Key.cget("text")) if ai_key != user_key: os.environ['OPENAI_API_KEY'] = ai_key openai.api_key = os.environ["OPENAI_API_KEY"] key_var.set(ai_key) messagebox.showinfo("Key is being validated", "A key has been entered") return ai_key, openai.api_key elif ai_key == user_key: print("please try again")
class Button_(Widget_): def __init__(self, parent_frame, x, y): Widget_.__init__(self, parent_frame, x, y) self.label = Label(self.widget_frame) self.label.pack() self.label_bg, self.label_fg = None, None def get_info(self): return self.label.cget('text') def set_text_field(self, label): self.label.config(text=label) def set_settings(self): return
class Textbox(Widget_): def __init__(self, parent_frame, x, y): Widget_.__init__(self, parent_frame, x, y) self.label_width = 20 self.entry_width = 30 self.stringvar = StringVar() self.label = Label(self.widget_frame, width=self.label_width) self.entry = Entry(self.widget_frame, width=self.entry_width, textvariable=self.stringvar) self.label.pack(side=LEFT) self.entry.pack(side=LEFT) self.label_bg, self.label_fg, self.label_hover_bg, self.label_hover_fg = None, None, None, None self.entry_bg, self.entry_fg, self.entry_hover_bg, self.entry_hover_fg = None, None, None, None def get_info(self): return self.label.cget('text'), self.entry.get() def set_text_field(self, label=False, entry=False): if label: self.label.config(text=label) if entry: self.stringvar.set(entry) def set_setting(self): return def set_input_restriction(self, string): def OnValidate(self, d, i, P, s, S, v, V, W, string): if d == 0: return True accepted_inputs = string.split(',') if 'int' in accepted_inputs and S.isdigit(): return True if 'lower' in accepted_inputs: S = S.lower() return True if 'upper' in accepted_inputs: S = S.upper() return True return False self.vcmd = self.widget_frame.register( OnValidate), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W', string self.entry.config(validate="all", validatecommand=self.vcmd) return pass
def F4(n): try: global num4 variable4 = function_number_four(n) if n == n: Number_4 = Label(canvas, text=variable4, textvariable=Int4, font=("Times New Roman", 10), bg="#5ae6e6", fg="#ff6b05") num4 = int(Number_4.cget("text")) if str(num4) != str(n): Number_4.place(relwidth=0.05, relheight=0.02, x=1400, y=540) Int4.set(num4) print(num4) return num4 elif str(num4) == str(n): print("please try again") except ValueError: messagebox.showinfo("Error", "Only use whole numbers for this operation...")
def F5(n2): try: global num5 variable5 = function_number_five(n2) if n2 == n2: Number_5 = Label(canvas, text=variable5, textvariable=Int5, font=("Times New Roman", 10), bg="#5ae6e6", fg="#ff6b05") num5 = int(Number_5.cget("text")) if str(num5) != str(n2): Number_5.place(relwidth=0.05, relheight=0.02, x=1400, y=680) Int5.set(num5) print(num5) return num5 elif str(num5) == str(n2): print("please try again") except ValueError: messagebox.showinfo("Error", "Only use whole numbers for this operation...")
def toks(tok): try: global tokens variable_token = token_function(tok) if tok == tok: t = Label(canvas, text=variable_token, textvariable=IntTokens, font=("Times New Roman", 10), bg="#5ae6e6", fg="#ff6b05") tokens = int(t.cget("text")) if str(tokens) != str(tok): t.place(relwidth=0.05, relheight=0.02, x=1400, y=800) IntTokens.set(tokens) print(tokens) return tokens elif str(tokens) == str(tok): print("please try again") except ValueError: messagebox.showinfo("Error", "Only use whole numbers for this operation...")
def info_callback(): info = tk.Tk() info.title("Python Wave Serial Encoder") info.geometry("400x150") # readme.iconphoto(False, tk.PhotoImage(file='st_icon.png')) title = tk.Label(info, text="Python Wave Serial Encoder", font="Helvetica 16 bold") inft = tk.Label( info, text="Copyright \u00a9 STMicroelectronics 2020\n\n\ Version 1.0.0", ) title.pack() inft.pack() link = Label(info, text="http://www.st.com", fg="blue", cursor="hand2") link.pack() link.bind("<Button-1>", lambda event: webbrowser.open(link.cget("text")))
class Slider: def __init__(self, parent, label, valueCarrier, groupLabel=""): self.instance = Scale(parent, from_=2, to=0, resolution=0.02, length=100, showvalue=0, command=valueCarrier.saveVal) self.valueCarrier = valueCarrier self.groupLabel = groupLabel self._label = None if isinstance(label, str): self._label = Label(parent, text=label) elif isinstance(label, PhotoImage): self._label = Label(parent, image=label) else: raise TypeError( 'Wrong Type. Label must be of type String or PhotoImage!') @property def label(self): return self._label.cget('text') # set pos for slider with label/icon def pos(self, row, column): self.instance.grid(row=row, column=column, padx=(21, 21), pady=5) self._label.grid(row=row + 1, column=column) # activate or deactivate slider def changeState(self, state): if state == DISABLED: self.instance.config(state=DISABLED, fg="#808080") self._label.config(fg="#808080") elif state == NORMAL: self.instance.config(state=NORMAL, fg="#000000") self._label.config(fg="#000000") else: raise ValueError( 'Wrong State. State can be either DISABLED or NORMAL!')
class _Tk_Nosy(object): """This class is the tkinter GUI object""" def __init__(self, master): self.dirname = os.path.abspath( os.curdir ) self.initComplete = 0 self.master = master self.x, self.y, self.w, self.h = -1,-1,-1,-1 # bind master to <Configure> in order to handle any resizing, etc. # postpone self.master.bind("<Configure>", self.Master_Configure) self.master.bind('<Enter>', self.bindConfigure) self.menuBar = Menu(master, relief = "raised", bd=2) top_Directory = Menu(self.menuBar, tearoff=0) top_Directory.add("command", label = "Change Dir", command = self.menu_Directory_Change_Dir) self.menuBar.add("cascade", label="Directory", menu=top_Directory) #top_Snippet = Menu(self.menuBar, tearoff=0) self.menuBar.add("command", label = "Run", command = self.menu_Run) master.config(menu=self.menuBar) # make a Status Bar self.statusMessage = StringVar() self.statusMessage.set(self.dirname) self.statusbar = Label(self.master, textvariable=self.statusMessage, bd=1, relief=SUNKEN) self.statusbar.pack(anchor=SW, fill=X, side=BOTTOM) self.statusbar_bg = self.statusbar.cget('bg') # save bg for restore myFont = tkinter.font.Font(family="Arial", size=12, weight=tkinter.font.BOLD) self.statusbar.config( font=myFont ) frame = Frame(master) frame.pack(anchor=NE, fill=BOTH, side=TOP) self.Pass_Fail_Button = Button(frame,text="Pass/Fail Will Be Shown Here", image="", width="15", background="green", anchor=W, justify=LEFT, padx=2) self.Pass_Fail_Button.pack(anchor=NE, fill=X, side=TOP) self.Pass_Fail_Button.bind("<ButtonRelease-1>", self.Pass_Fail_Button_Click) #self.master.title("tk_nosy") self.master.title('Python %s.%s.%s '%sys.version_info[:3]) self.oscillator = 1 # animates character on title self.oscillator_B = 0 # used to return statusbar to statusbar_bg self.lbframe = Frame( frame ) self.lbframe.pack(anchor=SE, side=LEFT, fill=BOTH, expand=1) scrollbar = Scrollbar(self.lbframe, orient=VERTICAL) self.Text_1 = Text(self.lbframe, width="80", height="24", yscrollcommand=scrollbar.set) scrollbar.config(command=self.Text_1.yview) scrollbar.pack(side=RIGHT, fill=Y) self.Text_1.pack(side=LEFT, fill=BOTH, expand=1) self.master.resizable(1,1) # Linux may not respect this self.numNosyCalls = 0 self.need_to_pick_dir = 1 if len(sys.argv)>1: # I don't care what the exception is, if there's a problem, bail # pylint: disable=W0702 try: dirname = os.path.abspath( sys.argv[1] ) self.try_change_to_new_dir( dirname ) except: pass # let Alarm force dir selection else: try: if os.path.isdir(os.path.join( self.dirname, 'tests' )): self.try_change_to_new_dir( self.dirname ) except: pass # let Alarm force dir selection print(LICENSE) self.Alarm() def try_change_to_new_dir(self, dirname): """A legal abspath will switch to dirname.""" # I don't care what the exception is, if there's a problem, bail # pylint: disable=W0702 if dirname: try: dirname = os.path.abspath( dirname ) except: return # let Alarm force dir selection else: return self.dirname = dirname print('Selected dirname =',dirname) fileD.clear() os.chdir( self.dirname ) self.reset_statusbar_bg() self.need_to_pick_dir = 0 #with open(NOSY_USER_DATA_FILE, 'w') as text_file: # text_file.write( self.dirname ) self.numNosyCalls = 0 def reset_statusbar_bg(self): """Return status bar to default state""" self.statusbar.config(bg=self.statusbar_bg) self.statusMessage.set(self.dirname) def set_statusbar_bg(self, c): """Set status bar to show new color and message""" self.statusbar.config(bg=c) self.oscillator_B = 1 # will return to initial color after a few cycles def menu_Directory_Change_Dir(self): """Menu selection to set directory in which to run nosetests""" dirname = self.AskDirectory( title='Choose Directory For Nose Tests', initialdir=".") if dirname: self.try_change_to_new_dir( dirname ) # >>>>>>insert any user code below this comment for section "menu_Directory_Change_Dir" # replace, delete, or comment-out the following print("called menu_Directory_Change_Dir") def menu_Run(self): """User initiates a nosetests run, not file change detection.""" print("called menu_Run") self.callNosy() def callNosy(self): """Run nosetests and display results""" self.numNosyCalls += 1 self.Text_1.delete(1.0, END) # turn indicator button gray while running the tests myFont = tkinter.font.Font(family="Arial", size=12, weight=tkinter.font.BOLD) self.Pass_Fail_Button.config(background="#999999", text='TESTING...', font=myFont) self.master.update() self.master.update_idletasks() # pylint: disable=W0201 self.passedAllTests, numPassed, numFailed, numErrors, numSkipped, outputTextL = \ run_nosetests(self.numNosyCalls) max_len_s = 42 num_lines = 1 for s in outputTextL: self.Text_1.insert(END, s) sL = s.split('\n') for ss in sL: max_len_s = max(max_len_s, len(ss)) num_lines += 1 if self.numNosyCalls % 2: myFont = tkinter.font.Font(family="Arial", size=12, weight=tkinter.font.BOLD) else: myFont = tkinter.font.Font(family="Arial", size=12) if self.passedAllTests: s = 'PASSED' if numPassed > 1: s = 'PASSED ALL %i TESTS'%numPassed elif numPassed == 1: s = 'PASSED ONE TEST' bg="#00ff00" if numSkipped==1: s = 'passed with 1 SKIP' bg = "#00cc00" elif numSkipped > 1: s = 'passed with %i SKIPS'%numSkipped bg = "#00cc00" elif numPassed==0: s = 'No Tests Found' bg="#ff8000" self.Pass_Fail_Button.config(background=bg, text=s, font=myFont) #self.master.geometry('200x50') else: s = 'FAILED %i, ERRORS %i, SKIP %i, PASSED %i'%(numFailed, numErrors, numSkipped, numPassed) self.Pass_Fail_Button.config(background="#ff0000", text=s, font=myFont) #self.master.geometry('516x385') # Show list of files being watched. #self.Text_1.insert(END, '_'*40+'\n') self.Text_1.insert(END, 'WATCHED *.py FILES'.center(40,'_') + '\n' ) self.Text_1.insert(END, '%s%s..\n\n'%(self.dirname,os.path.sep) ) num_lines += 3 len_dirname = len( self.dirname ) keyL = list(fileD.keys()) keyL.sort() lastdir = '' for key in keyL: dn = os.path.dirname( key ) if dn != lastdir: self.Text_1.insert(END, '..'+dn[len_dirname:] + '\n') max_len_s = max(max_len_s, len(dn)+1) lastdir = dn num_lines += 1 s = ' ' +os.path.basename( key ) self.Text_1.insert(END, s + '\n') max_len_s = max(max_len_s, len(s)+1) num_lines += 1 self.Text_1.config(width=max_len_s) self.Text_1.config(height=min(40, num_lines)) self.master.winfo_toplevel().wm_geometry("") def bindConfigure(self, event): """Part of goofy main window setup in tkinter.""" # tkinter requires arguments, but I don't use them # pylint: disable=W0613 if not self.initComplete: self.master.bind("<Configure>", self.Master_Configure) self.initComplete = 1 # return a string containing directory name def AskDirectory(self, title='Choose Directory', initialdir="."): """Run pop-up menu for user to select directory.""" # This is not an error # pylint: disable=E1101 if sys.version_info < (3,): dirname = tkFileDialog.askdirectory(parent=self.master, initialdir=initialdir,title=title) else: dirname = tkinter.filedialog.askdirectory(parent=self.master, initialdir=initialdir,title=title) return dirname # <-- string def Master_Configure(self, event): """Part of tkinter main window initialization""" if event.widget != self.master: if self.w != -1: return x = int(self.master.winfo_x()) y = int(self.master.winfo_y()) w = int(self.master.winfo_width()) h = int(self.master.winfo_height()) if (self.x, self.y, self.w, self.h) == (-1,-1,-1,-1): self.x, self.y, self.w, self.h = x,y,w,h if self.w!=w or self.h!=h: #print "Master reconfigured... make resize adjustments" self.w=w self.h=h def Pass_Fail_Button_Click(self, event): """Place-holder routine for user clicking Pass/Fail Button""" pass # alarm function is called after specified number of milliseconds def SetAlarm(self, milliseconds=1000): """Reinitialize tkinter alarm mechanism as well as update seconds counter in main window title bar. """ self.master.after( milliseconds, self.Alarm ) self.oscillator += 1 if self.oscillator > 5: self.oscillator = 0 if self.oscillator_B>0: self.oscillator_B += 1 if self.oscillator_B>5: self.oscillator_B = 0 self.reset_statusbar_bg() pad = '|'*self.oscillator #self.master.title("%i) tk_nosy "%self.numNosyCalls + pad ) s = '%s.%s.%s '%sys.version_info[:3] self.master.title('%i) Python %s '%(self.numNosyCalls , s + pad )) def Alarm(self): """Look for changed files every second, then reset alarm""" if self.need_to_pick_dir: dirname = self.AskDirectory( title='Choose Directory For Nose Tests', initialdir=".") self.try_change_to_new_dir( dirname ) #first call to numberOfChangedFiles will be > 0 if any .py files are found elif numberOfChangedFiles( self.dirname ) > 0: # or self.numNosyCalls==0 self.callNosy() self.SetAlarm()
class Textbox(Widget_): def __init__(self, parent_frame, x, y): Widget_.__init__(self, parent_frame, x, y) self.label_width = 15 self.entry_width = 20 self.stringvar = StringVar() self.label = Label(self.widget_frame, width=self.label_width, anchor=E) self.entry = Entry(self.widget_frame, width=self.entry_width, textvariable=self.stringvar, relief=FLAT) self.label.pack(side=LEFT, padx=3) self.entry.pack(side=LEFT) self.label_bg, self.label_fg, self.label_hover_bg, self.label_hover_fg = None, None, None, None self.entry_bg, self.entry_fg, self.entry_focus_bg, self.entry_focus_fg = '#FFFFFF', None, '#D0F2ED', None self.widget_frame.bind('<FocusIn>', lambda event: self.entry.config(bg=self.entry_focus_bg)) self.widget_frame.bind('<FocusOut>', lambda event: self.entry.config(bg=self.entry_bg)) #def get_(self): # return self.entry.get() def get_info(self): return self.label.cget('text'), self.entry.get() def settings(self, **kwargs): if 'label' in kwargs: self.label.config(text=kwargs['label']) if 'entry_state' in kwargs: self.entry_state = kwargs['entry_state'] self.entry.config(state=self.entry_state) if 'entry' in kwargs: if hasattr(self, 'entry_state') and self.entry_state == DISABLED: self.entry.config(state=NORMAL) self.stringvar.set(kwargs['entry']) if hasattr(self, 'entry_state') and self.entry_state == DISABLED: self.entry.config(state=DISABLED) if 'label_bg' in kwargs: self.label_bg = kwargs['label_bg'] self.label.config(bg=self.label_bg) if 'label_fg' in kwargs: self.label_fg = kwargs['label_fg'] self.label.config(fg=self.label_fg) def set_input_restriction(self, string): def OnValidate(d, i, P, s, S, v, V, W, string): if d == 0: return True accepted_inputs = string.split(',') if 'int' in accepted_inputs and S.isdigit(): return True if 'lower' in accepted_inputs: S = S.lower() return True if 'upper' in accepted_inputs: S = S.upper() return True return False self.vcmd = self.widget_frame.register(OnValidate), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W', string self.entry.config(validate="all", validatecommand=self.vcmd) return pass
class Tk_Nosy(object): """This class is the tkinter GUI object""" # make a collection of python interpreters to choose from pythonInterpreterCollection = None # will be PyInterpsOnSys object # extra python interpreters can run nosetests concurrently to main window # concurrent_versionL contains tuples = (PI, Popup) concurrent_versionL = [] # additional running python interpreters def __init__(self, master): self.dirname = os.path.abspath( os.curdir ) self.initComplete = 0 self.master = master self.x, self.y, self.w, self.h = -1,-1,-1,-1 # bind master to <Configure> in order to handle any resizing, etc. # postpone self.master.bind("<Configure>", self.Master_Configure) self.master.bind('<Enter>', self.bindConfigure) self.menuBar = Menu(master, relief = "raised", bd=2) self.menuBar.add("command", label = "Change_Dir", command = self.menu_Directory_Change_Dir) disp_Choices = Menu(self.menuBar, tearoff=0) self.display_test_details = StringVar() self.display_test_details.set('N') disp_Choices.add_checkbutton(label='Display Test Details', variable=self.display_test_details, onvalue='Y', offvalue='N') self.display_watched_files = StringVar() self.display_watched_files.set('N') disp_Choices.add_checkbutton(label='Show Watched Files', variable=self.display_watched_files, onvalue='Y', offvalue='N') self.menuBar.add("cascade", label="Display", menu=disp_Choices) py_choices = Menu(self.menuBar, tearoff=0) py_choices.add("command", label = "Change Python Version", command = self.changePythonVersion) py_choices.add("command", label = "Find New Python Interpreter", command = self.findNewPythonInterpreter) py_choices.add("command", label = "Launch Another Python Interpreter", command = self.launchAnotherPythonInterpreter) self.menuBar.add("cascade", label="Python", menu=py_choices) #top_Snippet = Menu(self.menuBar, tearoff=0) self.menuBar.add("command", label = "Run", command = self.menu_Run) self.display_test_details.trace("w", self.rerun_tests) self.display_watched_files.trace("w", self.rerun_tests) master.config(menu=self.menuBar) # make a Status Bar self.statusMessage = StringVar() self.statusMessage.set(self.dirname) self.statusbar = Label(self.master, textvariable=self.statusMessage, bd=1, relief=SUNKEN) self.statusbar.pack(anchor=SW, fill=X, side=BOTTOM) self.statusbar_bg = self.statusbar.cget('bg') # save bg for restore self.arial_12_bold_font = tkinter.font.Font(family="Arial", size=12, weight=tkinter.font.BOLD) self.arial_12_font = tkinter.font.Font(family="Arial", size=12) self.statusbar.config( font=self.arial_12_bold_font ) frame = Frame(master) frame.pack(anchor=NE, fill=BOTH, side=TOP) self.Pass_Fail_Button = Button(frame,text="Pass/Fail Will Be Shown Here", image="", width="15", background="green", anchor=W, justify=LEFT, padx=2) self.Pass_Fail_Button.pack(anchor=NE, fill=X, side=TOP) self.Pass_Fail_Button.bind("<ButtonRelease-1>", self.Pass_Fail_Button_Click) self.master.title("tk_nosy") self.oscillator = 1 # animates character on title self.oscillator_B = 0 # used to return statusbar to statusbar_bg self.lbframe = Frame( frame ) self.lbframe.pack(anchor=SE, side=LEFT, fill=BOTH, expand=1) scrollbar = Scrollbar(self.lbframe, orient=VERTICAL) self.Text_1 = Text(self.lbframe, width="80", height="24", yscrollcommand=scrollbar.set) scrollbar.config(command=self.Text_1.yview) scrollbar.pack(side=RIGHT, fill=Y) self.Text_1.pack(side=LEFT, fill=BOTH, expand=1) self.master.resizable(1,1) # Linux may not respect this self.numNosyCalls = 0 self.need_to_pick_dir = 1 print('sys.argv =',sys.argv) if len(sys.argv)>1: # I don't care what the exception is, if there's a problem, bail # pylint: disable=W0702 print( "Try Dir =",sys.argv[1] ) try: dirname = os.path.abspath( sys.argv[1] ) self.try_change_to_new_dir( dirname ) except Exception: pass # let Alarm force dir selection else: try: if os.path.isdir(os.path.join( self.dirname, 'tests' )): self.try_change_to_new_dir( self.dirname ) except Exception: pass # let Alarm force dir selection print(LICENSE) self.defaultPyInterp = None # need to identify default python interpreter if Tk_Nosy.pythonInterpreterCollection == None: Tk_Nosy.pythonInterpreterCollection = PyInterpsOnSys() self.defaultPyInterp = Tk_Nosy.pythonInterpreterCollection.get_PI_obj_by_py_path( sys.executable ) #print( Tk_Nosy.pythonInterpreterCollection ) self.Alarm() def try_change_to_new_dir(self, dirname): """A legal abspath will switch to dirname.""" # I don't care what the exception is, if there's a problem, bail # pylint: disable=W0702 if dirname: try: dirname = os.path.abspath( dirname ) except: return # let Alarm force dir selection else: return self.dirname = dirname print('Selected dirname =',dirname) fileD.clear() os.chdir( self.dirname ) self.reset_statusbar_bg() self.need_to_pick_dir = 0 #with open(NOSY_USER_DATA_FILE, 'w') as text_file: # text_file.write( self.dirname ) self.numNosyCalls = 0 def reset_statusbar_bg(self): """Return status bar to default state""" self.statusbar.config(bg=self.statusbar_bg) self.statusMessage.set(self.dirname) def set_statusbar_bg(self, c): """Set status bar to show new color and message""" self.statusbar.config(bg=c) self.oscillator_B = 1 # will return to initial color after a few cycles def menu_Directory_Change_Dir(self): """Menu selection to set directory in which to run nosetests""" dirname = self.AskDirectory( title='Choose Directory For Nose Tests', initialdir=".") if dirname: self.try_change_to_new_dir( dirname ) # >>>>>>insert any user code below this comment for section "menu_Directory_Change_Dir" # replace, delete, or comment-out the following print("called menu_Directory_Change_Dir") def menu_Run(self): """User initiates a nosetests run, not file change detection.""" print("called menu_Run") self.callNosy() def rerun_tests(self,*args): self.menu_Run() def callNosy(self): """Run nosetests and display results""" self.numNosyCalls += 1 runL = [(self.defaultPyInterp, self)] for PI,Popup in Tk_Nosy.concurrent_versionL: runL.append( (PI, Popup) ) for PI, tkwindow in runL: tkwindow.Text_1.delete(1.0, END) # turn indicator button gray while running the tests tkwindow.Pass_Fail_Button.config(background="#999999", text='TESTING...', font=self.arial_12_bold_font) self.master.update() self.master.update_idletasks() for PI, tkwindow in runL: self.run_tkwin_nosetests( PI, tkwindow) self.master.winfo_toplevel().wm_geometry("") def run_tkwin_nosetests(self, PI, tkwindow): """Run nosetests for main python interpreter and any concurrent python interpreters. Update GUI to show results. """ if PI.nose_version == None: # if nose was not installed last time we checked, check again PI.nose_version, err_msg = get_nose_version_info( PI.full_path ) if PI.nose_version == None: print( "\a" ) # make beep s = 'Can not verify nose for:\nPython ' + PI.name() tkwindow.Pass_Fail_Button.config(background='orange', text=s, font=self.arial_12_bold_font) s = 'Please verify nose installed for:\n'+str(PI) +\ '\n\n' + err_msg+\ '\n\nFor install instructions see:\n'+\ 'https://nose.readthedocs.org/en/latest/' tkwindow.Text_1.insert(END, s ) ShowError(title='Can not verify nose', message=s) return # pylint: disable=W0201 passedAllTests, numPassed, numFailed, numErrors, numSkipped, outputTextL = \ run_nosetests(self.numNosyCalls, PI, display_test_details=self.display_test_details.get()) max_len_s = 42 num_lines = 1 for s in outputTextL: tkwindow.Text_1.insert(END, s) sL = s.split('\n') for ss in sL: max_len_s = max(max_len_s, len(ss)) num_lines += 1 if self.numNosyCalls % 2: myFont = self.arial_12_bold_font else: myFont = self.arial_12_font if passedAllTests: s = 'PASSED' if numPassed > 1: s = 'PASSED ALL %i TESTS'%numPassed elif numPassed == 1: s = 'PASSED ONE TEST' bg="#00ff00" if numSkipped==1: s = 'passed with 1 SKIP' bg = "#00cc00" elif numSkipped > 1: s = 'passed with %i SKIPS'%numSkipped bg = "#00cc00" elif numPassed==0: s = 'No Tests Found' bg="#ff8000" tkwindow.Pass_Fail_Button.config(background=bg, text=s, font=myFont) #self.master.geometry('200x50') else: s = 'FAILED %i, ERRORS %i, SKIP %i, PASSED %i'%(numFailed, numErrors, numSkipped, numPassed) tkwindow.Pass_Fail_Button.config(background="#ff0000", text=s, font=myFont) #self.master.geometry('516x385') # Show list of files being watched. #self.Text_1.insert(END, '_'*40+'\n') tkwindow.Text_1.insert(END, 'WATCHED *.py FILES'.center(40,'_') + '\n' ) tkwindow.Text_1.insert(END, '%s%s..\n\n'%(self.dirname,os.path.sep) ) num_lines += 3 len_dirname = len( self.dirname ) if self.display_watched_files.get()=='Y': keyL = list(fileD.keys()) keyL.sort() lastdir = '' for key in keyL: dn = os.path.dirname( key ) if dn != lastdir: tkwindow.Text_1.insert(END, '..'+dn[len_dirname:] + '\n') max_len_s = max(max_len_s, len(dn)+1) lastdir = dn num_lines += 1 s = ' ' +os.path.basename( key ) tkwindow.Text_1.insert(END, s + '\n') max_len_s = max(max_len_s, len(s)+1) num_lines += 1 else: num_lines += 1 tkwindow.Text_1.insert(END, ' %i files watched.\n'%len(fileD)) tkwindow.Text_1.config(width=max_len_s) tkwindow.Text_1.config(height=min(40, num_lines)) def bindConfigure(self, event): """Part of goofy main window setup in tkinter.""" # tkinter requires arguments, but I don't use them # pylint: disable=W0613 if not self.initComplete: self.master.bind("<Configure>", self.Master_Configure) self.initComplete = 1 def change_python_exe(self, full_path ): """Allow nosetests to be run under any available python version """ PI = Tk_Nosy.pythonInterpreterCollection.add_interp( full_path ) if PI: self.defaultPyInterp = PI def findNewPythonInterpreter(self): """Find a new python interpreter, one that is not already in the PyInterpsOnSys object (pythonInterpreterCollection). """ if Tk_Nosy.pythonInterpreterCollection == None: print( 'pythonInterpreterCollection NOT yet initialized' ) self.statusMessage.set('Interpreter Collection NOT initialized') self.set_statusbar_bg( '#FF9999' ) return print('Open File') filetypes = [ ('python executable','py*'), ('Any File','*.*')] pathopen = tkFileDialog.askopenfilename(parent=self.master, title='Select Python Executable', filetypes=filetypes, initialdir=self.defaultPyInterp.full_path) if pathopen: self.change_python_exe( pathopen ) self.menu_Run() def kill_popup_window(self, popup_name): """Close a popup window running another verions of python interpreter""" for itup, tup in enumerate(Tk_Nosy.concurrent_versionL): PI, Popup = tup s = '%s %s' % (PI.exe_name, PI.version_str) if popup_name == s: Tk_Nosy.concurrent_versionL.pop( itup ) return True # removed popup from list return False # no popup found def launchAnotherPythonInterpreter(self): """Launch a pop-up window that concurrently runs another python version""" removeNameL=[self.defaultPyInterp.name()] for PI,Popup in Tk_Nosy.concurrent_versionL: removeNameL.append( PI.name() ) piL = Tk_Nosy.pythonInterpreterCollection.get_PI_list( removeNameL=removeNameL ) if len(piL)==0: print( 'All identified python interpreters in use.' ) else: print( [pi.name() for pi in piL] ) rbL = [PI.name() for PI in piL] dialog = Select_Py_Version(self.master, "Launch Another Python Version", dialogOptions={'rbL':rbL}) if dialog.result: PI = Tk_Nosy.pythonInterpreterCollection.get_PI_obj_by_name( dialog.result['selection']) s = '%s %s' % (PI.exe_name, PI.version_str) Popup = SatelliteWindow(self, self.master, s) Tk_Nosy.concurrent_versionL.append( (PI, Popup) ) self.menu_Run() def changePythonVersion(self): """Change to a different python version. If the PyInterpsOnSys object (pythonInterpreterCollection) has been initialized, select from its list. Otherwise find the python interpreter executable (ex. python.exe or python) """ if (Tk_Nosy.pythonInterpreterCollection == None) or \ (Tk_Nosy.pythonInterpreterCollection.num_terps() == 0): # If there is no list of available python interpreters, look for python file print('Open File') filetypes = [ ('python executable','py*'), ('Any File','*.*')] pathopen = tkFileDialog.askopenfilename(parent=self.master, title='Select Python Executable', filetypes=filetypes, initialdir=self.defaultPyInterp.full_path) if pathopen: self.change_python_exe( pathopen ) self.menu_Run() else: rbL = [PI.name() for PI in Tk_Nosy.pythonInterpreterCollection.interpL] dialog = Select_Py_Version(self.master, "Select Python Version", dialogOptions={'rbL':rbL}) if dialog.result: PI = Tk_Nosy.pythonInterpreterCollection.get_PI_obj_by_name( dialog.result['selection'] ) pathopen = PI.full_path self.change_python_exe( pathopen ) self.menu_Run() # return a string containing directory name def AskDirectory(self, title='Choose Directory', initialdir="."): """Run pop-up menu for user to select directory.""" # This is not an error # pylint: disable=E1101 if sys.version_info < (3,): dirname = tkFileDialog.askdirectory(parent=self.master, initialdir=initialdir,title=title) else: dirname = tkFileDialog.askdirectory(parent=self.master, initialdir=initialdir,title=title) return dirname # <-- string def Master_Configure(self, event): """Part of tkinter main window initialization""" if event.widget != self.master: if self.w != -1: return x = int(self.master.winfo_x()) y = int(self.master.winfo_y()) w = int(self.master.winfo_width()) h = int(self.master.winfo_height()) if (self.x, self.y, self.w, self.h) == (-1,-1,-1,-1): self.x, self.y, self.w, self.h = x,y,w,h if self.w!=w or self.h!=h: #print "Master reconfigured... make resize adjustments" self.w=w self.h=h # pylint: disable=W0613 def Pass_Fail_Button_Click(self, event): """Routine for user clicking Pass/Fail Button""" print('Arranging Windows by User Request') num_popups = len(Tk_Nosy.concurrent_versionL) DX = 50 DY = 70 x = 10 y = 10 + num_popups * DY self.master.geometry( '+%i+%i'%(x,y)) for PI,Popup in Tk_Nosy.concurrent_versionL: x += DX y -= DY Popup.geometry( '+%i+%i'%(x,y)) # alarm function is called after specified number of milliseconds def SetAlarm(self, milliseconds=1000): """Reinitialize tkinter alarm mechanism as well as update seconds counter in main window title bar. """ self.master.after( milliseconds, self.Alarm ) self.oscillator += 1 if self.oscillator > 5: self.oscillator = 0 if self.oscillator_B>0: self.oscillator_B += 1 if self.oscillator_B>5: self.oscillator_B = 0 self.reset_statusbar_bg() pad = '|'*self.oscillator s = '%s (v%s)'%(self.defaultPyInterp.exe_name, self.defaultPyInterp.version_str) self.master.title('%i) %s '%(self.numNosyCalls , s + pad )) for PI,Popup in Tk_Nosy.concurrent_versionL: s = '%s (v%s)'%(PI.exe_name, PI.version_str) Popup.title( '%i) %s '%(self.numNosyCalls , s + pad ) ) def Alarm(self): """Look for changed files every second, then reset alarm""" if self.need_to_pick_dir: dirname = self.AskDirectory( title='Choose Directory For Nose Tests', initialdir=".") self.try_change_to_new_dir( dirname ) #first call to numberOfChangedFiles will be > 0 if any .py files are found elif numberOfChangedFiles( self.dirname ) > 0: # or self.numNosyCalls==0 self.callNosy() self.SetAlarm()
class MultipleRunGUI: """GUI for batch and SxS modes for displaying the stats.""" def __init__(self, *, multiple_runner_class, input_spec, left_name, right_name): """Sets up windows and the instance of RunMultipleTimes that will do the actual work.""" #: The input_spec is an iterable of #: :py:class:`farg.core.read_input_spec.SpecificationForOneRun`. self.input_spec = input_spec #: Class responsible for the actual running multiple times. self.multiple_runner_class = multiple_runner_class #: Main window self.mw = mw = Tk() #: Statistics thus far, grouped by input. self.stats = AllStats(left_name=left_name, right_name=right_name) #: Are we in the process of quitting? self.quitting = False self.status_label = Label( mw, text='Not Started', font=('Times', 20), foreground='#000000') self.status_label_text = self.status_label.cget('text') self.status_label.pack(side=TOP, expand=True, fill=X) #: Has a run started? Used to ensure single run. self.run_started = False details_frame = Frame(mw) details_frame.pack(side=TOP) #: listbox on left listing inputs. frame = Frame(details_frame) scrollbar = Scrollbar(frame, orient=VERTICAL) listbox = Listbox( frame, yscrollcommand=scrollbar.set, height=25, width=70, selectmode=SINGLE) scrollbar.config(command=listbox.yview) scrollbar.pack(side=RIGHT, fill=Y) listbox.pack(side=LEFT, fill=BOTH, expand=1) listbox.bind('<ButtonRelease-1>', self.SelectForDisplay, '+') frame.pack(side=LEFT) self.listbox = listbox #: Canvas on right for details self.canvas = Canvas( details_frame, width=kCanvasWidth, height=kCanvasHeight, background='#FFFFFF') self.canvas.pack(side=LEFT) #: which input are we displaying the details of? self.display_details_for = None #: Thread used for running self.thread = None self.mw.bind('<KeyPress-q>', lambda e: self.Quit()) self.mw.bind('<KeyPress-r>', lambda e: self.KickOffRun()) self.Refresher() self.mw.after(1000, self.KickOffRun) def SelectForDisplay(self, _event): """Event-handler called when an input was selected for detailed display.""" selected = self.listbox.curselection() if not selected: selected = ['0'] self.display_details_for = self.listbox.get(selected[0]) def Quit(self): """Called when the user has indicated that the application should Quit. Waits for any ongoing run to finish, and then destroys windows. """ self.quitting = True if self.thread: self.thread.join() self.mw.quit() def Refresher(self): """Repeatedly refreshes the display.""" self.UpdateDisplay() self.mw.after(100, self.Refresher) def KickOffRun(self): """Start run if it has not already started.""" if self.run_started: return self.run_started = True self.thread = self.multiple_runner_class( input_spec=self.input_spec, gui=self) self.thread.start() def UpdateDisplay(self): """Displays the Stats.""" current_selection = self.listbox.curselection() self.listbox.delete(0, END) self.canvas.delete('all') inputs = self.stats.input_order self.status_label.configure(text=self.status_label_text) if not inputs: return for idx, input_string in enumerate(inputs): if input_string == self.display_details_for: self.listbox.insert(END, '%s <---' % input_string) else: self.listbox.insert(END, input_string) codelet_count_comparison, success_comparison = self.stats.IsRightBetter( input_string) color = kDisplayColorDict[(codelet_count_comparison, success_comparison)] self.listbox.itemconfigure(idx, background=color) if self.display_details_for: self.DisplayDetails() if current_selection: self.listbox.selection_set(current_selection[0]) def DisplayDetails(self): """Show detailed statistics of one input. Details are shown for whatever input is present in self.display_details_for. """ self.canvas.create_text(2, 2, text=self.display_details_for, anchor=NW) # Display left side self.DisplayOneSideStats( y=kBaseYOffset, # Confused by * is pylint: disable=E1123,C6010 label=self.stats.left_name, stats=self.stats.GetLeftStatsFor(self.display_details_for)) self.DisplayOneSideStats( y=kExptYOffset, # Confused by * is pylint: disable=E1123,C6010 label=self.stats.right_name, stats=self.stats.GetRightStatsFor(self.display_details_for)) self.DisplayInferenceStats( self.stats, self.display_details_for, y=kInferenceStatsYOffset) def DisplayOneSideStats(self, *, y, label, stats): """Display stats for one of the to sides for one input. y: Y-offset where to display. label: Name of the side. Will probably be one of "previous", "current", "base", or "expt". stats: Statistics for this run. This is a :py:class:`farg.core.run_stats.RunStats` object. """ self.canvas.create_text(10, y, anchor=NW, text=label) self.CreatePieChart(kPieChartXOffset, y + 20, stats) self.CreateHistogram(kHistogramXOffset, y + 20, stats) self.DisplayBasicStats(kBasicStatsXOffset, y + 20, stats) def CreatePieChart(self, x_offset, y_offset, stats): """Create PieChart. Args: x_offset: X-offset for Pie. y_offset: Y-offset for Pie. stats: Stats to display. Instance of :py:class:`~farg.core.run_stats.RunStats`. """ stats_per_state = stats.stats_per_state state_to_counts = dict((x, len(y.codelet_counts)) for x, y in stats_per_state.items()) total_runs = sum(state_to_counts.values()) if total_runs == 0: return start = 0 for state, count in state_to_counts.items(): extent = 359.9 * count / total_runs color = StateToColor(state) self.canvas.create_arc( x_offset, y_offset, x_offset + kPieChartDiameter, y_offset + kPieChartDiameter, start=start, extent=extent, fill=color) start += extent self.canvas.create_text( x_offset + kPieChartDiameter / 2, y_offset + kPieChartDiameter + 5, anchor=N, text='%d Runs' % total_runs) def CreateHistogram(self, x_offset, y_offset, stats): """Create histogram of codelet run times. Args: x_offset: X-offset for Pie. y_offset: Y-offset for Pie. stats: Stats to display. Instance of :py:class:`~farg.core.run_stats.RunStats`. """ all_runs = [] for state, stats_for_state in stats.stats_per_state.items(): all_runs.extend((state, x_offset) for x_offset in stats_for_state.codelet_counts) all_runs = sorted( (x_offset for x_offset in all_runs if x_offset[1] > 0), key=lambda x_offset: x_offset[1]) count = len(all_runs) if count == 0: return delta_x = kHistogramWidth / count max_codelet_count = max(x_offset[1] for x_offset in all_runs) for idx, run in enumerate(all_runs): color = StateToColor(run[0]) y_end = y_offset + kHistogramHeight - kHistogramHeight * run[ 1] / max_codelet_count this_x = x_offset + delta_x * idx self.canvas.create_line( this_x, y_end, this_x, y_offset + kHistogramHeight, fill=color) self.canvas.create_text( x_offset + kHistogramWidth / 2, y_offset + kHistogramHeight + 10, anchor=N, text='Max codelets: %d' % max_codelet_count) def DisplayBasicStats(self, x_offset, y_offset, stats): """Display basic stats (mean run time, success rate, etc.) for one side. Args: x_offset: X-offset for Pie. y_offset: Y-offset for Pie. stats: Stats to display. Instance of :py:class:`~farg.core.run_stats.RunStats`. """ successful_completion_stats = stats.stats_per_state[b'SuccessfulCompletion'] total_runs = sum( len(x_offset.codelet_counts) for x_offset in stats.stats_per_state.values()) if total_runs == 0: return percentage = '%3.2f%%' % ( 100 * len(successful_completion_stats.codelet_counts) / total_runs) self.canvas.create_text( x_offset, y_offset, anchor=NW, text='Success: %s' % percentage) codelet_counts = successful_completion_stats.codelet_counts if codelet_counts: mean_codelet_count = Mean(codelet_counts) median_codelet_count = Median(codelet_counts) self.canvas.create_text( x_offset, y_offset + 15, anchor=NW, text='Mean: %3.2f' % mean_codelet_count) self.canvas.create_text( x_offset, y_offset + 30, anchor=NW, text='Median: %3.2f' % median_codelet_count) def DisplayInferenceStats(self, stats, for_input, y): """Display inference stats: Is right hand side better than left? Args: stats: Instance of :py:class:`~farg.core.run_stats.AllStats`. for_input: What input string are we comparing the two sides? y: Y-offset of top of this display. """ codelet_stats, success_stats = stats.GetComparitiveStats(for_input) if not codelet_stats or not success_stats: return self.canvas.create_text( 10, y, anchor=NW, text='means: (%3.2f, %3.2f), variance: (%3.2f, %3.2f)' % (codelet_stats['left_mean'], codelet_stats['right_mean'], codelet_stats['left_variance'], codelet_stats['right_variance'])) self.canvas.create_text( 10, y + 20, anchor=NW, text='Counts: (%d, %d), k=%d, t=%3.2f, %s' % (codelet_stats['n1'], codelet_stats['n2'], codelet_stats['df'], codelet_stats['t'], codelet_stats['descriptor'])) self.canvas.create_text( 10, y + 40, anchor=NW, text='means: (%3.2f, %3.2f), variance: (%3.2f, %3.2f)' % (success_stats['left_mean'], success_stats['right_mean'], success_stats['left_variance'], success_stats['right_variance'])) self.canvas.create_text( 10, y + 60, anchor=NW, text='Counts: (%d, %d), k=%d, t=%3.2f, %s' % (success_stats['n1'], success_stats['n2'], success_stats['df'], success_stats['t'], success_stats['descriptor']))
class SatelliteWindow( Toplevel ): """ SatelliteWindow is used to display nosetests results of concurrently run python interpreters. """ def cleanupOnQuit(self): """When closing popup, do a little clean up.""" # I'm not sure that transient windows need this, but I'm trying to be careful self.MainWin.focus_set() if self.main_gui.kill_popup_window( self.statusMessage.get() ): self.destroy() self.main_gui.statusMessage.set('Closed: ' + self.statusMessage.get()) else: self.main_gui.statusMessage.set('ERROR Closing: ' + self.statusMessage.get()) self.main_gui.set_statusbar_bg( '#FF9999' ) def __init__(self, main_gui, MainWin, mytitle, dx=30, dy=30): """Initialize popup""" Toplevel.__init__(self, MainWin) self.title(mytitle) x = MainWin.winfo_x() if x<10: x=10 y = MainWin.winfo_y() if y<10: y=10 # position over to the upper right self.geometry( '+%i+%i'%(x+dx,y+dy)) self.config( highlightcolor='#FF99FF', highlightbackground='#FF99FF', highlightthickness=2, borderwidth=10 ) #=========== # make a Status Bar self.statusMessage = StringVar() self.statusMessage.set(mytitle) self.statusbar = Label(self, textvariable=self.statusMessage, bd=1, relief=SUNKEN) self.statusbar.pack(anchor=SW, fill=X, side=BOTTOM) self.statusbar_bg = self.statusbar.cget('bg') # save bg for restore myFont = tkinter.font.Font(family="Arial", size=12, weight=tkinter.font.BOLD) self.statusbar.config( font=myFont ) frame = Frame(self) frame.pack(anchor=NE, fill=BOTH, side=TOP) self.Pass_Fail_Button = Button(frame,text="Pass/Fail Will Be Shown Here", image="", width="15", background="green", anchor=W, justify=LEFT, padx=2) self.Pass_Fail_Button.pack(anchor=NE, fill=X, side=TOP) self.Pass_Fail_Button.bind("<ButtonRelease-1>", self.Pass_Fail_Button_Click) #self.title('%s %s.%s.%s '%(python_exe_name, python_major, python_minor, python_micro)) self.oscillator = 1 # animates character on title self.oscillator_B = 0 # used to return statusbar to statusbar_bg self.lbframe = Frame( frame ) self.lbframe.pack(anchor=SE, side=LEFT, fill=BOTH, expand=1) scrollbar = Scrollbar(self.lbframe, orient=VERTICAL) self.Text_1 = Text(self.lbframe, width="80", height="24", yscrollcommand=scrollbar.set) scrollbar.config(command=self.Text_1.yview) scrollbar.pack(side=RIGHT, fill=Y) self.Text_1.pack(side=LEFT, fill=BOTH, expand=1) self.resizable(1,1) # Linux may not respect this #=========== self.MainWin = MainWin self.main_gui = main_gui # only main window can close this window self.protocol('WM_DELETE_WINDOW', self.cleanupOnQuit) def Pass_Fail_Button_Click(self, event): """Place-holder routine for user clicking Pass/Fail Button""" self.main_gui.Pass_Fail_Button_Click( event ) def reset_statusbar_bg(self): """Return status bar to default state""" self.statusbar.config(bg=self.statusbar_bg) def set_statusbar_bg(self, c): """Set status bar to show new color and message""" self.statusbar.config(bg=c) self.oscillator_B = 1 # will return to initial color after a few cycles
class TestingPanel(Frame): """This is a class to represent the interface where the user can test strings with the machine. The user can test their given string with the machine for acceptance or rejection, or work on that string using the machine as a function to just output the results. In both cases the user can optionally choose to run the test sequentially; as in they can see the machine in-action with a button to advance it. Attributes: machine (utils.Machine): The machine of the user. info_manager (InfoManager): The object that handles the info section of the GUI. display_manager (Display): The object that handles the display to the user. """ def __init__(self, master, machine, info_manager, display_manager): """Initialize this testing panel with the user's machine and the necessary managers. Parameters: machine (utils.Machine): The machine of the user. info_manager (InfoManager): The object that handles the info section of the GUI. display_manager (Display): The object that handles the display to the user. """ super().__init__(master=master) self.grid_columnconfigure(1, weight=1) self.pack(fill='x') self.machine = machine self.info_manager = info_manager self.display_manager = display_manager # TestingState object to be used in sequential tests self._testing_state = None # prompt and entry for the test string self._test_str_prompt = Label(self, text='Enter test string') self._test_str_prompt.grid(row=0, column=0) self._test_str_entry = Entry(self, width=50) self._test_str_entry.grid(stick='we', row=0, column=1) # check boxes for "as function" and "sequential test" self._as_function_var = BooleanVar(self) self._as_func_btn = Checkbutton(self, text='as function', variable=self._as_function_var) self._as_func_btn.grid(row=0, column=2) self._seq_var = BooleanVar(self) self._seq_btn = Checkbutton(self, text='sequential test', variable=self._seq_var) self._seq_btn.grid(row=0, column=3, columnspan=2) # run test button self._test_btn = Button(self, text='Run test', command=self._run_test) self._test_btn.grid(row=0, column=5) # tape result label self._tape_result_lbl = Label(self, text='Tape result') self._tape_result_lbl.grid(row=1, column=0) self._tape_result = Label(self, width=50, bg='white') self._tape_result.grid(sticky='we', row=1, column=1, pady=6) # result label (acceptance/rejection) self._result = Label(self, width=10, fg='white') self._btn_og_color = self._result.cget('bg') self._result.grid(row=1, column=2) # buttons to be used during the tests self._next_btn = Button(self, text='Next', command=self._next) self._next_btn.grid(row=1, column=3) self._next_btn.grid_remove() self._stop_btn = Button(self, text='Stop', command=self._stop) self._stop_btn.grid(row=1, column=4) self._stop_btn.grid_remove() self._clear_btn = Button(self, text='Clear', command=self._clear) self._clear_btn.grid(row=1, column=5) self._clear_btn.grid_remove() # testing thread that is running the test, # meant to allow the user to exit infinite loop machines self._test_thread = None def _test_task(self, as_function): # task function to be executed by the testing thread; # execute the computation and update the appropriate labels self._stop_btn.grid() results = self.machine.compute(self._test_str_entry.get(), as_function=as_function) self._stop_btn.grid_remove() self._test_btn.config(state='normal') if not as_function: self._tape_result.config(text=results[1]) if results[0]: self._result.config(text='Accepted', bg='green') else: self._result.config(text='Rejected', bg='red') else: self._tape_result.config(text=results) self._test_thread = None def _run_test(self): # run the test according to the data given by the user self._result.config(text='', bg=self._btn_og_color) if self.machine.is_empty(): self.info_manager.update_status('Empty machine') return sequential = self._seq_var.get() as_function = self._as_function_var.get() self.info_manager.update_status('{} is blank symbol'.format( self.machine.blank)) self._test_btn.config(state='disabled') self.display_manager.clear_highlight() self._clear_btn.grid_remove() if not sequential: self._tape_result.config(text='') self._test_thread = threading.Thread(target=self._test_task, args=(as_function, )) self._test_thread.daemon = True self._test_thread.start() else: # sequential test self._testing_state = TestingState(self._test_str_entry.get(), as_function, self.machine.init_state) self._tape_result.config( text=self._testing_state.tape if len(self._testing_state.tape) != 0 else self.machine.blank, underline=0) self._next_btn.grid() self._stop_btn.grid() self.display_manager.clear_highlight() self.display_manager.highlight_state( self._testing_state.current_state) def _next(self): # advance the machine; "next" computation in the sequential test self.machine.compute_one(self._testing_state) self._tape_result.config(text=self._testing_state.tape, underline=self._testing_state.index) self.display_manager.highlight_state(self._testing_state.current_state) if self._testing_state.done: if not self._testing_state.as_function: if self._testing_state.result: self._result.config(text='Accepted', bg='green') else: self._result.config(text='Rejected', bg='red') self._next_btn.grid_remove() self._stop_btn.grid_remove() self._clear_btn.grid() self._test_btn.config(state='normal') self._testing_state = None def _stop(self): # stop the test; aborting the computation of the testing thread's machine if self._test_thread is not None: # non-sequential test self.machine.abort = True self._test_thread = None self._stop_btn.grid_remove() self._test_btn.config(state='normal') self.info_manager.update_status('Aborted test') else: # sequential test self._testing_state = None self._tape_result.config(text='', underline=-1) self._next_btn.grid_remove() self._stop_btn.grid_remove() self._test_btn.config(state='normal') self.display_manager.clear_highlight() self.info_manager.update_status('Stopped test') def _clear(self): # clear the highlighted state in the display, if any self.display_manager.clear_highlight() self._clear_btn.grid_remove()
class Button_(Widget_): def __init__(self, parent_frame, x, y): Widget_.__init__(self, parent_frame, x, y) self.label_bg, self.label_fg = 'grey', 'white' self.hover_bg, self.hover_fg = None, None self.label = Label(self.widget_frame, bg=self.label_bg, fg=self.label_fg) self.label.grid(row=0, column=1, ipadx=5, ipady=10) def get_info(self): return self.label.cget('text') def set_hover(self): def set_hover_bg(event): self.label.config(bg=self.hover_bg, fg=self.hover_fg) self.img.config(bg=self.hover_bg, fg=self.hover_fg) def remove_hover_bg(event): self.label.config(bg=self.label_bg, fg=self.label_fg) self.img.config(bg=self.label_bg, fg=self.label_fg) if hasattr(self, 'img'): self.widget_frame.bind('<Enter>', set_hover_bg) self.widget_frame.bind('<Leave>', remove_hover_bg) else: self.widget_frame.bind('<Enter>', lambda event: self.label.config(bg=self.hover_bg, fg=self.hover_fg)) self.widget_frame.bind('<Leave>', lambda event: self.label.config(bg=self.label_bg, fg=self.label_fg)) def settings(self, **kwargs): ''' all setting changes ''' if 'label_bg' in kwargs: self.label_bg = kwargs['label_bg'] self.label.config(bg=self.label_bg) if 'label_fg' in kwargs: self.label_fg = kwargs['label_fg'] self.label.config(fg=self.label_fg) if 'text' in kwargs: self.label.config(text=kwargs['text']) if 'font' in kwargs: self.label.config(font=kwargs['font']) if 'hover_bg' in kwargs: self.hover_bg = kwargs['hover_bg'] self.hover_fg = self.label_fg if self.hover_fg == None else self.hover_fg self.set_hover() if 'hover_fg' in kwargs: self.hover_fg = kwargs['hover_fg'] self.hover_bg = self.label_bg if self.hover_bg == None else self.hover_bg self.set_hover() if 'command' in kwargs: self.command = kwargs['command'] self.label.bind('<Button-1>', lambda event: self.command()) if hasattr(self, 'img'): self.img.bind('<Button-1>', lambda event: self.command()) if 'image' in kwargs: self.img_path = kwargs['image'] self.picture = Image.open(self.img_path) self.image = ImageTk.PhotoImage(self.picture) self.img = Label(self.widget_frame, bg=self.label_bg, fg=self.label_fg) self.img.grid(row=0, column=0, ipadx=5, ipady=5, columnspan=2, sticky=W) self.img.config(image=self.image) self.set_hover() if hasattr(self, 'command'): self.img.bind('<Button-1>', lambda event: self.command()) if 'image_resize' in kwargs: self.picture = self.picture.resize(kwargs['image_resize'], Image.ANTIALIAS) self.image = ImageTk.PhotoImage(self.picture) self.img.config(image=self.image) return