Example #1
0
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()
Example #2
0
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']
Example #4
0
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")
Example #5
0
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
Example #6
0
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()
Example #8
0
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)
Example #9
0
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()
Example #10
0
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()
Example #11
0
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()
Example #12
0
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()
Example #13
0
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
Example #14
0
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
Example #15
0
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))
Example #16
0
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()
Example #17
0
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()
Example #18
0
def _activate_frame(frame: tkinter.Frame) -> None:
    frame.tkraise()
    frame.focus_set()