def main(): global state_pub global root global max_velocity global max_steering_angle max_velocity = rospy.get_param("~speed", 2.0) max_steering_angle = rospy.get_param("~max_steering_angle", 0.34) state_pub = rospy.Publisher("mux/ackermann_cmd_mux/input/teleop", AckermannDriveStamped, queue_size=1) rospy.Timer(rospy.Duration(0.1), publish_cb) atexit.register(exit_func) os.system("xset r off") root = Tk() frame = Frame(root, width=100, height=100) frame.bind("<KeyPress>", keydown) frame.bind("<KeyRelease>", keyup) frame.pack() frame.focus_set() lab = Label( frame, height=10, width=30, text= "Focus on this window\nand use the WASD keys\nto drive the car.\n\nPress Q to quit", ) lab.pack() print("Press %c to quit" % QUIT) root.mainloop()
def main(): game = Game('10.14.10.25', 1337, 100, 50) root = Tk() root.title("Game of Life") frame = Frame(root) frame.focus_set() gameview = StringVar() Label(root, textvariable=gameview, font="Monospace").pack() game.setMockDisplay(gameview) game.loop() frame.pack() root.mainloop() game.stop()
def get_key(msg="Press any key ...", time_to_sleep=3): if msg: print(msg) key_pressed = {"value": ''} root = Tk() root.overrideredirect(True) frame = Frame(root, width=0, height=0) frame.bind("<KeyRelease>", lambda f: __set_key(f, root, key_pressed)) frame.pack() root.focus_set() frame.focus_set() frame.focus_force() # doesn't work in a while loop without it root.after(time_to_sleep * 1000, func=root.destroy) try: root.mainloop() except KeyboardInterrupt as e: root.destroy() key_pressed['value'] = None root = None # just in case return key_pressed['value']
def old_keyboard_input(): """ Maps certain keys to a keyboard, and adding the notes as we press/release keys. """ oscs = gen_oscs(SineOscillator) print(oscs) # Create AudioCollection for output collec = AudioCollection() collec.add_module(ZeroOscillator()) # Create KeyBoardHandler: hand = KeyboardHandler(collec, oscs) # Start streaming the AudioCollection: start_stream(collec) # Disabling continuous keypresses: os.system("xset r off") # Creating TKinter data: root = Tk() f = Frame(root, width=100, height=100) f.bind("<KeyPress>", hand.add_key) f.bind("<KeyRelease>", hand.remove_key) f.pack() f.focus_set() root.mainloop() os.system("xset r on")
class View: def __init__(self): self.root = Tk() self.root.title("Stroop Test") self.root.geometry('800x600') self.root.resizable(0, 0) # Configuramos la pantalla inicial self.initial_screen = Frame(self.root) self.initial_screen.config(bg='lightblue') self.initial_screen_name_label = Label( self.initial_screen, text='Nombre') self.initial_screen_name_entry = Entry( self.initial_screen) self.initial_screen_age_label = Label( self.initial_screen, text='Edad') self.initial_screen_age_entry = Entry(self.initial_screen) self.initial_screen_email_label = Label( self.initial_screen, text='Email') self.initial_screen_email_entry = Entry(self.initial_screen) self.initial_screen_instructions_label = Label( self.initial_screen, text='Para realizar este test debe' 'presionar en su teclado la flecha que corresponde\n' 'a la palabra que figura en pantalla. \n Para Rojo presione ←, ' 'para Azul presione ↑, para Verde ' 'presione ↓ y para Amarillo presione →', font=('Candara', 12), bg='lightblue') self.initial_screen_start_button = Button( self.initial_screen, text='Comenzar') # Entradas con los datos del usuario self.initial_screen_name_entry.insert(0, '') self.initial_screen_age_entry.insert(0, '') self.initial_screen_email_entry.insert(0, '') # Configuramos la pantalla del test self.test_screen = Frame(self.root) self.test_screen.config(bg="black") self.test_screen_label = Label( self.test_screen, width=40, text="Presioná cualquier tecla\npara comenzar", font=("Calibri", 35), fg='white', bg='black') # Configuramos la pantalla de los resultados self.score_board = Frame(self.root) self.score_board.config(bg="lightblue") self.score_board_user_label = Label(self.score_board) self.score_board_user_result = Label( self.score_board) self.score_board_first_place = Label( self.score_board, text='1.') self.score_board_second_place = Label( self.score_board, text='2.') self.score_board_third_place = Label( self.score_board, text='3.') self.score_board_erase_button = Button( self.score_board, text='Borrar tu resultado') self.show_initial_screen() return def show_initial_screen(self): self.initial_screen.pack(side='top', fill='both', expand=True) self.initial_screen_name_label.pack( side='top', pady=50) self.initial_screen_name_entry.pack(side='top') self.initial_screen_age_label.pack( side='top', pady=40) self.initial_screen_age_entry.pack(side='top') self.initial_screen_email_label.pack( side='top', pady=40) self.initial_screen_email_entry.pack(side='top') self.initial_screen_start_button.pack( side='bottom', anchor=SE, padx=30, pady=40) self.initial_screen_instructions_label.pack( side='bottom', anchor=CENTER, pady=20) return def hide_initial_screen(self): # Nos sirve para que no aparezca ningún widget de la pantalla inicial self.initial_screen.pack_forget() return def change_from_initial_to_test_screen(self): # Cambiamos a la pantalla inicial a la pantalla del test self.hide_initial_screen() self.show_test_screen() return def show_error_message_pop_up(self, message): # Creamos una ventana de error messagebox.showerror('Error', message) return def show_test_screen(self): self.test_screen.pack(side='top', fill='both', expand=True) self.test_screen_label.pack(side='top', pady=250) self.test_screen.focus_set() return def hide_test_screen(self): self.test_screen.pack_forget() return def change_from_test_to_score_board(self): # Cambiamos de la pantalla del test a la pantalla de resultados self.hide_test_screen() self.show_score_board() return def show_score_board(self): self.score_board.pack(side='top', fill='both', expand=True) self.score_board_user_label.pack(side='top', anchor=NW, pady=50) self.score_board_user_result.pack(side='top') self.score_board_first_place.pack(side='top') self.score_board_second_place.pack(side='top') self.score_board_third_place.pack(side='top') self.score_board_erase_button.pack(side='bottom', pady=50) return def set_score_board_current_user_name(self, name): # Dato del nombre del usuario actual self.score_board_user_label.config(text='Nombre: ' + name) return def set_score_board_current_test_score(self, test_score): # Dato del último resultado del usuario actual self.score_board_user_result.config( text='Tu puntaje fue de: %.2f' % test_score) return def set_score_board_first_place_user(self, user): # Consultamos el primer lugar con nombre de usuario y resultado self.score_board_first_place.config( text='1. %s (%.2f)' % (user.name, user.average_score)) return def set_score_board_second_place_user(self, user): # Consultamos el segundo lugar con nombre de usuario y resultado self.score_board_second_place.config( text='1. %s (%.2f)' % (user.name, user.average_score)) return def set_score_board_third_place_user(self, user): # Consultamos el tercer lugar con nombre de usuario y resultado self.score_board_third_place.config( text='1. %s (%.2f)' % (user.name, user.average_score)) return def disable_erase_button(self): # Desactivamos el botón Borrar los resultados una vez presionado self.score_board_erase_button.config(state=DISABLED) return def show_user_data_deleted_message(self): # Ventana emergente que corrobora que los datos fueron borrados messagebox.showinfo('OK', 'Datos borrados con éxito') return def start_gui(self): self.root.mainloop() return
def move_file(directory): if not os.path.exists(directory): os.makedirs(directory) new_file = directory + 'Picture_{0}.jpg'.format(file_count) os.rename(photo_path, new_file) top_frame = Frame(tk_root) top_frame.bind("<KeyPress>", keydown) top_frame.bind("<BackSpace>", backspace) top_frame.bind("<space>", space) top_frame.bind("<Escape>", escape) top_frame.bind("<Tab>", tab) top_frame.focus_set() bottom_frame = Frame(tk_root) right_frame = Frame(tk_root) top_frame.pack(side='top') bottom_frame.pack(side='bottom') right_frame.pack(side='right') path_generator = search(p) photo_path = next(path_generator) photo = ImageTk.PhotoImage(Image.open(photo_path)) picture = tk.Label(tk_root, image=photo) picture.image = photo picture.pack(side='left') top_text = Message(top_frame, text="Hello", width=300, justify='left') bottom_text = Label(
history = [] def keyup(e): print(e.keycode) if e.keycode in history: history.pop(history.index(e.keycode)) def keydown(e): if not e.keycode in history: history.append(e.keycode) frame = Frame(root, width=1, height=1) frame.bind("<KeyPress>", keydown) frame.bind("<KeyRelease>", keyup) frame.pack() path = "testimg.jpg" # Creates a Tkinter-compatible photo image, which can be used everywhere Tkinter expects an image object. img = ImageTk.PhotoImage(Image.open(path)) panel = Label(root, image=img) # The Pack geometry manager packs widgets in rows or columns. panel.pack(side="bottom", fill="both", expand="yes") frame.focus_set() root.mainloop()
class ABSingleLickGui: def __init__(self, root=Tk()): self.root = root self.root.title("Apple/Banana Single Lick") self.root.configure(bg=BACKGROUND_COLOR) self.titleLabel = Label(self.root, text='AppleBanana Single Lick Experiment', font=STATUS_FONT, bg=BACKGROUND_COLOR) self.ard = None self.experiment = None self.isConfigLoaded = False self.isArdConnected = False self.isPumpOn = False self.estTime = StringVar() self.lickCount = IntVar() self.lickCount.set(0) self.isSoundOn = BooleanVar() self.stopUpdating = threading.Event() self.ardUpdater = threading.Thread(target=self.updateVariable) port = MouseArduino.getUnoPort() #Frames self.master = Frame(root, bg=BACKGROUND_COLOR) self.master.grid_rowconfigure(0) self.master.grid_rowconfigure(1) self.master.grid_rowconfigure(2, weight=5) self.master.grid_columnconfigure(0, weight=1) self.master.grid_columnconfigure(1, weight=1) self.master.grid_columnconfigure(2, weight=1) self.ardInitFrame = Frame(self.master, bd=3, relief='groove', bg=BACKGROUND_COLOR) self.ardControlFrame = Frame(self.master, bd=3, relief='groove', bg=BACKGROUND_COLOR) self.initFrame = Frame(self.master, bd=3, relief='groove', bg=BACKGROUND_COLOR) self.argFrame = Frame(self.master, bd=3, relief='groove', bg=BACKGROUND_COLOR) self.finalControlFrame = Frame(self.master, bd=3, relief='groove', bg=BACKGROUND_COLOR) #ardInitFrame self.ardInitFrameLabel = Label(self.ardInitFrame, text="Connect to Hardware", bg=HEADER_COLOR, font=LARGE_FONT, fg='white', relief='solid', borderwidth=2, width=40) self.comLabel = Label(self.ardInitFrame, bg=BACKGROUND_COLOR, text="Com Port:", font=TEXT_FONT) self.comEntry = Entry(self.ardInitFrame, font=TEXT_FONT) self.baudrateLabel = Label(self.ardInitFrame, bg=BACKGROUND_COLOR, text="Baudrate:", font=TEXT_FONT) self.baudrateEntry = Entry(self.ardInitFrame, font=TEXT_FONT) self.connectButton = Button(self.ardInitFrame, text="Connect", font=STATUS_FONT, command=self.connect) self.ardInitFrameLabel.grid(row=0, columnspan=2, padx=40, pady=10) self.comLabel.grid(row=1, column=0, sticky=tk.E) self.comEntry.grid(row=1, column=1, sticky=tk.W) self.baudrateLabel.grid(row=2, column=0, sticky=tk.E) self.baudrateEntry.grid(row=2, column=1, sticky=tk.W) self.connectButton.grid(row=3, columnspan=2, pady=10) self.comEntry.insert(0, port) self.baudrateEntry.insert(0, 115200) #ardControlFrame self.ardControlFrameLabel = Label(self.ardControlFrame, text='Pre-experiment Control', bg=HEADER_COLOR, font=LARGE_FONT, fg='white', relief='solid', borderwidth=2, width=40) self.sendStringEntry = Entry(self.ardControlFrame, font=TEXT_FONT, width=20) self.sendStringButton = Button(self.ardControlFrame, text='Send String', font=TEXT_FONT, bg=BACKGROUND_COLOR, command=self.sendString) self.rewardButton = Button(self.ardControlFrame, text='Reward(R)', font=STATUS_FONT, width=10, bg=BACKGROUND_COLOR, command=self.deliverReward, height=1) self.pumpButton = Button(self.ardControlFrame, text='Pump Water(P)', font=STATUS_FONT, command=self.togglePump, bg=OFF_COLOR, width=12, height=1) self.lickLabel = Label(self.ardControlFrame, text='LICK', bg=LICK_OFF_COLOR, font=LICK_FONT, width=10, height=1) self.lickCountLabel = Label(self.ardControlFrame, text='Lick Count :', bg=BACKGROUND_COLOR, font=LARGE_FONT) self.lickCountButton = Button(self.ardControlFrame, textvariable=self.lickCount, font=LARGE_FONT, bg=BACKGROUND_COLOR, command=lambda: self.lickCount.set(0)) self.soundCheckButton = Checkbutton(self.ardControlFrame, text='Lick Sound', variable=self.isSoundOn, bg=BACKGROUND_COLOR) self.ardControlFrameLabel.grid(row=0, columnspan=2, padx=40, pady=10) self.sendStringEntry.bind('<Return>', self.sendString) self.sendStringEntry.grid(row=1, column=0, padx=5, sticky=tk.E) self.sendStringEntry.bind('<Escape>', lambda x: self.master.focus()) self.sendStringButton.grid(row=1, column=1, padx=5, sticky=tk.W) self.rewardButton.grid(row=2, column=0, pady=10) self.pumpButton.grid(row=2, column=1, pady=10) self.lickLabel.grid(row=3, columnspan=2, pady=15) self.lickCountLabel.grid(row=4, column=0, sticky=tk.E) self.lickCountButton.grid(row=4, column=1, sticky=tk.W) self.soundCheckButton.grid(row=5, columnspan=2) #initFrame self.initFrameLabel = Label(self.initFrame, text="Session Configuration", font=LARGE_FONT, bg=HEADER_COLOR, fg='white', relief='solid', borderwidth=2, width=40) self.loadButton = Button(self.initFrame, text="Load Config(L)", font=STATUS_FONT, command=self.selectFile) self.sessionNameLabel = Label(self.initFrame, text="Session Name:", font=TEXT_FONT, bg=BACKGROUND_COLOR) self.sessionNameEntry = Entry(self.initFrame, font=TEXT_FONT) self.numOfTrialsLabel = Label(self.initFrame, text="Number of Trials:", font=TEXT_FONT, bg=BACKGROUND_COLOR) self.numOfTrialsEntry = Entry(self.initFrame, font=TEXT_FONT) self.numOfTrialsEntry.bind('<KeyRelease>', self.updateTime) self.numOfTrialsEntry.bind('<Escape>', lambda x: self.master.focus()) self.initFrameLabel.grid(row=0, columnspan=2, padx=40, pady=10) self.sessionNameLabel.grid(row=1, column=0, sticky=tk.E) self.sessionNameEntry.grid(row=1, column=1, sticky=tk.W) self.sessionNameEntry.bind('<Escape>', lambda x: self.master.focus()) self.numOfTrialsLabel.grid(row=2, column=0, sticky=tk.E) self.numOfTrialsEntry.grid(row=2, column=1, sticky=tk.W) self.loadButton.grid(row=3, columnspan=2, pady=10) #finalControlFrame self.finalControlFrameLabel = Label(self.finalControlFrame, text='Experiment Control', bg=HEADER_COLOR, font=LARGE_FONT, fg='white', relief='solid', bd=2, width=40) self.estTimeLabel = Label(self.finalControlFrame, textvariable=self.estTime, font=STATUS_FONT, bg=BACKGROUND_COLOR) self.startButton = Button(self.finalControlFrame, text="START EXPERIMENT", font='Helvetica 20 bold', command=self.startExperiment) self.finalControlFrameLabel.grid(padx=40, pady=10) self.estTimeLabel.grid(pady=10) self.startButton.grid(pady=15) #master self.titleLabel.pack(pady=5) self.master.pack(padx=20, pady=20) self.initFrame.grid(row=0, column=0) self.ardInitFrame.grid(row=1, column=0) self.finalControlFrame.grid(row=2, column=0, sticky='NSWE') self.argFrame.grid(row=0, column=1, rowspan=3, sticky='NSWE') for frame in [ self.master, self.initFrame, self.ardInitFrame, self.finalControlFrame, self.argFrame ]: frame.bind('r', self.deliverReward) frame.bind('p', self.togglePump) frame.bind('l', self.selectFile) frame.bind('R', self.deliverReward) frame.bind('P', self.togglePump) frame.bind('L', self.selectFile) frame.bind("<Button-1>", lambda e: self.master.focus_set()) self.updateTime() def run(self): self.master.mainloop() def selectFile(self, event=None): fileName = filedialog.askopenfilename() self.configFileName = fileName for widget in self.argFrame.winfo_children(): widget.destroy() self.argFrameLabel = Label(self.argFrame, text="Experiment Configuration: " + os.path.basename(fileName), font=LARGE_FONT, bg=HEADER_COLOR, fg='white', relief='solid', bd=2, width=40).grid(columnspan=2, padx=40, pady=10) try: with open(fileName) as f: self.args = json.load(f) except Exception as e: print(e) argToLen = lambda x: len(str(x)) maxArgNameLength = argToLen( max(self.args.keys(), key=lambda x: argToLen(x))) maxArgValueLength = argToLen( max(self.args.values(), key=lambda x: argToLen(x))) correctTrialDuration = self.args["Cue duration"] + \ self.args["Correct response visual duration"] + \ (self.args["Stimulus duration"] if self.args["Give reward without lick"] == 0 else 0) wrongTrialDuration = self.args["Cue duration"] +\ self.args["Stimulus duration"] + \ self.args["Wrong response flash duration"] + \ self.args["Wrong response rest duration"] self.trialDuration = correctTrialDuration * self.args[ "A image probability"] + wrongTrialDuration * ( 1 - self.args["A image probability"]) for i, (argName, value) in enumerate( sorted(self.args.items(), key=lambda item: item[0])): lName = Label(self.argFrame, text=str(argName) + " :", font='Helvetica 12 bold', bg=BACKGROUND_COLOR).grid(row=i + 3, column=0, sticky=tk.E) lValue = Label(self.argFrame, text=str(value), bg=BACKGROUND_COLOR).grid( row=i + 3, column=1, sticky=tk.W, ) self.updateTime() self.isConfigLoaded = True def connect(self): try: comport = self.comEntry.get() baudrate = self.baudrateEntry.get() if comport == "" or baudrate == "": raise Exception("Please fill in all values") baudrate = int(baudrate) self.ard = MouseArduino(comport, baudrate) self.ard.start() self.ardInitFrame.destroy() self.ardUpdater.start() self.ardControlFrame.grid(row=1, column=0) self.isArdConnected = True except Exception as e: messagebox.showerror( "Error", "Could not connect to Arduino. Make sure port is correct or other program isn't grabbing the port :" + str(e)) def deliverReward(self, event=None): self.ard.deliverReward() def sendString(self, event=None): self.ard.write(self.sendStringEntry.get()) self.sendStringEntry.delete(0, 'end') def updateVariable(self): while not self.stopUpdating.is_set(): if self.ard.newMsg.wait(1): while not self.ard.msgQueue.empty(): self.ard.newMsg.clear() msg = self.ard.msgQueue.get() print(msg) args = Utilities.parse(msg) arg = args[1].strip() if arg == 'LK': self.lickCount.set(self.lickCount.get() + 1) self.lickLabel.configure(bg=ON_COLOR) if self.isSoundOn.get(): Sound.cue(0.05) time.sleep(0.2) self.lickLabel.configure(bg=LICK_OFF_COLOR) elif arg == 'startpump': self.pumpButton.configure(bg=ON_COLOR) self.isPumpOn = True elif arg == 'stoppump': self.pumpButton.configure(bg=OFF_COLOR) self.isPumpOn = False def togglePump(self, event=None): if self.isPumpOn: self.ard.stopPump() else: self.ard.startPump() def updateTime(self, event=None): numOfTrials = self.numOfTrialsEntry.get() try: totalDuration = self.trialDuration * int(numOfTrials) tmin = totalDuration // 60 tsec = totalDuration % 60 timeStr = "{:.0f} Min {:.0f} Sec".format(tmin, tsec) except Exception as e: timeStr = "" print(e) self.estTime.set("Estimated duration: {:>10}".format(timeStr)) def startExperiment(self): if not self.isConfigLoaded: messagebox.showerror("Error", "Please load configuration file") elif not self.isArdConnected: messagebox.showerror("Error", "Please connect Arduino") else: try: sessionName = self.sessionNameEntry.get() numOfTrials = self.numOfTrialsEntry.get() if sessionName == "" or numOfTrials == "": raise Exception("Please fill in all values") numOfTrials = int(numOfTrials) self.experiment = ABSingleLick(self.ard) self.experiment.startExperiment(sessionName, numOfTrials, self.configFileName) except Exception as e: messagebox.showerror("Error", e)
class View(): """This calls contains all the tkinter specific code""" def __init__(self, control, master): """View constructor""" self.control = control # Link back to talk to controller self.master = master master.wm_state('zoomed') # Full screen. Might not work on Mac self.frame = Frame(master) self.create_menus() self.create_context_menus() self.create_toolbar() self.frame.pack(fill=BOTH, expand=YES) self.frame.focus_set() self.create_events() def create_menus(self): """creates the menus""" # main menu menubar = Menu(self.master) # file menus filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="New", accelerator="^N", command=self.control.cmd_new) filemenu.add_command(label="Open", accelerator="^O", command=self.control.cmd_open) filemenu.add_command(label="Save", accelerator="^S", command=self.control.cmd_save) filemenu.add_command(label="Save as", command=self.control.cmd_save_as) filemenu.add_separator() filemenu.add_command(label="Exit", command=self.control.cmd_exit) menubar.add_cascade(label="File", menu=filemenu) # edit menus editmenu = Menu(menubar, tearoff=0) editmenu.add_command(label="Undo", accelerator="^Z", command=self.control.cmd_null) editmenu.add_command(label="Redo", accelerator="^C", command=self.control.cmd_null) editmenu.add_separator() editmenu.add_command(label="Cut", accelerator="^X", command=self.control.cmd_null) editmenu.add_command(label="Copy", accelerator="^C", command=self.control.cmd_null) editmenu.add_command(label="Paste", accelerator="^V" , command=self.control.cmd_null) editmenu.add_separator() editmenu.add_command(label="Delete", command = self.control.cmd_null) editmenu.add_separator() editmenu.add_command(label="Select all", command = self.control.cmd_null) menubar.add_cascade(label="Edit", menu=editmenu) # drawing menus drawingmenu = Menu(menubar, tearoff=0) drawingmenu.add_command(label="Select", command=self.control.cmd_null) drawingmenu.add_command(label="Line", command=self.control.cmd_line) drawingmenu.add_command(label="Rectangle", command=self.control.cmd_rectangle) drawingmenu.add_command(label="Circle", command=self.control.cmd_circle) drawingmenu.add_command(label="Group", command=self.control.cmd_null) drawingmenu.add_command(label="Instance", command=self.control.cmd_null) menubar.add_cascade(label="Drawing", menu=drawingmenu) # toolbar menus toolbarmenu = Menu(menubar, tearoff=0) toolbarmenu.add_checkbutton(label='Tools', command=self.control.cmd_tools) menubar.add_cascade(label="Toolbar", menu=toolbarmenu) # help menus helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label="About", command = self.control.cmd_null) menubar.add_cascade(label="Help", menu = helpmenu) self.master.config(menu=menubar) # lock in menubar def create_context_menus(self): """Creates the connects menus, i.e. for right click""" self.context = Menu(self.master, tearoff=0) self.context.add_command(label="Dirty", command=self.control.cmd_dirty) self.context.add_command(label="Clean", command=self.control.cmd_clean) def create_toolbar(self): """Creates toolbar, hopefully floating dockable but not yet""" self.toolbar = Frame(self.master, bd=1, relief=RAISED) self.img = Image.open("exit.png") eimg = ImageTk.PhotoImage(self.img) exitButton = Button(self.toolbar, image=eimg, bd=1, relief=RAISED, command=self.control.cmd_exit) exitButton.image = eimg exitButton.pack(side=TOP, padx=2, pady=2) anotherButton = Button(self.toolbar, image=eimg, bd=1, relief=RAISED, command=self.control.cmd_null) anotherButton.image = eimg anotherButton.pack(side=TOP, padx=2, pady=2) anotherButton = Button(self.toolbar, image=eimg, bd=1, relief=RAISED, command=self.control.cmd_null) anotherButton.image = eimg anotherButton.pack(side=TOP, padx=2, pady=2) self.toolbar.pack(side=LEFT, fill=Y) def create_events(self): """Binds keyboard events to handlers""" self.frame.bind("<Control-o>", self.key_open) self.frame.bind("<Control-s>", self.key_save) self.frame.bind("<Button-1>", self.left_click) self.frame.bind("<Button-3>", self.right_click) self.frame.bind("<Configure>", self.on_resize) # Window closing event self.master.protocol('WM_DELETE_WINDOW', self.control.cmd_exit) def on_resize(self,e): """Called when window changes size""" pass @staticmethod def question_box(title, text): """Just a wrapped for tkinter so command calls can be tkinter independent""" return messagebox.askquestion(title, text) == "yes" @staticmethod def warning_box(title, text): """Just a wrapped for tkinter so command calls can be tkinter independent""" messagebox.showwarning(title, text) @staticmethod def info_box(title, text): """Just a wrapped for tkinter so command calls can be tkinter independent""" messagebox.showinfo(title, text) @staticmethod def open_file_dialog(): """Just a wrapped for tkinter so command calls can be tkinter independent""" return filedialog.askopenfilename(filetypes=(("Gcode","*.gcode"), ("All files","*.*"))) @staticmethod def save_file_dialog(initial_file): """Just a wrapped for tkinter so command calls can be tkinter independent""" return filedialog.asksaveasfile(mode='w', initialfile=initial_file, filetypes=(("Gcode","*.gcode"),("All files","*.*")), defaultextension=".gcode") def key_open(self, e): self.control.cmd_open() def key_save(self, e): self.control.cmd_open() def left_click(self, e): self.control.cmd_left_click(e.x_root, e.y_root) def right_click(self, e): self.control.cmd_right_click(e.x_root, e.y_root) def show_context_menu(self, x, y): self.context.tk_popup(x, y, 0) def show_toolbar(self): # self.frame = Frame(self.master) self.create_menus() self.create_context_menus() self.create_toolbar() self.create_toolbar() self.create_toolbar() self.frame.pack(fill=BOTH, expand=YES) self.frame.focus_set() self.create_events() def hide_toolbar(self): self.toolbar.pack_forget()
class TimeGUI: _excel = ExcelHelper() def __init__(self, master, settings): self._settings = settings self._frame = Frame(master) self._frame.pack() self._check_in_b = Button(self._frame, text=" TIME ", command=self._add_time) self._check_in_b.pack(side=TOP) self._desc = Text(self._frame, height=12) self._desc.bind('<Control-t>', self._add_time) self._desc.bind('<Control-d>', self._desc_and_distract) self._desc.pack(side=TOP) self._add_desc_b = Button(self._frame, text=" ADD ", command=self._desc_and_distract) self._add_desc_b.pack(side=RIGHT) self._send_email_b = Button(self._frame, text=" SEND ", command=self._send_email) self._send_email_b.pack(side=LEFT) self._frame.bind('<Control-t>', self._add_time) self._frame.bind('<Control-d>', self._add_desc) self._frame.bind('<Control-s>', self._send_email) self._instructions = Label( self._frame, text= "Ctrl + t -> Add Time\nCtrl + d -> Add Desc\nCtrl + s -> Send Sheet" ) self._instructions.pack(side=BOTTOM) self._frame.focus_set() def _get_text(self): """ Gets the text from the text box object :return: Current text in the text box """ desc = self._desc.get("1.0", 'end-1c') return desc def _add_time(self, event=None): """ Event used in hot keys and button presses. Adds time to spreadsheet. :param event: Used when event is called on hot key press. :return: """ try: self._excel.add_time() except: Popups.failed_edit() def _add_desc(self, event=None): """ Event used in hot keys and button presses. Adds description to spreadsheet. :param event: Used when event is called on hot key press. :return: """ try: self._excel.add_desc(self._get_text()) self._desc.delete("1.0", END) except: Popups.failed_edit() def _desc_and_distract(self, event=None): """ This event is used to submit the description and then cear the focus. :param event: Used when event is called on hot key press. :return: """ self._add_desc() self._lose_focus() def _lose_focus(self): """ Sets the focus on the frame. So that hot keys can be called. :return: """ self._frame.focus_set() def _send_email(self, event=None): """ Event to send email on hot key call or button press :param event: Used when event is called on hot key press. :return: """ if Popups.send_confirmation(): thread = Thread(target=Email.send_email, args=( self._settings, self._excel, )) thread.start() thread.join()
class MazeGUI: def __init__(self): self.maze = Maze(4, 4) self.root = Tk() self.gamescreen = Frame(self.root) self.startmenu = Frame(self.root) self.db = None self.display = None self.drawer = None self.start_time = None self.root.resizable(False, False) self.root.title("TriviaMaze") self.start_menu_init() self.startmenu.grid(row=0, column=0) self.gamescreen.grid_forget() pygame.init() pygame.mixer.init() self.root.mainloop() pygame.init() pygame.mixer.init() """Start menu""" def start_menu_init(self): """Builds the start menu for the game. Has a button to start a new game, continue game, display instructions and exit the program. Under the new game button there are options for different game difficulties, with easy as the default selection.""" self.startmenu.grid(row=0, column=0) menu_spacer = Frame(self.startmenu, height=80, width=600) menu_spacer.grid(row=0, column=0, columnspan=3) menu_spacer2 = Frame(self.startmenu, height=420, width=100) menu_spacer2.grid(row=2, column=1) menu_spacer3 = Frame(menu_spacer2) menu_spacer3.grid(row=4, column=1) title = Label(self.startmenu, text="504 TriviaMaze", font="Times 40", pady=50) title.grid(row=1, column=0, columnspan=4) new_game_button = Button(menu_spacer2, text="New Game", font="Times 20", command=lambda: self.display_new_game_menu()) new_game_button.grid(row=3, column=1, sticky=W) continue_game_button = Button(menu_spacer2, text="Continue Game", font="Times 20", command=self.display_load_menu) continue_game_button.grid(row=6, column=1, columnspan=2, sticky=W) instructions_button = Button(menu_spacer2, text="Instructions", font="Times 20", command=self.display_instructions) instructions_button.grid(row=7, column=1, columnspan=2, sticky=W) exit_button = Button(menu_spacer2, text="Exit", font="Times 20", command=self.root.destroy) exit_button.grid(row=8, column=1, columnspan=2, sticky=W) def display_instructions(self): """Displays basic instructions for the game. Hides the start menu and replaces it with a screen containing text from a separate text file. Creates a button that will return the user to the start menu.""" self.startmenu.grid_forget() instruction_file = open("triviamaze_instructions.txt", 'r') instruction_text = instruction_file.read() instruct_frame = Frame(self.root, height=600, width=600) instruct_frame.grid(row=0, column=0) t = Text(instruct_frame, wrap="word", font="Times 16") t.grid(row=0, column=0) t.insert("1.0", instruction_text) instruction_file.close() back_button = Button( instruct_frame, text="Back", font="Times 20", command=lambda: self.screen_switch(instruct_frame, self.startmenu)) back_button.grid(row=1, column=0) def display_new_game_menu(self): """Creates and displays the new game menu, allowing the player to choose question difficulty, maze size, and trivia category. The default options are easy, 4x4 and no specific category.""" def set_difficulty(difficulty): buttons = { "Easy": easy_button, "Medium": medium_button, "Hard": hard_button } for button in buttons.values(): button['relief'] = 'raised' buttons[difficulty]['relief'] = 'sunken' maze.set_difficulty(difficulty.lower()) def set_category(chosen_category, possible_categories): """Ensures a valid category is chosen""" if chosen_category in possible_categories: maze.set_category(chosen_category) else: invalid_selection = Label( new_game_menu, text="The selected category is invalid, please choose a " "different category.", font='Times 16', pady=5) invalid_selection.grid(row=5, column=0, columnspan=4) new_game_menu = Toplevel(self.root) maze = self.maze instruction_text = "Please select a category from the provided list.\nChoosing a specific category will reduce " \ "the number of\navailable questions and increase the change of repeat questions.\n Selecting" \ " no category will pull from all possible categories." selection_instruction = Label(new_game_menu, text=instruction_text, font="Times 14", pady=10) selection_instruction.grid(row=0, column=0, columnspan=3) difficulty_frame = Frame(new_game_menu) difficulty_frame.grid(row=1, column=0, columnspan=3) difficulty_label = Label(difficulty_frame, text="Question difficulty: ", font="Times 16", pady=15) difficulty_label.grid(row=1, column=0) hard_button = Button(difficulty_frame, text="Hard", padx=5, font="Times 12", command=lambda: set_difficulty("Hard")) hard_button.grid(row=1, column=4) medium_button = Button(difficulty_frame, text="Medium", padx=5, font="Times 12", command=lambda: set_difficulty("Medium")) medium_button.grid(row=1, column=3) easy_button = Button(difficulty_frame, text="Easy", padx=5, font="Times 12", command=lambda: set_difficulty("Easy")) easy_button.grid(row=1, column=2) set_difficulty("Easy") dimension_frame = Frame(new_game_menu) dimension_frame.grid(row=2, column=0, columnspan=3) dimension_choices = range(3, 11) row_label = Label(dimension_frame, text="Row: ", font="Times 16", pady=15) row_label.grid(row=2, column=0, sticky=W) row_choice = StringVar() row_choice.set(4) row_select = OptionMenu(dimension_frame, row_choice, *dimension_choices) row_select.grid(row=2, column=1) col_label = Label(dimension_frame, text="Col: ", font="Times 16") col_label.grid(row=2, column=2, sticky=W) col_choice = StringVar() col_choice.set(4) col_select = OptionMenu(dimension_frame, col_choice, *dimension_choices) col_select.grid(row=2, column=3) db = SQLDatabase() category_list = db.request_category_list() category_frame = Frame(new_game_menu) category_frame.grid(row=3, column=0, columnspan=3) category_label = Label(category_frame, text="Category: ", font="Times 16", pady=15).grid(row=3, column=0) c = StringVar() category_box = ttk.Combobox(category_frame, justify='left', textvariable=c, font='Times 16') categories = [] for key in category_list.keys(): categories.append(key) category_box['values'] = categories category_box.grid(row=3, column=1) button_frame = Frame(new_game_menu) button_frame.grid(row=4, column=1) submit = Button(button_frame, text='Start', font='Times 20', command=lambda: [ set_category(c.get(), categories), self.maze.resize_maze(int(row_choice.get()), int(col_choice.get())), self.start_game(new_game=True), new_game_menu.destroy() ]) submit.grid(row=4, column=0) back_button = Button(button_frame, text='Back', font='Times 20', command=lambda: new_game_menu.destroy()) back_button.grid(row=4, column=1) def prompt(self, savefile, type): """Creates a text prompt in the text display of the game screen asking the player to confirm their save/load. Prompt message depend on whether the player wishes to save or load. Upon confirming their action the save or load is initiated with the indicated save file. savefile: name of the save file as a string type: type of request, either 'save' or 'load' """ self.clear_text_display() if type == "save": confirm_text = "Any existing data in this save file will be written over." \ "\nAre you sure you wish to continue?" ok_button = Button(self.text_display, text="Yes", font='Times 20', command=lambda: self.save_game(savefile)) else: confirm_text = "Any unsaved progress will be lost when loading a save file.\n " \ "Are you sure you wish to continue?" ok_button = Button(self.text_display, text="Yes", font='Times 20', command=lambda: self.load_game(savefile)) ok_button.grid(row=1, column=2) warning_text = Label(self.text_display, font="Times 18", padx=10, pady=10, text=confirm_text) warning_text.grid(row=0, column=1, columnspan=4) back_button = Button(self.text_display, text="No", font='Times 20', command=lambda: self.clear_text_display()) back_button.grid(row=1, column=3) def load_game(self, savefile, event=None, load_menu=None): """Attempts to open the indicated save file. If it is not found and the load request came from the load menu, nothing happens, if the load request came from in game, displays an error message in the text display before returning. If the file is found, the maze is set equal to the save file data, the existing display is switched, the game restarts with the new maze. savefile: name of the save file as a string load_menu: load menu frame, used to indicate if the load request came from the load menu or in game, default is None """ print(f'loading {savefile}') try: loadhandle = open(savefile + '.pkl', 'rb') except FileNotFoundError: if load_menu: return else: self.clear_text_display() no_file_found_text = "No save file could be found for this save slot." no_file = Label(self.text_display, text=no_file_found_text, font='Times 20', padx=30, pady=40) no_file.grid(row=0, column=0) continue_button = Button(self.text_display, text='Continue', font='Times 20', command=self.clear_text_display) continue_button.grid(row=1, column=0) return load_tone = pygame.mixer.Sound('sfx/load_tone.wav') pygame.mixer.Sound.play(load_tone) mazedata = pickle.load(loadhandle) loadhandle.close() self.maze = mazedata if not load_menu: self.display.destroy() else: load_menu.destroy() self.screen_switch(self.startmenu, self.gamescreen) self.start_game() self.check_end_game() def save_game(self, savefile): """ Sets the time elapsed field for the maze and saves the current maze to the indicated save file. Displays a message in the text display to tell the player that the save was completed. savefile: name of the save file as a string """ self.maze.set_time_elapsed(self.start_time, int(time.time())) self.start_time = int(time.time()) savehandle = open(savefile + '.pkl', 'wb') pickle.dump(self.maze, savehandle) savehandle.close() self.clear_text_display() confirmation = Label( self.text_display, font="Times 18", pady=10, padx=120, text="Successfully saved", ) confirmation.grid(row=0, column=0) back_button = Button(self.text_display, text="Continue", font='Times 18', command=self.clear_text_display) back_button.grid(row=1, column=0) save_tone = pygame.mixer.Sound('sfx/save_tone.wav') pygame.mixer.Sound.play(save_tone) def display_load_menu(self): """ Builds a load menu that displays the three save slots. Loads the save information if the save file exists and uses different maze methods/fields to obtain information about the save such as the maze size, player location, trivia category, trivia difficulty, and time spent in game and displays this info. """ saves = Frame(self.root, height=650, width=650, bg='SystemButtonFace') saves.grid(row=0, column=0) save = [] load_instruct = "Loading will take a few seconds, and can be inconsistent.\n" \ "Wait a moment before clicking a save file again or exit the load menu and try again." instruct = Label(saves, text=load_instruct, font='Times 12', pady=10) instruct.grid(row=0, column=0) for i in range(1, 4): savelabel = LabelFrame(saves, height=175, width=550, text=f'Save {i}', cursor='hand1', font='Times 16') savelabel.grid(row=i, column=0, sticky=E) savelabel.grid_propagate(0) try: loadhandle = open(f'save_file_{i}.pkl', 'rb') maze = pickle.load(loadhandle) info = [ f'Rows: {maze.get_size()[0]}', f'Columns: {maze.get_size()[1]}', f'Difficulty: {maze.difficulty}', f'Category: {maze.category}', f'Position: {maze.player_location}', f'Time: {maze.get_time()}' ] for j in range(len(info)): label = Label(savelabel, text=info[j], font='Times 14', anchor=W, padx=5, pady=10) label.grid(row=j % 2, column=j // 2, sticky=W) loadhandle.close() save_file = "save_file_" + str(i) savelabel.bind( '<Button-1>', partial(self.load_game, save_file, load_menu=saves)) except FileNotFoundError: continue save.append(savelabel) back_button = Button( saves, text="Back", font='Times 20', anchor=N, command=lambda: self.screen_switch(saves, self.startmenu)) back_button.grid(row=4, column=0) def start_game(self, new_game=False): """Builds game screen and database of questions, switches to game screen, saves the current time for use in tracking the play time. new_game: boolean indicating if the game is being loaded from a save file or if it is a new game """ if new_game: self.maze.construct() self.screen_switch(self.startmenu, self.gamescreen) for item in self.gamescreen.winfo_children(): item.destroy() self._menu_init() self._movement_interface_init() size = self.maze.get_size() self.display = Canvas(self.gamescreen, height=size[0] * 100, width=size[1] * 100, bg="gray") self.drawer = Drawer(self.maze, self.display) self.drawer.draw() self.display.grid(row=0, column=0, columnspan=4) self.db = SQLDatabase(self.maze.category, self.maze.difficulty, self.maze.get_total_doors()) self.db.build_database() self.start_time = int(time.time()) def screen_switch(self, curr_frame, new_frame): """Switches the main display from the current frame to the desired frame. curr_frame: current frame that is being displayed new_frame: the desired frame """ curr_frame.grid_forget() new_frame.grid(row=0, column=0) """Game Screen""" def _menu_init(self): """Creates the menubar consisting of options for loading a game, saving the current game, getting instructions, or exiting the game.""" def confirm_exit(root): """Creates a popup that makes sure the user wishes to exit the program.""" def close(): root.destroy() def back(): warning.destroy() warning = Toplevel() warning_text = Label(warning, font="Times 20", pady=10, text="Are you sure you wish to exit? \n" "Any unsaved progress will not be kept.") warning_text.grid(row=0, column=0, columnspan=4) ok_button = Button(warning, text="Ok", font='Times 16', command=close).grid(row=1, column=1) back_button = Button(warning, text="Back", font='Times 16', command=back).grid(row=1, column=2) def display_help(): """Prints out the instruction text from the in the text display.""" instruction_file = open("triviamaze_instructions.txt", 'r') instruction_text = instruction_file.read() instruction_file.close() help_window = Toplevel() help_label = Label(help_window, text=instruction_text, font='Times 14') help_label.grid(row=0, column=0) menubar = Menu(self.root) menubar.add_command(label="Help", command=display_help) savemenu = Menu(menubar, tearoff=0) savemenu.add_command( label="Save 1", command=lambda: self.prompt("save_file_1", "save")) savemenu.add_command( label="Save 2", command=lambda: self.prompt("save_file_2", "save")) savemenu.add_command( label="Save 3", command=lambda: self.prompt("save_file_3", "save")) menubar.add_cascade(label="Save", menu=savemenu) loadmenu = Menu(menubar, tearoff=0) loadmenu.add_command( label="Load 1", command=lambda: self.prompt("save_file_1", "load")) loadmenu.add_command( label="Load 2", command=lambda: self.prompt("save_file_2", "load")) loadmenu.add_command( label="Load 3", command=lambda: self.prompt("save_file_3", "load")) menubar.add_cascade(label="Load", menu=loadmenu) menubar.add_command(label="Exit", command=lambda: confirm_exit(self.root)) self.root.config(menu=menubar) def _movement_interface_init(self): """Creates the interface allowing player movement, binds arrow keys to different movements.""" self.text_display = Frame(self.gamescreen, height=200, width=600, borderwidth=1) self.text_display.grid_propagate(0) self.text_display.grid(row=1, column=0) movementframe = Frame(self.gamescreen) self.north = Button(movementframe, text="North", command=lambda: self.display_question("north"), pady=5) self.north.grid(row=1, column=2, columnspan=2) self.south = Button(movementframe, text="South", command=lambda: self.display_question("south"), pady=5) self.south.grid(row=3, column=2, columnspan=2) self.east = Button(movementframe, text="East", command=lambda: self.display_question("east"), pady=5) self.east.grid(row=2, column=4) self.west = Button(movementframe, text="West", command=lambda: self.display_question("west"), pady=5) self.west.grid(row=2, column=1) movementframe.grid(row=1, column=1) self.gamescreen.bind('<Left>', partial(self.arrowKey, "west")) self.gamescreen.bind('<Right>', partial(self.arrowKey, "east")) self.gamescreen.bind('<Up>', partial(self.arrowKey, "north")) self.gamescreen.bind('<Down>', partial(self.arrowKey, "south")) self.gamescreen.focus_set() def arrowKey(self, direction, event=None): if self.maze.check_direction(self.maze.player_location[0], self.maze.player_location[1], direction): self.display_question(direction) else: pass def _set_move_button_state(self): """Sets the state of the movement buttons depending on if the adjacent rooms can be reached from the current room or not.""" row, col = self.maze.player_location[0], self.maze.player_location[1] directions = ["north", "south", "east", "west"] buttons = [self.north, self.south, self.east, self.west] for i in range(4): if self.maze.check_direction(row, col, directions[i]): buttons[i]['state'] = "normal" else: buttons[i]['state'] = "disabled" def _move_player(self, direction, event=None, correct=True): """Moves the player if correct. If incorrect, then the corresponding door is locked. In both cases the game display is redrawn, the movement buttons are reset and any text that is in the text display is deleted. direction: string representing the direction the player is moving correct: boolean indicating if the player correctly answered the trivia question""" pygame.mixer.init() if correct: self.maze.move_player(direction) walk_sound = pygame.mixer.Sound('sfx/walk.wav') pygame.mixer.Sound.play(walk_sound) else: self.maze.lock_door(direction) door_lock_sound = pygame.mixer.Sound('sfx/door_lock.wav') pygame.mixer.Sound.play(door_lock_sound) self.drawer.draw() self._set_move_button_state() self.clear_text_display() self.check_end_game() def check_end_game(self): """Checks if either player wins or maze is no longer completable. If either condition is met, the corresponding end game screen is displayed and options for exiting and replaying are offered.""" def close(window): window.destroy() if self.maze.player_wins(): text = Label(self.text_display, text=f'Congrats, you have won the game!', font="Times 26", padx=20, pady=10) game_win_sound = pygame.mixer.Sound('sfx/game_win.wav') pygame.mixer.Sound.play(game_win_sound) elif not self.maze.is_completable(): text = Label(self.text_display, text=f'Game Over\nYou can no longer reach the exit.', font="Times 26", padx=20) game_lose_sound = pygame.mixer.Sound('sfx/game_lose.wav') pygame.mixer.Sound.play(game_lose_sound) else: return text.grid(row=0, column=0, columnspan=4) replay_button = Button( self.text_display, text="Replay", font="Times 20", command=lambda: [ self.start_menu_init(), self.screen_switch(self.gamescreen, self.startmenu) ]) replay_button.grid(row=1, column=1) exit_button = Button(self.text_display, text="Exit", font="Times 20", command=lambda: close(self.root)) exit_button.grid(row=1, column=2) def display_question(self, direction): """If a question is currently being displayed, pass. If the room that the player is moving too has already been visited, then move the player. Otherwise, pull a question from the database, and display it in the text display. direction: string representing the direction that the player is attempting to move in """ def highlight_selection(i, event=None): answer_list[i]['bg'] = 'gray' def unhighlight_selection(i, event=None): answer_list[i]['bg'] = 'SystemButtonFace' if self.text_display.winfo_children(): return destination = self.maze.find_destination(self.maze.player_location[0], self.maze.player_location[1], direction) if destination in self.maze.visited_rooms: self.maze.move_player(direction) self.drawer.draw() self._set_move_button_state() walk_short_sound = pygame.mixer.Sound('sfx/walk_short.wav') pygame.mixer.Sound.play(walk_short_sound) else: question = self.db.get_random_question() question_text = Label(self.text_display, text=f'{question[1]}', font="Times 16", justify="left", wraplength=600, anchor=W, width=600) question_text.grid(row=0, column=0) answer_list = [] answer_count = len(question) positions = [*range(1, answer_count + 1)] random.shuffle(positions) for i in range(2, answer_count): if not question[i]: return answer = Label(self.text_display, text=f'\t{question[i]}', font="Times 14", anchor=W) answer.grid(row=positions.pop() + 1, column=0, sticky=E + W) answer.bind('<Enter>', partial(highlight_selection, i - 2)) answer.bind('<Leave>', partial(unhighlight_selection, i - 2)) answer.bind( '<Button-1>', partial(self._move_player, direction, correct=(i == 2))) answer_list.append(answer) def clear_text_display(self): """Clears items in the text display.""" for item in self.text_display.winfo_children(): item.destroy()
class App(threading.Thread): def __init__(self, connection: socket): threading.Thread.__init__(self) self.start() def run(self): self.canvas = "500x500" self.labelFont = ('times', 20, 'bold') self.buttonFont = ('times', 10, 'bold') self.root = Tk() self.root.geometry(self.canvas) self.connection = connection # Create a frame self.app = Frame(self.root, bg="white") self.app.grid() self.app.focus_set() self.initGuiElements() self.initVideoStream(STREAM_HOST) self.initJoystick() self.root.mainloop() def initVideoStream(self, STREAM_HOST): # Create a label in the frame self.lmain = Label(self.app) self.lmain.grid(row=0, column=1) self.videoStream = VideoStreamThread(self.lmain, STREAM_HOST) self.videoStream.start() def initGuiElements(self): self.sliderTilt = PositionSlider('t', self.root, from_=-90, to=90, tickinterval=20, orient=HORIZONTAL, troughcolor='grey', length=200) self.sliderTilt.grid(row=1, column=0) self.sliderTilt.set(0) self.sliderPan = PositionSlider('p', self.root, from_=90, to=-30, tickinterval=5, orient=VERTICAL, troughcolor='grey', length=200, showvalue=0) self.sliderPan.grid(row=1, column=1) self.sliderPan.set(0) self.sliderPower = PositionSlider('w', self.root, from_=100, to=-100, tickinterval=20, orient=VERTICAL, troughcolor='green', length=200, showvalue=0) self.sliderPower.grid(row=1, column=2) self.sliderPower.set(0) self.lblPotent = Label(self.root, text="PotentValue: ") self.lblPotent.grid(row=2, column=0) """buttonReset = Button(root, text='Reset To Origin', command=self.resetSlider, bg='red', fg='#fff') buttonReset.config(font=buttonFont) buttonReset.grid(row=3, column=0)""" self.root.bind("<Left>", self.sliderTilt.decrement) self.root.bind("<Right>", self.sliderTilt.increment) self.root.bind("<Up>", self.sliderPan.increment) self.root.bind("<Down>", self.sliderPan.decrement) self.root.bind("<W>", self.sliderPower.increment) self.root.bind("<S>", self.sliderPower.decrement) self.root.bind('<KeyRelease-Left>', self.sliderTilt.keyReleased) self.root.bind('<KeyRelease-Right>', self.sliderTilt.keyReleased) self.root.bind('<KeyRelease-Up>', self.sliderPan.keyReleased) self.root.bind('<KeyRelease-Down>', self.sliderPan.keyReleased) self.root.bind("<KeyRelease-W>", self.sliderPower.keyReleased) self.root.bind("<KeyRelease-S>", self.sliderPower.keyReleased) def initJoystick(self): self.j = Joystick(app.sliderPan, app.sliderTilt, app.sliderPower) self.j.start()
class Spreadsheet(Frame): def __init__(self, master=None, nr=0, nc=0): Frame.__init__(self, master) self.master = master self.master.bind("<Return>", self.setCell) self.nRows = nr #number of rows self.nCols = nc #number of columns y = self.nRows * 22 + 52 x = self.nCols * 76 + 31 geo = (str(x) + "x" + str(y)) master.geometry(geo) master.configure(bg='grey') self.cells2D = [[Cell(r, c) for c in range(nc)] for r in range(nr)] self.symtab = {} self.cascaDe = {} self.focus = ("a", 1) self.daBoard = Frame(self) self.daBoard.pack(side='top') self.daFocus = Frame(self) self.daFocus.pack(side='bottom') self.daFocus.focus_set() #self.pack() self.buildtkLabels() self.buildtkCells() self.buildFocus() def buildtkLabels(self): gridzero = Label(self.daBoard) gridzero.grid(row=0, column=0) for i in range(self.nCols): colNum = Label(self.daBoard, text=str(i), borderwidth=1, relief="solid", width=8) colNum.grid(row=0, column=i + 1) for r in range(self.nRows): rowLet = Label(self.daBoard, text=chr(ord('A') + r), borderwidth=1, relief="solid", width=3) rowLet.grid(row=r + 1, column=0) def buildtkCells(self): for c in range(self.nCols): for r in range(self.nRows): tcell = Label(self.daBoard, borderwidth=1, relief="solid", width=8) tcell.grid(row=r + 1, column=c + 1) tcell.bind( "<Button-1>", lambda event, rl=r, cl=c: self.setFocus(coords=(rl, cl))) def buildFocus(self, coords=None, error=None): if (error != None): self.focusLabel = Label(self.daFocus, text=self.focus[0] + str(self.focus[1]) + ":", borderwidth=0, relief="solid", width=5) self.focusLabel.grid(row=0, column=0) self.focusEntry = Entry(self.daFocus, width=16) self.focusEntry.insert(END, str(error)) self.focusEntry.grid(row=0, column=1) elif (coords == None): self.focusLabel = Label(self.daFocus, text=self.focus[0] + str(self.focus[1]) + ":", borderwidth=0, relief="solid", width=5) self.focusLabel.grid(row=0, column=0) cell = self.getCell((self.focus[0], self.focus[1])) #print("get cell: ",cell) self.focusEntry = Entry(self.daFocus, width=16) self.focusEntry.insert(END, str(cell.expression)) self.focusEntry.grid(row=0, column=1) else: r = coords[0] c = coords[1] if (isinstance(r, str) == True): r = ord(r) - ord('a') self.focusLabel = Label(self.daFocus, text=self.focus[0] + str(self.focus[1]) + ":", borderwidth=0, relief="solid", width=2) self.focusLabel.grid(row=0, column=0) cell = self.getCell((self.focus[0], self.focus[1])) self.focusEntry = Label(self.daFocus, text=str(cell.value), borderwidth=0, relief="solid", width=16) self.focusEntry.grid(row=0, column=1) def getCell(self, event=None, coords=None): if (coords == None): r = self.focus[0] c = self.focus[1] else: r = coords[0] c = coords[1] if (isinstance(r, str) == True): r = ord(r) - ord('a') cell = self.cells2D[r][int(c)] return cell def setCell(self, event=None, coords=None, expr=None): if (coords == None): coords = (self.focus[0], self.focus[1]) if (expr == None): expr = self.focusEntry.get() #print(str(coords[0])+str(coords[1])+": "+str(expr)) r = coords[0] c = coords[1] if (isinstance(r, str) == True): r = ord(r) - ord('a') try: self.cells2D[r][c].expression = expr self.evaluate((r, c)) self.cascade((r, c)) self.setLabel(frame=self.daBoard, row=r, col=c) self.updateSymTab(row=r, col=c) print(self) except RecursionError: self.setFocus(error="Error: Cyclic Dependancy") print("Cyclic Dependancy") def evaluate(self, coords=None): if (coords == None): coords = (self.focus[0], self.focus[1]) r = coords[0] c = coords[1] try: self.cells2D[r][c].value = eval(str(self.cells2D[r][c].expression)) self.updateSymTab(r, c, self.cells2D[r][c].value) #print("eval r:",r,", c: ",c,"*****TRY", self.cells2D[r][c].value) except: doSymEval = False for sym in self.symtab: if (sym in self.cells2D[r][c].expression): doSymEval = True self.cells2D[r][c].value = self.symEvaluate( self.cells2D[r][c].expression, row=r, col=c) symCell = self.getCell(sym) """print("symEval r:",r,", c: ",c,"*****symEval*****:", self.cells2D[r][c].expression," ",self.cells2D[r][c].value, "\nSym value: ",symCell.value)""" if (doSymEval == False): #it's just a string or it has incorrect notation so save as string self.cells2D[r][c].value = self.cells2D[r][c].expression #print("FailedSymEval r:",r,", c: ",c,"*****FailedSymEval", self.cells2D[r][c].value) def symEvaluate(self, expr, row=None, col=None): for s in self.symtab: if (s in expr): if (s in self.cascaDe): csym = str(row) + str(col) if (isinstance(row, int)): cr = chr(row + 97) csym = str(cr) + str(col) self.cascaDe[s].add(csym) else: self.addToCascadeDict(s, row, col) expr = expr.replace(s, str(self.symtab[s])) #print("CascaDe: ", self.cascaDe) try: rExpr = eval(expr) #print("SYM EVAL: ",rExpr,", Expr: ",expr) return rExpr except: return expr def setLabel(self, frame=None, row=None, col=None): if (frame == None): frame = self.daBoard if (row == None): row = self.focus[0] if (col == None): col = self.focus[1] for child in frame.children.values(): info = child.grid_info() #print(info) if (info['row'] - 1 == int(row) and info['column'] - 1 == int(col)): child.config(text=str(self.cells2D[row][col].value)) def setFocus(self, event=None, coords=None, error=None): if (error != None): self.buildFocus(error=error) else: r = coords[0] c = coords[1] if (isinstance(r, int) == True): r = chr(r + 97) self.focus = (r, c) self.buildFocus() def updateSymTab(self, row=None, col=None, value=None): if (row == None): row = self.focus[0] if (col == None): col = self.focus[1] if (isinstance(row, int) == True): row = chr(row + 97) sym = str(row) + str(col) if (value == None): cell = self.getCell((row, col)) self.symtab[sym] = cell.value #print("cell Value:",cell.value) #print("symTab: ",self.symtab) else: self.symtab[sym] = value def isSym(self, sym): if (sym in self.symtab): return True return False def getSym(self, sym=None): if (isinstance(sym, tuple)): if (isinstance(sym[0]), int): r = chr(sym[0] + 97) sym = str(r) + str(sym[1]) elif (sym == None): sym = str(self.focus[0]) + str(self.focus[1]) return self.symtab[sym] def addToCascadeDict(self, sym, row, col): if (isinstance((sym[0]), int)): sr = chr(sym[0] + 97) sym = str(sr) + str(sym[1:]) if (isinstance(row, int)): cr = chr(row + 97) csym = str(cr) + str(col) self.cascaDe[sym] = {csym} def cascade(self, coords): #print("COUNTING CASCADES") cr = coords[0] cDe = coords if (isinstance(coords, tuple)): if (isinstance(coords[0], int)): cr = chr(coords[0] + 97) cDe = str(cr) + str(coords[1]) if (cDe in self.cascaDe): for C in self.cascaDe[cDe]: r = C[0] c = C[1] if (isinstance(r, str) == True): r = ord(r) - ord('a') if (isinstance(c, str) == True): c = int(c) self.evaluate((r, c)) value = self.cells2D[r][c].value self.updateSymTab(r, c, value) self.cascade((r, c)) self.setLabel(frame=self.daBoard, row=r, col=c) def __repr__(self): lStr = "" for i in self.cells2D: lStr += "[" for c in i: lStr += str(c.value) lStr += "," lStr = lStr[:-1] lStr += "]\n" return lStr def __str__(self): lStr = "" #if(neighbors == False): for i in self.cells2D: lStr += "[" for c in i: lStr += str(c.value) lStr += "," lStr = lStr[:-1] lStr += "]\n" return lStr
class QWERTYKeyboard(BaseInput): """ Gets and sends continuous keyboard input to the decoder. We utilise TKInter to get input from the keyboard. """ def __init__(self): super(QWERTYKeyboard, self).__init__() self.root = None # Root instance of TKinter self.frame = None # Instance of TKinter frame def start(self): """ We setup and configure the tkinter front end for getting keys. We also disable 'xset' on linux machines, which causes problems with how key inputs are configured. """ # Check if we are on linux: if platform.system() == 'Linux': # Disable 'xset' os.system("xset r off") # Configure TKinter input window self.root = Tk() self.frame = Frame(self.root, width=100, height=100) self.frame.bind("<KeyPress>", self.decoder.key_pressed) self.frame.bind("<KeyRelease>", self.decoder.key_released) self.frame.pack() self.frame.focus_set() self.root.mainloop() def stop(self): """ We stop the TKinter instance, and enable 'xset' if we are on linux. """ # Check if we are on linux: if platform.system() == 'Linux': # Disable 'xset' os.system("xset r on") # Disable the root instance: self.root.destroy() def run(self): """ Actual run method for QWERTYKeyboard. We start the TKinter thread, and ensure that it is configured correctly. """ pass
class Spreadsheet(Frame): def __init__(self, root = None, nRows = 0, nCols = 0): Frame.__init__(self, root) self.root = root self.root.bind("<Return>", self.setCell) self.nRows = nRows self.nCols = nCols lengthX = self.nCols*75 + 40 #use geometry to create length and width lengthY = self.nRows*24 + 60 lw = (str(lengthX)+"x"+str(lengthY)) root.geometry(lw) root.configure(bg='grey') self.gridx = [[Cell(r,c) for c in range(nCols)] for r in range(nRows)] self.symTable = {} self.dependers = {} self.board = Frame(self) self.board.pack(side='top') self.focusBox = Frame(self) self.focusBox.pack(side='bottom') self.focusBox.focus_set() self.focus = ("a", 0) self.focusLabel = None self.focusEntry = None self.remover = None self.restore = 0 #set labels A B C and 1 2 3 ect labler = Label(self.board) labler.grid(row=0, column=0) for x in range(self.nCols): colLabel = Label(self.board, text=str(x), borderwidth = 1, relief = "solid", width = 8) colLabel.grid(row=0, column=x+1) for y in range(self.nRows): rowLabel = Label(self.board, text=chr(ord('A')+y), borderwidth = 1, relief = "solid", width = 3) rowLabel.grid(row=y+1, column=0) # build all of the cells for c in range(nCols): for r in range(nRows): cellx = Label(self.board, bg="white", borderwidth = 1, relief = "solid", width = 8) cellx.grid(row=r+1, column=c+1) cellx.bind("<Button-1>", lambda event,rl = r, cl = c: self.setFocus(coords = (rl,cl))) #create the focus on the excell sheet self.createFocus() def createFocus(self, coords = None, error = None): if(error != None): self.focusLabel = Label(self.focusBox, text=self.focus[0]+str(self.focus[1])+":", borderwidth = 0, relief = "solid", width = 5) self.focusLabel.grid(row=0, column=0) self.focusEntry = Entry(self.focusBox, width = 16) self.focusEntry.insert(END, str(error)) self.focusEntry.grid(row = 0, column = 1) elif(coords == None): self.focusLabel = Label(self.focusBox, text=self.focus[0]+str(self.focus[1])+":", borderwidth = 0, relief = "solid", width = 5) self.focusLabel.grid(row=0, column=0) cellx = self.getCell((self.focus[0], self.focus[1])) self.focusEntry = Entry(self.focusBox, width = 16) self.focusEntry.insert(END, str(cellx.expression)) self.focusEntry.grid(row = 0, column = 1) else: y = coords[0] x = coords[1] #adjust cords to integers if needed if(isinstance(y,str) == True): y = ord(y) - ord('a') if(isinstance(x,str) == True): x = int(x) self.focusLabel = Label(self.focusBox, text=self.focus[0]+str(self.focus[1])+":", borderwidth = 0, relief = "solid", width = 5) self.focusLabel.grid(row=0, column=0) cellx = self.getCell((self.focus[0], self.focus[1])) self.focusEntry = Label(self.focusBox, text=str(cellx.value), borderwidth = 0, relief = "solid", width = 16) self.focusEntry.grid(row=0, column = 1) frame = self.board if coords != None: yy = coords[0] xx = coords[1] if(isinstance(yy,str) == True): yy = ord(yy) - ord('a') if(isinstance(xx,str) == True): xx = int(xx) else: xx = ord(self.focus[0]) - ord('a') yy = int(self.focus[1]) for child in frame.children.values(): info = child.grid_info() if(int(info['row'])-1 == int(xx) and int(info['column'])-1 == int(yy)): child.config(bg="Yellow") else: child.config(bg="white") def setFocus(self, event = None, coords=None, error = None): if(error != None): self.createFocus(coords = coords, error = error) else: y = coords[0] x = coords[1] if(isinstance(y, int) == True): self.focus = (chr(y+97), x) else: self.focus = (y,x) self.createFocus() def getCell(self, event = None, coords = None): if(coords == None): y = self.focus[0] x = self.focus[1] else: y = coords[0] x = coords[1] if(isinstance(y,str) == True): y = ord(y) - ord('a') if(isinstance(x,int) == False): x = int(x) return self.gridx[y][x] def myisDigit(self, strx): print("entered") if "." in strx: strx.replace(".", '') return strx.isdigit() def setCell(self, event = None, coords = None, expression = None): if(coords == None): #no coords assume focus box coords = (self.focus[0], self.focus[1]) if(expression == None or expression == ""): expression = self.focusEntry.get() y = coords[0] x = coords[1] if(isinstance(y, str) == True): y = ord(y) - ord('a') if(isinstance(x, str) == True): x = int(x) #try and evaluate error oldExpression = self.gridx[y][x].expression oldValue = self.gridx[y][x].value try: self.gridx[y][x].expression = expression self.evaluation((y,x)) self.dependencyDealing((y,x),(y,x)) self.setLabel(frame = self.board, coords = (y,x)) self.updateTable(coords = (y,x)) except: self.restore = 1 sym = str(chr(y+97))+str(x) symx = str(chr(self.remover[0]+97))+str(self.remover[1]) self.gridx[y][x].value = oldValue self.gridx[y][x].expression = oldExpression try: self.dependers[sym] = [] except: print("nothing depending on it") print(sym) messagebox.showerror("Error", "An error has occured entering this value") for x in range(self.nCols): for y in range(self.nRows): if self.gridx[y][x].expression != "": self.evaluation((y,x)) self.restore = 0 def evaluation(self, coords = None): if(coords == None): y = self.focus[0] x = self.focus[1] else: y = coords[0] x = coords[1] if(isinstance(y, str) == True): y = ord(y) - ord('a') try: self.gridx[y][x].value = eval(str(self.gridx[y][x].expression)) print(str(self.gridx[y][x].value)) self.updateTable(coords = (y,x), value = self.gridx[y][x].value) except: valueEp = 0 for symbol in self.symTable: if symbol in self.gridx[y][x].expression: valueEp = 1 self.gridx[y][x].value = self.symEvaluation(self.gridx[y][x].expression, coords = (y,x)) print("value2 : " + str(self.gridx[y][x].value)) if valueEp == 0: self.gridx[y][x].value = "" messagebox.showerror("Error", "An error has occured entering this value") def symEvaluation(self, expression, coords = None): for sym in self.symTable: if sym in expression: if sym in self.dependers: if(isinstance(coords[0], int)): symx = str(chr(coords[0]+97))+str(coords[1]) else: symx = str(coords[0])+str(coords[1]) if symx not in self.dependers[sym]: self.dependers[sym].append(symx) else: self.addDependency(sym, coords) if self.myisDigit(str(self.symTable[sym])) == False: print("isFalse") symz = "'"+ str(self.symTable[sym]) + "'" else: symz = str(self.symTable[sym]) expression = expression.replace(sym, symz) try: print("expression: "+ expression) result = eval(expression) print("result: " + str(result)) return result except: messagebox.showerror("Error", "An error has occured entering this value") return "" def addDependency(self, sym, coords): if(isinstance((sym[0]), int)): x = chr(sym[0]+97) sym = str(x)+str(sym[1:]) if(isinstance(coords[0], int)): y = chr(coords[0]+97) else: y = coords[0] setsym = str(y)+str(coords[1]) self.dependers[sym] = [setsym] def updateTable(self, coords = None, value = None): if(coords == None): y = self.focus[0] x = self.focus[1] else: y = coords[0] x = coords[1] if(isinstance(y, int) == True): y = chr(y+97) val = str(y) + str(x) if(value == None): cellx = self.getCell((y,x)) self.symTable[val] = cellx.value else: self.symTable[val] = value def setLabel(self, frame = None, coords = None): if(frame == None): frame = self.board if(coords == None): coords = (focus[0], focus[1]) for child in frame.children.values(): info = child.grid_info() if(int(info['row'])-1 == int(coords[0]) and int(info['column'])-1 == int(coords[1])): child.config(text=str(self.gridx[coords[0]][coords[1]].value)) def dependencyDealing(self, coords, cCoords = None): if(isinstance(coords,tuple)): if(isinstance(coords[0], int)): row = chr(coords[0]+97) else: row = coords[0] coordx = str(row)+str(coords[1]) else: coordx = coords if coordx in self.dependers: for loc in self.dependers[coordx]: r = loc[0] c = loc[1:] if(isinstance(r, str) == True): r = ord(r) - ord('a') if(isinstance(c, str) == True): c = int(c) cordx = (r,c) if cordx == cCoords and self.restore != 1: self.remover = coords raise OverflowError() else: self.evaluation((r,c)) valuex = self.gridx[r][c].value self.updateTable(coords = (r,c), value = valuex) self.dependencyDealing((r,c), cCoords) self.setLabel(frame = self.board, coords = (r, c))
class TrailBlazerGUI: ''' Defines the graphical user interface, which displays and allows users to interact with various modules. ''' def __init__(self, master): ''' Initializes the GUI. ''' self.master = master self.bg = "#90EE90" self.fg = "#654321" self.e_page = "empty" master.title("Trail Blazer") master.geometry("1920x1080") master.configure(bg=self.bg) master.bind("<Escape>", self.close) self.start = Frame(master, height=1080, width=1920, bg=self.bg) self.start.pack() self.start.focus_set() self.start.bind("<Return>", self.login_page) self.greet = Label(self.start, text="Welcome to our Route Suggestion GUI!", font=("sans serif", 50), fg=self.fg, bg=self.bg, pady=10) self.greet.pack() self.intro = Message(self.start, text="We are writing software to help generate and visualize new routes for runners, walkers, and bikers. \nWe are creating this for our Software Design final project.", font=("sans serif", 20), width=1900, justify=CENTER, fg=self.fg, bg=self.bg, pady=10) self.intro.pack() self.buttons1 = Frame(self.start, width=500, bg=self.bg) self.buttons1.pack() self.proceed = Button(self.buttons1, text="Proceed", bg="#64e764", fg="#654321", pady=5, activebackground="#bcf5bc", activeforeground="#8b5d2e", command=self.login_page) self.proceed.grid(row=0, column=0) self.cancel = Button(self.buttons1, text="Cancel", bg="#64e764", fg="#654321", pady=5, activebackground="#bcf5bc", activeforeground="#8b5d2e", command=master.quit) self.cancel.grid(row=0, column=1) self.logo = PhotoImage(file="images/trail_blazer_logo.gif") self.logo_disp = Label(self.start, image=self.logo, fg=self.fg, bg=self.bg) self.logo_disp.pack(side=BOTTOM) def login_page(self, event=None): ''' Displays a page where the user can login to find a route. ''' if self.e_page != "empty": self.e_page.pack_forget() self.e_page.destroy() else: self.start.pack_forget() self.start.destroy() self.l_page = Frame(self.master, height=1080, width=1920, bg=self.bg) self.l_page.pack() self.l_page.focus_set() self.l_page.bind("<Return>", self.valid_login) self.l_page.bind("<Escape>", self.close) self.request = Label(self.l_page, text="Please log in to continue.", font=("sans serif", 20), fg=self.fg, bg=self.bg, pady=20) self.request.pack() self.login = Frame(self.l_page, width=1000, bg=self.bg) self.login.pack() self.login.bind("<Return>", self.valid_login) self.first = Label(self.login, text="First Name = ", font=("sans serif", 15), anchor=W, bg=self.bg, fg=self.fg, pady=10) self.first.grid(row=0, sticky=E) self.first_in = Entry(self.login, font=("sans serif", 15), exportselection=0, cursor="xterm") self.first_in.bind("<Return>", self.valid_login) self.first_in.grid(row=0, column=1, columnspan=3) self.last = Label(self.login, text="Last Name = ", font=("sans serif", 15), anchor=W, bg=self.bg, fg=self.fg, pady=10) self.last.grid(row=1, sticky=E) self.last_in = Entry(self.login, font=("sans serif", 15), exportselection=0, cursor="xterm") self.last_in.bind("<Return>", self.valid_login) self.last_in.grid(row=1, column=1, columnspan=3) self.user = Label(self.login, text="Username = "******"sans serif", 15), anchor=W, bg=self.bg, fg=self.fg, pady=10) self.user.grid(row=2, sticky=E) self.user_in = Entry(self.login, font=("sans serif", 15), exportselection=0, cursor="xterm") self.user_in.bind("<Return>", self.valid_login) self.user_in.grid(row=2, column=1, columnspan=3) self.pss = Label(self.login, text="Password = "******"sans serif", 15), anchor=W, bg=self.bg, fg=self.fg, pady=10) self.pss.grid(row=3, sticky=E) self.pss_in = Entry(self.login, font=("sans serif", 15), exportselection=0, cursor="xterm", show="*") self.pss_in.bind("<Return>", self.valid_login) self.pss_in.grid(row=3, column=1, columnspan=3) self.buttons2 = Frame(self.l_page, width=500, bg=self.bg) self.buttons2.pack() self.submit = Button(self.buttons2, text="Submit", bg="#64e764", fg="#654321", pady=5, activebackground="#bcf5bc", activeforeground="#8b5d2e", command=self.valid_login) self.submit.bind("<Return>", self.valid_login) self.submit.grid(row=0, column=0) self.cancel = Button(self.buttons2, text="Cancel", bg="#64e764", fg="#654321", pady=5, activebackground="#bcf5bc", activeforeground="#8b5d2e", command=self.master.quit) self.cancel.bind("<Return>", self.valid_login) self.cancel.grid(row=0, column=1) def home_page(self, event=None): ''' Displays the GUI home page, where user can find the weather of a given location and request a route. ''' first_name = self.first_in.get() last_name = self.last_in.get() self.l_page.pack_forget() self.l_page.destroy() self.h_page = Frame(self.master, height=1080, width=1920, bg=self.bg) self.h_page.pack() self.h_page.focus_set() self.h_page.bind("<Return>", self.find_route) self.h_page.bind("<Escape>", self.close) self.hello = Label(self.h_page, text="Hello! Welcome to your profile page!", font=("sans serif", 50), bg=self.bg, fg=self.fg, pady=20) self.hello.pack() self.weather_init = Frame(self.h_page, width=1000, bg=self.bg) self.weather_init.pack() self.weather_init.bind("<Return>", self.get_forecast) self.location = Label(self.weather_init, text="Current Location = ", font=("sans serif", 15), anchor=W, bg=self.bg, fg=self.fg, pady=10) self.location.grid(row=0, sticky=E) self.location_in = Entry(self.weather_init, font=("sans serif", 15), exportselection=0, cursor="xterm") self.location_in.bind("<Return>", self.get_forecast) self.location_in.grid(row=0, column=1) self.buttons5 = Frame(self.h_page, width=500, bg=self.bg) self.buttons5.pack() self.buttons5.bind("<Return>", self.get_forecast) self.weatherby = Button(self.buttons5, text="Find Weather", bg="#64e764", fg="#654321", activebackground="#bcf5bc", activeforeground="#8b5d2e", pady=5, command=self.get_forecast) self.weatherby.grid(row=0, column=0) self.name_is = Label(self.h_page, text="Where would you like to go, %s %s?" % (first_name, last_name), font=("sans serif", 15), fg=self.fg, bg=self.bg, pady=10) self.name_is.pack() self.profile = Frame(self.h_page, width=1000, bg=self.bg) self.profile.pack() self.profile.bind("<Return>", self.find_route) self.loc = Label(self.profile, text="Starting Location:", font=("sans serif", 15), anchor=W, bg=self.bg, fg=self.fg, pady=10) self.loc.grid(row=0, sticky=E) self.lat = Label(self.profile, text="Latitiude = ", font=("sans serif", 15), anchor=W, bg=self.bg, fg=self.fg, pady=10) self.lat.grid(row=1, column=0) self.lat_in = Entry(self.profile, font=("sans serif", 15), exportselection=0, cursor="xterm") self.lat_in.bind("<Return>", self.find_route) self.lat_in.insert(0, "42.292922") if self.profile.focus_get() == self.lat_in: self.lat_in.delete() self.lat_in.grid(row=1, column=1) self.lng = Label(self.profile, text="Longitude = ", font=("sans serif", 15), anchor=W, bg=self.bg, fg=self.fg, pady=10) self.lng.grid(row=1, column=2) self.lng_in = Entry(self.profile, font=("sans serif", 15), exportselection=0, cursor="xterm") self.lng_in.bind("<Return>", self.find_route) self.lng_in.insert(0, "-71.263073") if self.profile.focus_get() == self.lat_in: self.lat_in.delete() self.lng_in.grid(row=1, column=3) self.dist = Label(self.profile, text="Distance(km) = ", font=("sans serif", 15), anchor=W, bg=self.bg, fg=self.fg, pady=10) self.dist.grid(row=2, sticky=E) self.dist_in = Entry(self.profile, font=("sans serif", 15), exportselection=0, cursor="xterm") self.dist_in.bind("<Return>", self.find_route) self.dist_in.grid(row=2, column=1) self.dist_max = Label(self.profile, text="Maximum distance = 2", font=("sans serif", 10), anchor=W, bg=self.bg, fg=self.fg, pady=10, padx=10) self.dist_max.grid(row=2, column=2, sticky=E) self.buttons3 = Frame(self.h_page, width=500, bg=self.bg) self.buttons3.pack() self.enter = Button(self.buttons3, text="Find Route", bg="#64e764", fg="#654321", activebackground="#bcf5bc", activeforeground="#8b5d2e", pady=5, command=self.find_route) self.enter.bind("<Return>", self.find_route) self.enter.grid(row=0, column=0) self.elev = Button(self.buttons3, text="View Elevation", bg="#64e764", fg="#654321", activebackground="#bcf5bc", activeforeground="#8b5d2e", pady=5, command=self.find_elevation) self.elev.bind("<Return>", self.find_elevation) self.elev.grid(row=0, column=1) self.cancel = Button(self.buttons3, text="Cancel", bg="#64e764", fg="#654321", activebackground="#bcf5bc", activeforeground="#8b5d2e", pady=5, command=self.master.quit) self.cancel.grid(row=0, column=2) def error(self, event=None): ''' Displays an error page if a user did not provide all of the required information. ''' self.l_page.pack_forget() self.l_page.destroy() self.e_page = Frame(self.master, height=1080, width=1920, bg=self.bg) self.e_page.pack() self.e_page.focus_set() self.e_page.bind("<Return>", self.login_page) self.e_page.bind("<Escape>", self.close) self.err_title = Label(self.e_page, text="Error: Missing Information", font=("sans serif", 50), bg=self.bg, fg=self.fg, pady=10) self.err_title.pack() self.err_mss = Message(self.e_page, text="Your submission was missing some data. All fields are rquired.\nPlease return to fill out all fields.", font=("sans serif", 20), width=1900, justify=CENTER, fg=self.fg, bg=self.bg, pady=10) self.err_mss.pack() self.buttons4 = Frame(self.e_page, width=500, bg=self.bg) self.buttons4.pack() self.ret = Button(self.buttons4, text="Return", bg="#64e764", fg="#654321", pady=5, activebackground="#bcf5bc", activeforeground="#8b5d2e", command=self.login_page) self.ret.grid(row=0, column=0) self.cancel = Button(self.buttons4, text="Cancel", bg="#64e764", fg="#654321", pady=5, activebackground="#bcf5bc", activeforeground="#8b5d2e", command=self.master.quit) self.cancel.grid(row=0, column=1) def valid_login(self, event=None): ''' Checks if a user provided all of the necessary information to login. ''' firstname = self.first_in.get() lastname = self.last_in.get() username = self.user_in.get() password = self.pss_in.get() if not firstname and not lastname and not username and not password: return self.error() else: return self.home_page() def get_forecast(self, event=None): ''' Gets and displays a weather forecast for a given location. ''' from weather import Weather, Unit self.weather = Weather(unit=Unit.FAHRENHEIT) self.local = self.weather.lookup_by_location(self.location_in.get()) self.condition = self.local.condition self.forecasts = self.local.forecast self.forecast = self.forecasts[1] self.location.destroy() self.location_in.destroy() self.buttons5.destroy() self.weather_1 = Label(self.weather_init, text="Today's weather will be %s and %s F" % (self.condition.text, self.condition.temp), font=("sans serif", 17), justify=CENTER, fg=self.fg, bg=self.bg) self.weather_1.pack() self.weather_2 = Label(self.weather_init, text="with a high of %s F and a low of %s F." % (self.forecast.high, self.forecast.low), font=("sans serif", 15), justify=CENTER, fg=self.fg, bg=self.bg) self.weather_2.pack() self.weather_3 = Label(self.weather_init, text="According to Yahoo weather on %s." % (self.condition.date), font=("sans serif", 10), justify=CENTER, fg=self.fg, bg=self.bg, pady=5) self.weather_3.pack() def find_route(self, event=None): ''' Finds and plots a route. ''' api = overpy.Overpass() lat = float(self.lat_in.get()) lng = float(self.lng_in.get()) radius = 0.01 distance = float(self.dist_in.get()) self.route = intersections.graph_it(api, lat, lng, radius, distance) intersections.plot_graph(self.route) def find_elevation(self, event=None): ''' Finds and graphs the elevations of points along a route. ''' distance = float(self.dist_in.get()) route_coords = intersections.find_route_coords(self.route) unzipped = list(zip(*route_coords)) get_elevations.plot_elevation(get_elevations.get_elevation_list(unzipped[0], unzipped[1]), distance) def close(self, event=None): self.master.quit()
def main(): # Set up game entities paddle = Paddle((guiWidth - Paddle.Width) / 2, guiHeight - Paddle.Height - 10) ball = Ball(200, 600) topWall = Wall(0, 0, guiWidth, 0) leftWall = Wall(0, 0, 0, guiHeight) rightWall = Wall(guiWidth, 0, guiWidth, guiHeight) gameEntities = [paddle, ball, topWall, leftWall, rightWall] for i in range(0, 500, 50): for j in range(100, 200, 25): gameEntities.append( Block(i, j, _from_rgb((200, int(i * 2 / 5), j + 50)))) # Set up GUI gui = Tk() gui.geometry(f"{guiWidth}x{guiHeight}") gui.title("Breakout") # Bring to front gui.lift() gui.attributes("-topmost", True) gui.attributes("-topmost", True) gui.after_idle(gui.attributes, '-topmost', False) frame = Frame(gui, width=guiWidth, height=guiHeight) canvas = Canvas(frame, width=guiWidth, height=guiHeight, bg='black') for gameEntity in gameEntities: gameEntity.addToCanvas(canvas) canvas.pack() # Set up key binding frame.bind("<Left>", lambda event: movePaddle(event, paddle, canvas, "left")) frame.bind("<Right>", lambda event: movePaddle(event, paddle, canvas, "right")) frame.pack() frame.focus_set() # While the ball is in play while canvas.coords(ball.canvasEntity)[1] < canvas.coords( paddle.canvasEntity)[1] - paddle.height + 1: for gameEntity in gameEntities: if isinstance(gameEntity, Ball): # Ball can't collide with itself continue if ball.collide(gameEntity, canvas): if isinstance(gameEntity, Block): # Ball collided with block so destroy it canvas.delete(gameEntity.canvasEntity) gameEntities.remove(gameEntity) ball.increaseSpeed() if isinstance(gameEntity, Paddle): # Ball collided with paddle, need to update its velocity vector gameEntity.updateBallVelocity(ball, canvas) # Update paddle position if (paddle.step != 0): canvas.move(paddle.canvasEntity, 10 * paddle.step, 0) paddle.step = 0 # Update ball position canvas.move(ball.canvasEntity, ball.getVelocityX(), ball.getVelocityY()) canvas.update() exit()
def _activate_frame(frame: tkinter.Frame) -> None: frame.tkraise() frame.focus_set()