Beispiel #1
0
	def toggle_items(self, btn: tk.Button, frm: tk.Frame):
		if btn['bg'] == 'gray':
			frm.pack(side=tk.BOTTOM)
			btn['bg'] = 'white'
		else:
			frm.pack_forget()
			btn['bg'] = 'gray'
Beispiel #2
0
class LoginScreen(Window):
    def __init__(self, program):
        super().__init__(program)
        self.levels = None
        self.settings = program.settings
        self.level_handler = LevelHandler(program.settings)
        self.frame = Frame(program.master, width=800, height=800)
        self.frame.pack(side='top', fill='both', expand=1)
        self.show()

    def add_button(self, text, command):
        button = Button(self.frame,
                        text=text,
                        width=100,
                        height=20,
                        command=command)
        button.pack()

    def dispose(self):
        self.frame.pack_forget()
        self.frame.destroy()
        self.frame = None

    def show(self):
        self.add_button('New Game', self.new_game)
        self.add_button('Load Game', self.load_game)
        self.add_button('Exit', self.exit)
        self.frame.tkraise()

    def new_game(self):
        self.dispose()
        g = Game(self.program)
        g.new()
        self.change(Game(self.program))

    def exit(self):
        self.program.exit()

    def load_game(self):
        self.dispose()
        lg = LoadGame(self.program)
        lg.show()
        self.change(lg)

    def clear(self):
        self.frame.pack_forget()
        self.level_handler = None
        self.frame.destroy()
Beispiel #3
0
class Level:
    def __init__(self, calc, levels, current=None):
        self.calc = calc
        self.master = calc.master
        self.levels = levels #allowed levels in current game
        self.current = current
        self.leveldone_image = Image.open(r'images\done.png').resize((20, 20), Image.ANTIALIAS)
        self.levelundone_image = Image.open(r'images\undone.png').resize((20, 20), Image.ANTIALIAS)
        self.levelpending_image = Image.open(r'images\pending.png').resize((20, 20), Image.ANTIALIAS)
        self.leveldone_photo = ImageTk.PhotoImage(self.leveldone_image)
        self.levelundone_photo = ImageTk.PhotoImage(self.levelundone_image)
        self.levelpending_photo = ImageTk.PhotoImage(self.levelpending_image)
        self.field = Frame(self.master)
        self.update()

    def response(self, i):
        self.calc.start_game(i)

    def update(self):
        #assuming levels preserves order and current >= levels[0]
        self.field.pack_forget()
        image = self.leveldone_photo
        labeling = False
        if self.current is None:
            self.current = self.identify_level()
        self.labels = dict()
        for i in self.levels:
            if i == self.current:
                image = self.levelpending_photo
                self.labels[i] = Button(self.field, image=image, command=lambda x=i: self.response(x), bg='green')
                self.labels[i].pack(side="left")
                image = self.levelundone_photo
                labeling = True
                continue
            if not(labeling):
                self.labels[i] = Button(self.field, image=image, command=lambda x=i: self.response(x))
                self.labels[i].pack(side="left")
            else:
                self.labels[i] = Label(self.field, image=image)
                self.labels[i].pack(side="left")
        self.field.grid(row=0, column=5, columnspan=2, sticky="nesw")

    def remove(self):
        for n in self.labels.values():
            n.pack_forget()

    def identify_level(self):
        return read('register.txt', pprint=False, allowed=self.levels)
Beispiel #4
0
class LoadGame(Window):
    def __init__(self, program):
        super().__init__(program)
        self.frame = Frame(program.master, width=800, height=800)
        self.frame.pack(side='top', fill='both', expand=1)
        self.listbox = Listbox()
        self.save_names = []

    def dispose(self):
        self.listbox.pack_forget()
        self.frame.pack_forget()
        self.listbox.destroy()
        self.frame.destroy()
        self.listbox = None
        self.frame = None

    def show(self):
        for file_name, file_path in self.program.settings.list_saves():
            self.listbox.insert(END, file_name)
            self.save_names.append(file_name)
        self.listbox.pack()
        self.add_button('Back', self.back)
        self.add_button('Load', self.load)

    def load(self):
        selection = next(iter(map(int, self.listbox.curselection())))
        self.dispose()
        g = Game(self.program)
        g.load(self.save_names[selection])
        self.change(g)

    def back(self):
        self.dispose()
        self.change(LoginScreen(self.program))

    def add_button(self, text, command):
        button = Button(self.frame,
                        text=text,
                        width=100,
                        height=20,
                        command=command)
        button.pack()
Beispiel #5
0
class Confirmation:
    def __init__(self, root, message, experiment):
        self.experiment = experiment
        self.frame = Frame(root)
        self.frame.pack(fill=X)
        self.label = Label(self.frame, text=message)
        self.label.pack()
        self.button = Button(self.frame, text="Open", command=self.open)
        self.button.pack()
        self.button = Button(self.frame, text="Dismiss", command=self.close)
        self.button.pack()

    def open(self):
        webbrowser.open(
            f'https://app.labstep.com/experiment-workflow/{self.experiment.id}/results',
            new=2)
        self.frame.pack_forget()

    def close(self):
        self.frame.pack_forget()
Beispiel #6
0
class Window:
    """
    Abstract Window class
    """
    def __init__(self, root):
        self.root = root
        self.frame = Frame(master=self.root,
                           bd=0,
                           height=670,
                           width=1280,
                           bg=BACKGROUND)

    def show(self):
        self.frame.pack(side=TOP)
        self.frame.pack_propagate(0)

    def hide(self):
        self.frame.pack_forget()

    def update(self):
        self.frame.update()
Beispiel #7
0
class Component:

    def __init__(self, app):
        self.nav = Frame(app.nav, bg="#5a5a5a")
        self.app = app
        self.range = [0, 200]

    def render(self):
        self.nav.pack(side="left")

    def receive_range(self):
        self.range = self.app.current_range

    def receive_grid(self, grid):
        pass

    def size_changed(self):
        pass

    def uninstall(self):
        self.nav.pack_forget()
        self.app.components.remove(self)
class Scene(object):
    scenemanager = SceneManager()

    def __init__(self, root):
        self.frame = Frame(root)

    def hide_scene(self):
        self.frame.pack_forget()

    def show_scene(self, *args, **kwargs):
        self.frame.pack(fill="both", expand=True)

    def start_scene(self):
        pass

    def update(self):
        pass

    def tick_update(self):
        pass

    def __repr__(self):
        return f"SceneObject<{self.__class__.__name__}>"
Beispiel #9
0
 def pack_forget(self, *args, **kargs):
     self._game_scene.restart_game()
     Frame.pack_forget(self, *args, **kargs)
Beispiel #10
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
class GraphyInspector:

    def __init__(self, parent):

        self.parent = parent

        self.width = self.parent.right_frame_width
        self.padding = self.parent.right_frame_padding

        self.frame = Frame(master=self.parent.right_frame)
        self.frame.pack(side='top', fill='y', )

        # "Inspector" title bar
        self.title_frame = Frame(master=self.frame)
        self.title_frame.pack(side='top')
        self.title_label = Label(master=self.title_frame, text="Inspector", width=self.width, bg='lightgray')
        self.title_label.pack()

        # identifier for type of object selected
        self.type_frame = Frame(master=self.frame, relief='sunken')
        self.type_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
        self.type_label1 = Label(master=self.type_frame, width=int(self.width/2)-self.padding, text='Object:')
        self.type_label1.pack(side='left', padx=self.padding, pady=self.padding)
        self.type_label2 = Label(master=self.type_frame, width=int(self.width / 2) - self.padding, text='', bg='white')
        self.type_label2.pack(side='right', padx=self.padding, pady=self.padding)

        # label of selected object (i.e. name user gives them, no canvas IDs here)
        self.label_frame = Frame(master=self.frame, relief='sunken')
        self.label_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
        self.label_label = Label(master=self.label_frame, width=int(self.width/2)-self.padding, text="Label:")
        self.label_label.pack(side='left', padx=self.padding, pady=self.padding)
        self.label_var = StringVar()
        self.label_var.set('')
        self.label_entry = Entry(self.label_frame, width=int(self.width/2)-self.padding, textvariable=self.label_var)
        self.label_entry.pack(side='right', padx=self.padding, pady=self.padding)
        self.label_entry.bind('<Button-1>', self.select_label_text)
        self.label_entry.bind('<Return>', self.drop_widget_focus)

        # status identifier (for vertices and layers)
        self.status_frame = Frame(master=self.frame, relief='sunken')
        self.status_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
        self.status_label1 = Label(master=self.status_frame, width=int(self.width/2)-self.padding, text='Status:')
        self.status_label1.pack(side='left', padx=self.padding, pady=self.padding)
        self.status_label2 = Label(master=self.status_frame, width=int(self.width/2)-self.padding, text='', bg='white')
        self.status_label2.pack(side='right', padx=self.padding, pady=self.padding)
        self.activation_var = StringVar()
        self.activation_var.set('')
        self.activation_menu = OptionMenu(self.status_frame, self.activation_var, "Identity", "Sigmoid", "ReLU", "Logarithmic", "Exponential")
        self.activation_menu.pack(side='right', padx=self.padding, pady=self.padding)

        # weight identifier (for edges only)
        self.weight_frame = Frame(master=self.frame, relief='sunken')
        self.weight_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
        self.weight_label = Label(master=self.weight_frame, width=int(self.width/2)-self.padding, text="Weight:")
        self.weight_label.pack(side='left', padx=self.padding, pady=self.padding)
        self.weight_var = DoubleVar()
        self.weight_entry = Entry(self.weight_frame, width=int(self.width / 2) - self.padding, textvariable=self.weight_var)
        self.weight_entry.pack(side='right', padx=self.padding, pady=self.padding)
        self.weight_entry.bind('<Button-1>', self.select_weight_text)
        self.weight_entry.bind('<Return>', self.drop_widget_focus)

        # node count identifier (for layers only)
        self.node_frame = Frame(master=self.frame, relief='sunken')
        self.node_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
        self.node_label = Label(master=self.node_frame, width=int(self.width/2)-self.padding, text="Node Count:")
        self.node_label.pack(side='left', padx=self.padding, pady=self.padding)
        self.node_var = IntVar()
        self.node_entry = Entry(self.node_frame, width=int(self.width / 2) - self.padding, textvariable=self.node_var)
        self.node_entry.pack(side='right', padx=self.padding, pady=self.padding)
        self.node_entry.bind('<Button-1>', self.select_node_text)
        self.node_entry.bind('<Return>', self.drop_widget_focus)

        # leakiness
        self.leakiness_frame = Frame(master=self.frame, relief='sunken')
        self.leakiness_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
        self.leakiness_label = Label(master=self.leakiness_frame, width=int(self.width/2)-self.padding, text="Leakiness")
        self.leakiness_label.pack(side='left', padx=self.padding, pady=self.padding)
        self.leakiness_var = DoubleVar()
        self.leakiness_entry = Entry(self.leakiness_frame, width=int(self.width / 2) - self.padding, textvariable=self.leakiness_var)
        self.leakiness_entry.pack(side='right', padx=self.padding, pady=self.padding)
        self.leakiness_entry.bind('<Button-1>', self.select_leakiness_text)
        self.leakiness_entry.bind('<Return>', self.drop_widget_focus)

        # bias
        self.bias_frame = Frame(master=self.frame, relief='sunken')
        self.bias_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
        self.bias_label = Label(master=self.bias_frame, width=int(self.width/2)-self.padding, text="Bias:")
        self.bias_label.pack(side='left', padx=self.padding, pady=self.padding)
        self.bias_var = DoubleVar()
        self.bias_entry = Entry(self.bias_frame, width=int(self.width / 2) - self.padding, textvariable=self.bias_var)
        self.bias_entry.pack(side='right', padx=self.padding, pady=self.padding)
        self.bias_entry.bind('<Button-1>', self.select_bias_text)
        self.bias_entry.bind('<Return>', self.drop_widget_focus)

        # output bound
        self.bound_frame = Frame(master=self.frame, relief='sunken')
        self.bound_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
        self.bound_label = Label(master=self.bound_frame, width=int(self.width/2)-self.padding, text="Output Bound:")
        self.bound_label.pack(side='left', padx=self.padding, pady=self.padding)
        self.bound_var = DoubleVar()
        self.bound_entry = Entry(self.bound_frame, width=int(self.width / 2) - self.padding, textvariable=self.bound_var)
        self.bound_entry.pack(side='right', padx=self.padding, pady=self.padding)
        self.bound_entry.bind('<Button-1>', self.select_bound_text)
        self.bound_entry.bind('<Return>', self.drop_widget_focus)

        # noise
        self.noise_frame = Frame(master=self.frame, relief='sunken')
        self.noise_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
        self.noise_label = Label(master=self.noise_frame, width=int(self.width/2)-self.padding, text="Weight Noise:")
        self.noise_label.pack(side='left', padx=self.padding, pady=self.padding)
        self.noise_var = DoubleVar()
        self.noise_entry = Entry(self.noise_frame, width=int(self.width / 2) - self.padding, textvariable=self.noise_var)
        self.noise_entry.pack(side='right', padx=self.padding, pady=self.padding)
        self.noise_entry.bind('<Button-1>', self.select_noise_text)
        self.noise_entry.bind('<Return>', self.drop_widget_focus)

        # input / output
        self.input_output_frame = Frame(master=self.frame, relief='sunken')
        self.input_output_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
        self.input_var = BooleanVar()
        self.input_var.set(False)
        self.output_var = BooleanVar()
        self.output_var.set(False)
        self.input_toggle = Checkbutton(master=self.input_output_frame, text="Is Input", variable=self.input_var)
        self.output_toggle = Checkbutton(master=self.input_output_frame, text="Is Output", variable=self.output_var)
        self.input_toggle.pack(side='left', padx=self.padding, pady=self.padding)
        self.output_toggle.pack(side='left', padx=self.padding, pady=self.padding)

        self.selected = None
        self.selected_type = None
        self.set_unselected()

        self.label_var.trace('w', self.set_selected_label)
        self.weight_var.trace('w', self.set_selected_weight)
        self.activation_var.trace('w', self.set_selected_activation)
        self.leakiness_var.trace('w', self.set_selected_leakiness)
        self.node_var.trace('w', self.set_selected_node_count)
        self.bias_var.trace('w', self.set_selected_bias)
        self.bound_var.trace('w', self.set_selected_bound)
        self.noise_var.trace('w', self.set_selected_noise)
        self.input_var.trace('w', self.set_input)
        self.output_var.trace('w', self.set_output)

        # mode
        self.mode = parent.mode
        self.set_mode(parent.mode)

    # object is a vertex or edge, type is 'vertex' or 'edge'...
    def set_selected(self, selected_object, selected_object_type):

        self.selected = selected_object
        self.selected_type = selected_object_type

        if self.mode == "Graph":
            if selected_object_type == 'vertex':
                self.type_label2.config(text="Vertex")
                self.status_label2.config(text=selected_object.status)

                self.type_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
                self.label_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
                self.status_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)

                self.label_var.set(selected_object.label)

            elif selected_object_type == 'edge':
                self.type_label2.config(text="Edge")

                self.type_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
                self.label_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
                self.weight_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)

                self.label_var.set(selected_object.label)
                self.weight_var.set(selected_object.weight)

            else:
                print('dafuq is going on')

        elif self.mode == "Net":
            if selected_object_type == 'vertex':
                self.type_label2.config(text="Layer")
                self.status_label2.config(text=selected_object.status)

                self.type_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
                self.label_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
                self.status_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
                self.node_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
                self.leakiness_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
                self.bias_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
                self.bound_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
                self.input_output_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)

                self.label_var.set(selected_object.label)
                self.node_var.set(selected_object.node_count)
                self.activation_var.set(selected_object.status)
                self.leakiness_var.set(selected_object.leakiness)
                self.bias_var.set(selected_object.bias)
                self.bound_var.set(selected_object.bound)
                self.input_var.set(selected_object.is_input_layer)
                self.output_var.set(selected_object.is_output_layer)

            elif selected_object_type == 'edge':
                self.type_label2.config(text="Weights")

                self.type_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
                self.label_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
                self.weight_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)
                self.noise_frame.pack(side='top', fill='x', pady=self.padding, padx=self.padding)

                self.label_var.set(selected_object.label)
                self.weight_var.set(selected_object.weight)
                self.noise_var.set(selected_object.noise)

        else:
            print('This will never happen.')

    # nothing is selected
    def set_unselected(self):
        self.type_frame.pack_forget()
        self.label_frame.pack_forget()
        self.status_frame.pack_forget()
        self.weight_frame.pack_forget()
        self.node_frame.pack_forget()
        self.bias_frame.pack_forget()
        self.bound_frame.pack_forget()
        self.noise_frame.pack_forget()
        self.input_output_frame.pack_forget()
        self.leakiness_frame.pack_forget()
        self.selected = None
        self.selected_type = None

    # set label of selected object
    def set_selected_label(self, *args):
        self.selected.set_label(self.label_var.get())

    # set weight of selected object
    def set_selected_weight(self, *args):
        self.selected.set_weight(self.weight_var.get())

    def set_selected_activation(self, *args):
        self.selected.set_status(self.activation_var.get())

    def set_selected_node_count(self, *args):
        self.selected.set_node_count(self.node_var.get())

    def set_selected_bias(self, *args):
        self.selected.set_bias(self.bias_var.get())

    def set_selected_bound(self, *args):
        self.selected.set_bound(self.bound_var.get())

    def set_selected_noise(self, *args):
        self.selected.set_noise(self.noise_var.get())

    def set_input(self, *args):
        self.selected.set_input_layer(self.input_var.get())

    def set_output(self, *args):
        self.selected.set_output_layer(self.output_var.get())

    def set_selected_leakiness(self, *args):
        self.selected.set_leakiness(self.leakiness_var.get())

    def update(self):
        if self.selected:
            selected = self.selected
            type = self.selected_type
            self.set_unselected()
            self.set_selected(selected, type)

    def select_label_text(self, event):
        if event:
            # delay so the default click doesn't undo selection, then recall and fall through to "else"
            self.parent.tk.after(50, self.select_label_text, False)
        else:
            self.label_entry.select_range(0, 'end')
            self.label_entry.icursor(0)

    def select_weight_text(self, event):
        if event:
            # delay so the default click doesn't undo selection, then recall and fall through to "else"
            self.parent.tk.after(50, self.select_weight_text, False)
        else:
            self.weight_entry.select_range(0, 'end')
            self.weight_entry.icursor(0)

    def select_node_text(self, event):
        if event:
            self.parent.tk.after(50, self.select_node_text, False)
        else:
            self.node_entry.select_range(0, 'end')
            self.node_entry.icursor(0)

    def select_bias_text(self, event):
        if event:
            self.parent.tk.after(50, self.select_bias_text, False)
        else:
            self.bias_entry.select_range(0, 'end')
            self.bias_entry.icursor(0)

    def select_noise_text(self, event):
        if event:
            self.parent.tk.after(50, self.select_noise_text, False)
        else:
            self.noise_entry.select_range(0, 'end')
            self.noise_entry.icursor(0)

    def select_bound_text(self, event):
        if event:
            self.parent.tk.after(50, self.select_bound_text, False)
        else:
            self.bound_entry.select_range(0, 'end')
            self.bound_entry.icursor(0)

    def select_leakiness_text(self, event):
        if event:
            self.parent.tk.after(50, self.select_leakiness_text, False)
        else:
            self.leakiness_entry.select_range(0, 'end')
            self.leakiness_entry.icursor(0)

    def drop_widget_focus(self, event):
        self.frame.focus()

    def set_mode(self, mode):
        if mode == "Graph":
            self.mode = mode
            self.weight_label.config(text="Weight:")
            self.status_label1.config(text="Status:")
            self.activation_menu.pack_forget()
            self.input_output_frame.pack_forget()
            self.status_label2.pack(side='right', padx=self.padding, pady=self.padding)
        elif mode == "Net":
            self.mode = mode
            self.weight_label.config(text="Start Weight:")
            self.status_label1.config(text="Activation:")
            self.status_label2.pack_forget()
            self.activation_menu.pack(side='right', padx=self.padding, pady=self.padding)
        else:
            print("This will never happen.")
Beispiel #12
0
class TelaInicial():

    #==================================================================
    def __init__(self, janela):
        janela.title("Puro Fit")
        self.janela = janela
        self.janela.configure(background="azure2")
        self.janela.geometry("325x300+400+200")

        #=Criação e posicionamento de elementos da tela
        self.frm_upper = Frame(janela, bg="azure2")
        self.frm_down = Frame(janela, bg="azure2")

        tam = 10
        self.lb_title = Label(self.frm_upper,
                              text="Puro Fit",
                              font=('arial', '30'),
                              fg="midnight blue",
                              bg="azure2")
        self.btn_plotar = Button(self.frm_down,
                                 text="Novo ajuste",
                                 command=self.proxJanelaNovo,
                                 bg="LightSkyBlue4",
                                 width=tam)
        self.btn_sair = Button(self.frm_down,
                               text="Sair",
                               command=self.janela.destroy,
                               bg="LightSkyBlue4",
                               width=tam)

        self.ocupar = Label(self.frm_upper, width=37, height=3, bg="azure2")
        self.ocupar2 = Label(self.frm_upper, width=37, height=3, bg="azure2")

        self.ocupar.pack(side=TOP)
        self.lb_title.pack(side=TOP)
        self.ocupar2.pack(side=TOP)

        self.frm_upper.pack(side=TOP)
        self.frm_down.pack(side=TOP)

        self.lb_title.pack(side=TOP)
        self.btn_plotar.pack(side=TOP)
        self.btn_sair.pack(side=BOTTOM)

    #==================================================================
    #=Passa para a próxima janela, limpando a anterior antes
    def proxJanelaNovo(self):
        self.limparJanela()
        TelaPontos(self.janela, self)

    #==================================================================
    #= Caso seja necessário retornar a essa janela, os objetos devem ser
    #= redesenhados.
    def redesenhar(self):
        self.frm_upper.pack(side=TOP)
        self.frm_down.pack(side=TOP)

        self.ocupar.pack(side=TOP)
        self.lb_title.pack(side=TOP)
        self.ocupar2.pack(side=TOP)

        self.btn_plotar.pack(side=TOP)
        self.btn_sair.pack(side=BOTTOM)

    #==================================================================
    #= Caso seja necessário sair dessa janela, os objetos devem ser apagados.
    def limparJanela(self):

        self.lb_title.pack_forget()
        self.btn_plotar.pack_forget()
        self.btn_sair.pack_forget()

        self.ocupar.pack_forget()
        self.ocupar2.pack_forget()

        self.frm_upper.pack_forget()
        self.frm_down.pack_forget()
Beispiel #13
0
class TestApp(Frame):
    def __init__(self, parent=None):
        self.root = tk()
        root = self.root
        self.parent = parent
        Frame.__init__(self)
        top_frame = Frame(root)
        bottom = Frame(root)
        box_frame = Frame(top_frame)
        label_frame = Frame(box_frame)
        input_frame = Frame(box_frame)
        bottom.pack(side=BOTTOM, fill=BOTH, expand=True)
        # Packings
        top_frame.pack(side=TOP)
        bottom.pack(side=BOTTOM, fill=BOTH, expand=True)
        box_frame.pack(side=LEFT)
        label_frame.pack(side=TOP)
        input_frame.pack(side=BOTTOM)

        # create the widgets for the top part of the GUI,
        # and lay them out
        self.ticker_field = Text(top_frame, width=5, height=1)
        self.time_range = Text(top_frame, width=2, height=1)
        ticker_label = Label(top_frame, text="Ticker:", width=5, height=1)
        time_label = Label(top_frame, text="Hrs", width=2, height=1)

        button1 = Button(root,
                         text="Recent Posts",
                         width=10,
                         height=2,
                         command=self.recent_posts)
        button3 = Button(root,
                         text="Summary",
                         width=10,
                         height=2,
                         command=self.trending_posts)
        button2 = Button(root,
                         text="All Posts",
                         width=10,
                         height=2,
                         command=self.all_posts)
        button4 = Button(root,
                         text="Open Url",
                         width=10,
                         height=2,
                         command=self.open_url)

        button1.pack(in_=top_frame, side=LEFT)
        button3.pack(in_=top_frame, side=LEFT)
        button2.pack(in_=top_frame, side=LEFT)
        button4.pack(in_=top_frame, side=LEFT)

        ticker_label.pack(in_=label_frame, side=LEFT)
        time_label.pack(in_=label_frame, side=LEFT)
        self.ticker_field.pack(in_=input_frame, side=LEFT)
        self.time_range.pack(in_=input_frame, side=LEFT)
        self.main = self.master
        self.main.geometry('1200x800+200+100')
        self.main.title('Table app')

        # btn2 = Button(self.root, text="Ticker Post History", command=self.button2)
        # btn2.pack()
        # urlbtn = Button(self.root, text="Open url", command=self.open_url)
        # urlbtn.pack()

        self.f = Frame(self.main)
        self.f.pack(fill=BOTH, expand=1)
        # df = panda_db.get_trending()
        df = panda_db.get_all_posts("8")
        # df = panda_db.get_posts_by_ticker("AI")

        self.table = Table(self.f,
                           dataframe=df,
                           showtoolbar=True,
                           showstatusbar=True)

        self.table.show()

        return

    def all_posts(self):
        date_range = str(self.time_range.get("1.0", END))
        df = panda_db.get_all_posts(date_range)
        self.table = Table(self.f,
                           dataframe=df,
                           showtoolbar=True,
                           showstatusbar=True)
        self.table.show()
        self.table.redraw()

    def recent_posts(self):
        ticker = str(self.ticker_field.get("1.0", END))
        print(ticker)
        date_range = str(self.time_range.get("1.0", END))
        self.f.pack_forget()
        df = panda_db.get_posts_by_ticker(ticker.upper(), date_range)
        self.f.pack(fill=BOTH, expand=1)
        self.table = Table(self.f,
                           dataframe=df,
                           showtoolbar=True,
                           showstatusbar=True)
        self.table.show()
        self.table.redraw()

    def trending_posts(self):
        self.f.pack_forget()
        date_range = str(self.time_range.get("1.0", END))
        df = panda_db.get_trending(date_range)
        self.f.pack(fill=BOTH, expand=1)
        self.table = Table(self.f,
                           dataframe=df,
                           showtoolbar=True,
                           showstatusbar=True)
        self.table.show()
        self.table.redraw()

    def open_url(self):
        url = self.table.selection_get()
        webbrowser.register(
            'chrome', None,
            webbrowser.BackgroundBrowser(
                "C://Users//awgra//AppData//Local//Google//Chrome//Application//chrome.exe"
            ))
        webbrowser.get('chrome').open(url)
class AOTGui:
    def __init__(self):
        self.gui =  Tk()
        self.gui.title(client_title)
        self.gui.geometry('800x500')
        self.numRow = 0
        scrollbar = Scrollbar(self.gui)
        self.canvas = Canvas(self.gui, bg='pink', yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.canvas.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.frame = Frame(self.canvas)
        self.canvas.pack(side=LEFT, fill=BOTH, expand=True)
        self.canvas.create_window(0, 0, window=self.frame, anchor=NW)
        self.var_city = StringVar(self.frame)
        self.var_file = StringVar(self.frame)
        self.var_city.set(city_list[0])
        self.var_file.set(file_list[0])

        Label(self.frame, text='Version '+str(client_version), bg='turquoise').grid(row=0, column=0)

        Label(self.frame, text='City').grid(row=1, column=0, sticky=W)
        OptionMenu(self.frame, self.var_city, *city_list).grid(row=1, column=1, sticky=W)
        Label(self.frame, text='Items', padx=15).grid(row=1, column=2, sticky=W)
        OptionMenu(self.frame, self.var_file, *file_list).grid(row=1, column=3, sticky=W)
        Button(self.frame, text='Search', command=self.cmd_search).grid(row=1, column=4, sticky=W)

        Label(self.frame, text='Item').grid(row=2, column=0, columnspan=2, sticky=W)
        Label(self.frame, text='Price', padx=15).grid(row=2, column=2, sticky=W)
        Label(self.frame, text='Black Market', padx=15).grid(row=2, column=3, sticky=W)
        Label(self.frame, text='Profit', padx=15).grid(row=2, column=4, sticky=W)

        self.gui.update()
        self.canvas.config(scrollregion=self.canvas.bbox('all'))
        self.gui.mainloop()

    def human_readable_value(self,value):
        if 1e3 <= value < 1e6:
            return str(round(value/1e3)) + ' k'
        elif 1e6 <= value:
            return str(round(value/1e6, 1)) + ' m'
        else:
            return str(value)

    def add_item(self, item_id, name, price, blackmarket, profit):
        img = PhotoImage(file='img/'+item_id+'.png')
        label = Label(self.frame, image=img)
        label.image = img
        label.grid(row=3+self.numRow, column=0, sticky=W)
        Label(self.frame, text=name).grid(row=3+self.numRow, column=1, sticky=W)
        Label(self.frame, text=self.human_readable_value(price), padx=15).grid(row=3+self.numRow, column=2, sticky=W)
        Label(self.frame, text=self.human_readable_value(blackmarket), padx=15).grid(row=3+self.numRow, column=3, sticky=W)
        Label(self.frame, text=self.human_readable_value(profit), padx=15).grid(row=3+self.numRow, column=4, sticky=W)
        self.numRow += 1
        self.gui.update()
        self.canvas.config(scrollregion=self.canvas.bbox('all'))

    def reset(self):
        self.numRow = 0
        for widget in self.frame.winfo_children()[10:]:
            widget.destroy()
        self.frame.pack_forget()

    def cmd_search(self):
        self.reset()
        city = self.var_city.get() 
        item_file = 'items/' + self.var_file.get()
        item_query = open(item_file, 'r').read().replace('\n', ',')[:-1]
        item_array = open(item_file, 'r').read().split('\n')
        r = item_requests(item_array, city)
        if not item_query:
            return
        response_city= r[0]
        response_blackmarket = r[1]
        #    response_city = requests.get(data_route + item_query + '?locations=' + city).json()
        #    response_blackmarket = requests.get(data_route + item_query + '?locations=blackmarket').json()
        offer_dict = {}
        for entry in response_city:
            item = entry['item_id']
            value = entry['sell_price_min']
            quality = entry['quality']
            name = item + "#" + str(quality)

            if value:
                offer_dict[name] = [value, 0]

        for entry in response_blackmarket:
            item = entry['item_id']
            value = entry['buy_price_max']
            time = entry['sell_price_min_date']
            a = datetime.now() - datetime.strptime(time, '%Y-%m-%dT%H:%M:%S')
            qualities = [x for x in range(entry['quality'], 6)]
            items_to_purchase = [item+"#"+str(x) for x in qualities]
            city_values = []
            for item_key in items_to_purchase:
                if item_key in offer_dict.keys():
                    item_city_value = offer_dict[item_key][0]
                    city_values.append(item_city_value)
            if len(city_values) > 0:
                offer_dict[items_to_purchase[0]] = [min(city_values), value, a]
        full_list = sorted(offer_dict.items(), key=lambda x:(x[0], -x[1][1]+x[1][0], time))
        profit_list = []

        for item in full_list:
            name = item[0]
            values_pair = item[1]
            time = values_pair[2]
            profit = round(values_pair[1]*(1-tax) - values_pair[0])
            if profit > 0 and (1 - values_pair[0] / profit) < 0.85:
                profit_list.append([name, values_pair, profit, time])

        profit_list.sort(key=lambda x:(x[2]))

        i = 0
        for item in profit_list[::-1]:
            _id, _quality = item[0].split('#')

            enchant = item[0][-3] if "@" in item[0] else '0'
            tier = _id[1]
            quality = quality_list[int(_quality) -1]
            if _id in id_to_name.keys():
                translated_name = id_to_name[_id]
            else:
                tier = ''
                enchant = ''
                translated_name = _id

            name = f'{tier}.{enchant} {translated_name}, {quality}'

            item_id = item[0].split('#')[0]
            price = item[1][0]
            blackmarket = item[1][1]
            profit = item[2]
            time = item [3]

            self.add_item(item_id, name, price, blackmarket, profit)
            i += 1
Beispiel #15
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()
Beispiel #16
0
class Tile(object):
    __spawn_anim_duration_ms = 100
    __anim_update_interval_ms = 10
    __move_speed = 5

    def __init__(self, size, value, config: GameConfig):
        """
        Create a tile
        :param size: tile size (squared width and height) in px
        :param value: tile value
        :param fg: tile foreground hex color string
        :param bg: tile background hex color string
        :param font: tile label font Tuple (face, size)
        """
        self.config = config
        self.size = size
        self.value = value
        self.fg, self.bg = config.get_tile_colors(value)
        self.font = config.get_label_font()
        self.__futures = []
        self.__current_move_future = None
        self.__current_position = None
        self.__merge_event = None
        self.__destination = None
        self.__tile = None
        self.__label = None

    def __update_value(self, new_value):
        """
        Update tile value to new one
        :param new_value: new value to set
        :return: None
        """
        self.__change_value(new_value)
        self.__update_label()

    def spawn_at(self, root, x, y):
        """
        Spawn the tile at specified position
        :param root: tile master widget
        :param x: x
        :param y: y
        :return: None
        """
        self.__tile = Frame(root, width=1, height=1)
        self.__current_position = (x, y)
        self.__tile.place(x=x, y=y, anchor=CENTER)
        self.__tile.pack_propagate(False)
        self.__update_label()

        self.__play_spawn_anim()
        pass

    def move_to(self, x=None, y=None):
        """
        Move the tile to specified position
        :param x: x
        :param y: y
        :return: None
        """
        if not self.__current_position: # do nothing if not been placed on board
            return
        if self.__current_move_future and not self.__current_move_future.done():
            self.__current_move_future.cancel()
            self.__current_position = self.__destination
            self.__tile.place(x=self.__current_position[0], y=self.__current_position[1], anchor=CENTER)
            self.__proceed_with_merge()
        if not x:
            x = self.__current_position[0]
        if not y:
            y = self.__current_position[1]
        dest = (x, y)
        if dest == self.__current_position:
            return
        self.__destination = dest
        self.__play_move_anim()

    def move_and_merge(self, merge_callback, new_value, x=None, y=None):
        self.__merge_event = (merge_callback, new_value)
        self.move_to(x, y)

    def __proceed_with_merge(self):
        if not self.__merge_event:
            return
        callback, new_value = self.__merge_event
        self.__merge_event = None
        if callback:
            callback()
        self.__update_value(new_value)

    def __change_value(self, new_value):
        self.value = new_value
        self.fg, self.bg = self.config.get_tile_colors(self.value)

    def __update_label(self):
        if self.__label:
            self.__label.config(text=self.value, bg=self.bg, fg=self.fg)
            return
        self.__label = Label(self.__tile, text=self.value, bg=self.bg, fg=self.fg, justify=CENTER, font=self.font)
        self.__label.pack(fill=BOTH, expand=True)

    @staticmethod
    def __get_direction(start, end):
        diff = end - start
        if not diff:
            return 0
        return diff / abs(diff)

    def __play_move_anim(self):
        destination_x, destination_y = self.__destination
        current_x, current_y = self.__current_position
        x_dir = self.__get_direction(current_x, destination_x)
        y_dir = self.__get_direction(current_y, destination_y)

        async def anim():
            x, y = self.__current_position
            new_x = x + x_dir * Tile.__move_speed * Tile.__anim_update_interval_ms
            new_y = y + y_dir * Tile.__move_speed * Tile.__anim_update_interval_ms
            new_x = min(destination_x, new_x) if x_dir > 0 else max(destination_x, new_x)
            new_y = min(destination_y, new_y) if y_dir > 0 else max(destination_y, new_y)
            self.__current_position = (new_x, new_y)
            self.__tile.place(x=new_x, y=new_y, anchor=CENTER)

            if (new_x, new_y) != self.__destination:
                await asyncio.sleep(Tile.__anim_update_interval_ms / 1000)   # update every 10ms
                await anim()
            else:
                self.__proceed_with_merge()

        def start_anim():
            f = asyncio.ensure_future(anim())
            self.__current_move_future = f
            f.add_done_callback(self.__remove_finished_futures)
            self.__futures.append(f)
        io_loop = asyncio.get_event_loop()
        io_loop.call_soon_threadsafe(start_anim)

    def __play_spawn_anim(self):
        step = (self.size - 1) / Tile.__spawn_anim_duration_ms

        async def anim(current_size):
            new_size = min(self.size, int(step * Tile.__anim_update_interval_ms + current_size))
            self.__tile.config(width=new_size, height=new_size)
            if new_size < self.size:
                await asyncio.sleep(Tile.__anim_update_interval_ms / 1000)   # update every 10ms
                await anim(new_size)

        def start_anim():
            f = asyncio.ensure_future(anim(1))
            f.add_done_callback(self.__remove_finished_futures)
            self.__futures.append(f)
        io_loop = asyncio.get_event_loop()
        io_loop.call_soon_threadsafe(start_anim)

    def __remove_finished_futures(self, f):
        self.__futures.remove(f)

    def destroy(self):
        for f in self.__futures:
            f.cancel()  # cancel any playing animations on destroy
        if self.__tile:
            self.__tile.pack_forget()
            self.__tile.destroy()
Beispiel #17
0
class TelaGrafico():
    #==================================================================
    def __init__(self, janela, jAnterior, px, err_x, py, err_y):

        style.use("bmh")

        self.jAnterior = jAnterior
        self.janela = janela.geometry("500x620+200+0")

        tam = 8
        #=Frame feito para conter a imagem do plot========================
        self.frm_graphic = Frame(janela,
                                 bd=10,
                                 height=300,
                                 width=500,
                                 bg="azure2")
        self.frm_buttons = Frame(janela, bd=10, bg="azure2")

        self.btn_return = Button(self.frm_buttons,
                                 text="Voltar",
                                 command=self.voltar,
                                 bg="LightSkyBlue4",
                                 width=tam)
        self.btn_plot = Button(self.frm_buttons,
                               text="Salvar",
                               command=self.salvar_imagem,
                               bg="LightSkyBlue4",
                               width=tam)

        #=====Botoes de ajuste=====
        self.btn_linear = Button(self.frm_buttons,
                                 text="Linear",
                                 bg="LightSkyBlue4",
                                 width=tam)
        self.btn_linear["command"] = partial(self.curve_plot, px, err_x, py,
                                             err_y, Fit_linear, "Linear")
        self.btn_expo = Button(self.frm_buttons,
                               text="Exponencial",
                               bg="LightSkyBlue4",
                               width=tam)
        self.btn_expo["command"] = partial(self.curve_plot, px, err_x, py,
                                           err_y, Fit_exponencial,
                                           "Exponencial")
        self.btn_quadra = Button(self.frm_buttons,
                                 text="Quadrática",
                                 bg="LightSkyBlue4",
                                 width=tam)
        self.btn_quadra["command"] = partial(self.curve_plot, px, err_x, py,
                                             err_y, Fit_quadrada, "Quadrática")
        self.btn_cube = Button(self.frm_buttons,
                               text="Cúbica",
                               bg="LightSkyBlue4",
                               width=tam)
        self.btn_cube["command"] = partial(self.curve_plot, px, err_x, py,
                                           err_y, Fit_cubica, "Cúbica")
        self.btn_racio = Button(self.frm_buttons,
                                text="Racional",
                                bg="LightSkyBlue4",
                                width=tam)
        self.btn_racio["command"] = partial(self.curve_plot, px, err_x, py,
                                            err_y, Fit_racional, "Racional")
        #==========================

        self.frm_graphic.pack(side=TOP)
        self.frm_buttons.pack(side=BOTTOM)

        self.btn_linear.grid(row=3, column=0)
        self.btn_expo.grid(row=3, column=1)
        self.btn_quadra.grid(row=3, column=2)
        self.btn_cube.grid(row=3, column=3)
        self.btn_racio.grid(row=3, column=4)

        self.btn_return.grid(row=5, column=0)
        self.btn_plot.grid(row=5, column=1)

        #======================================================
        #=Código para desenhar o gráfico no frame da janela
        #
        #=Primeira linha cria a figura onde o plot será feito
        self.fig = Figure(figsize=(7, 5))

        #=Não sei bem o que o add_subplot faz ainda, mas parece que é algum tipo
        #=de "preparação" pro plot ser feito em uma variável
        self.grafico = self.fig.add_subplot(111)
        #=função simples para plotar as duas variáveis. "bo" é o tipo de "linha"
        self.grafico.plot(px, py, "bo")

        self.grafico.set_xlabel('x', labelpad=5)
        self.grafico.set_ylabel('y', labelpad=5)

        #=Um "canvas" (tela de pintura) precisa ser feito no tkinter para desenhar o gráfico.
        #=aparentemente, esse método FigureCanvastkAgg cria essa "tela" e assoscia ela ao
        #=tkinter. Ela passa com parâmetro a figura que será desenhada e em qual janela,
        #=frame, etc ela será desenhada.
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.frm_graphic)
        #=aparentemente é o que posiciona a imagem no frame, assim como fazemos
        #=com os widgets na janela.

        self.canvas.get_tk_widget().pack()
        #=faz o desenho do plot (seria interessante testar o código sem isso e ver se
        # simplesmente não vai aparecer o plot)
        self.canvas.draw()

    #==================================================================
    def limparJanela(self):
        self.btn_return.grid_forget()
        self.btn_plot.grid_forget()
        self.btn_linear.grid_forget()
        self.btn_expo.grid_forget()
        self.btn_quadra.grid_forget()
        self.btn_cube.grid_forget()
        self.btn_racio.grid_forget()

        self.frm_buttons.pack_forget()
        self.frm_graphic.pack_forget()

    #==================================================================
    def voltar(self):
        self.limparJanela()
        self.jAnterior.redesenhar()

    #==================================================================
    def limpar_grafico(self):
        self.canvas.get_tk_widget().pack_forget()

    #==================================================================
    def curve_plot(self, px, err_x, py, err_y, Funcao, f_nome):
        funct = Funcao(px, py, err_x, err_y)
        popt, pcov, qui_quadrado = funct.gerar_qui_quadrado()

        x_teste = []
        d0 = px.min()

        while d0 < px.max():
            x_teste.append(d0)
            d0 += 1
        x_teste.append(px.max())
        x_teste = array(x_teste)

        self.limpar_grafico()

        def gerar_legenda():
            legenda = ""
            for coef, err_coef, letra in zip(popt, pcov, ['A', 'B', 'C', 'D']):
                legenda += letra + f" = {coef:.2f} +/- {err_coef:.2f}\n"
            legenda += r'$\chi^2$/ndof ='
            legenda += f"{qui_quadrado:.2f}"
            return legenda

        self.fig = Figure(figsize=(7, 5))
        self.grafico = self.fig.add_subplot(111)
        self.grafico.plot(x_teste,
                          funct.funcao(popt, x_teste),
                          "k",
                          label=gerar_legenda())

        self.grafico.errorbar(px, py, yerr=array(err_y), fmt='o')
        self.grafico.legend(fontsize='x-small')

        self.grafico.set_xlabel('x', labelpad=5)
        self.grafico.set_ylabel('y', labelpad=5)

        self.canvas = FigureCanvasTkAgg(self.fig, master=self.frm_graphic)
        self.canvas.get_tk_widget().pack()
        self.canvas.draw()

        self.resultados(popt, pcov, qui_quadrado, f_nome)

    #==========================================================================
    def salvar_imagem(self):
        filename = filedialog.asksaveasfilename()
        self.fig.savefig(filename)

    #==========================================================================
    def resultados(self, popt, pcov, qui_quadrado, f_nome):
        top_res = Toplevel(bd=10)
        top_res.resizable(False, False)
        top_res.title("Resultados: " + f_nome)
        top_res.configure(background="azure2")

        txt_a_value = Entry(top_res)
        txt_a_value.insert(0, popt[0])
        txt_a_value.config(state='readonly')
        Label(top_res, text="A: ", bg="azure2").grid(row=0, column=0)
        txt_a_value.grid(row=0, column=1)

        txt_a_error = Entry(top_res)
        txt_a_error.insert(0, pcov[0])
        txt_a_error.config(state='readonly')
        Label(top_res, text="+/-", bg="azure2").grid(row=0, column=2)
        txt_a_error.grid(row=0, column=3)

        txt_b_value = Entry(top_res)
        txt_b_value.insert(0, popt[1])
        txt_b_value.config(state='readonly')
        Label(top_res, text="B: ", bg="azure2").grid(row=1, column=0)
        txt_b_value.grid(row=1, column=1)

        txt_b_error = Entry(top_res)
        txt_b_error.insert(0, pcov[1])
        txt_b_error.config(state='readonly')
        Label(top_res, text="+/-", bg="azure2").grid(row=1, column=2)
        txt_b_error.grid(row=1, column=3)

        if (len(popt) > 2):
            txt_c_value = Entry(top_res)
            txt_c_value.insert(0, popt[2])
            txt_c_value.config(state='readonly')
            Label(top_res, text="C: ", bg="azure2").grid(row=2, column=0)
            txt_c_value.grid(row=2, column=1)

            txt_c_error = Entry(top_res)
            txt_c_error.insert(0, pcov[2])
            txt_c_error.config(state='readonly')
            Label(top_res, text="+/-", bg="azure2").grid(row=2, column=2)
            txt_c_error.grid(row=2, column=3)

            if (len(popt) > 3):
                txt_d_value = Entry(top_res)
                txt_d_value.insert(0, popt[3])
                txt_d_value.config(state='readonly')
                Label(top_res, text="D: ", bg="azure2").grid(row=3, column=0)
                txt_d_value.grid(row=3, column=1)

                txt_d_error = Entry(top_res)
                txt_d_error.insert(0, pcov[3])
                txt_d_error.config(state='readonly')
                Label(top_res, text="+/-", bg="azure2").grid(row=3, column=2)
                txt_d_error.grid(row=3, column=3)

        txt_q_entry = Entry(top_res)
        txt_q_entry.insert(0, round(qui_quadrado, 4))
        txt_q_entry.config(state='readonly')
        Label(top_res, text="x²/ndof: ", bg="azure2").grid(row=4, column=0)

        txt_q_entry.grid(row=4, column=1)
Beispiel #18
0
class QuantMonitor(object):

    # 背景色
    bgColor = rgb_to_hex(245, 245, 245)
    bgColorW = "white"

    def __init__(self, frame, control, language):
        self.parentFrame = frame
        self._controller = control
        self._logger = self._controller.get_logger()
        self.language = language

        # Monitor不同标签的背景色
        self.rColor = self.bgColorW
        self.lColor = self.bgColor
        self.sColor = self.bgColor
        self.eColor = self.bgColor

        self.createButtonFrame()

        # 执行列表、监控日志、信号记录、错误
        self.executeList = Frame(self.parentFrame)
        self.monitorLog = Frame(self.parentFrame)
        self.sigRecord = Frame(self.parentFrame)
        self.errRecord = Frame(self.parentFrame)

        self.executeList.pack(side=TOP, fill=BOTH, expand=YES)

        self.monText = None
        self.sigText = None
        self.errText = None

    def createButtonFrame(self):
        btnFrame = Frame(self.parentFrame, height=30, bg=self.bgColor)
        btnFrame.pack_propagate(0)
        btnFrame.pack(side=TOP, fill=X)
        # 利用frame做出button的黑色边框
        # f1 = Frame(btnFrame, highlightbackground="black", highlightthickness=1, bd=0)
        # f1.pack(side=LEFT)

        self.runBtn = Button(btnFrame,
                             text="策略运行",
                             relief=FLAT,
                             padx=14,
                             pady=1.5,
                             bg=self.rColor,
                             bd=0,
                             highlightthickness=1,
                             command=self.toMonFrame)
        self.logBtn = Button(btnFrame,
                             text="运行日志",
                             relief=FLAT,
                             padx=14,
                             pady=1.5,
                             bg=self.lColor,
                             bd=0,
                             highlightthickness=1,
                             command=self.toLogFrame)
        self.sigBtn = Button(btnFrame,
                             text="信号记录",
                             relief=FLAT,
                             padx=14,
                             pady=1.5,
                             bg=self.sColor,
                             bd=0,
                             highlightthickness=1,
                             command=self.toSigFrame)
        self.errBtn = Button(btnFrame,
                             text="错误信息",
                             relief=FLAT,
                             padx=14,
                             pady=1.5,
                             bg=self.eColor,
                             bd=0,
                             highlightthickness=1,
                             command=self.toErrFrame)
        self.runBtn.pack(side=LEFT, expand=NO)
        self.logBtn.pack(side=LEFT, expand=NO)
        self.sigBtn.pack(side=LEFT, expand=NO)
        self.errBtn.pack(side=LEFT, expand=NO)

        for btn in (self.runBtn, self.logBtn, self.sigBtn, self.errBtn):
            btn.bind("<Enter>", self.handlerAdaptor(self.onEnter, button=btn))
            btn.bind("<Leave>", self.handlerAdaptor(self.onLeave, button=btn))

    def createMonitor(self):
        # monitorRightBar = Scrollbar(self.monitorLog)
        # monitorRightBar.pack(side=RIGHT, fill=Y), yscrollcommand=monitorRightBar.set

        self.monText = MonitorText(self.monitorLog, height=20, bd=0)
        self.monText.createScrollbar()
        self.monText.pack(fill=BOTH, expand=YES)

    def createSignal(self):
        self.sigText = SignalText(self.sigRecord, height=20, bd=0)
        self.sigText.createScrollbar()
        self.sigText.pack(fill=BOTH, expand=YES)

    def createExecute(self):
        headList = [
            "编号", "策略名称", "基准合约", "频率", "运行状态", "实盘运行", "初始资金", "可用资金", "最大回撤",
            "累计收益", "胜率"
        ]
        widthList = [5, 50, 50, 5, 10, 5, 20, 10, 20, 20, 5]

        self.executeBar = ttk.Scrollbar(self.executeList, orient="vertical")
        self.executeBar.pack(side=RIGHT, fill=Y)

        self.executeListTree = ttk.Treeview(self.executeList,
                                            show="headings",
                                            height=28,
                                            columns=tuple(headList),
                                            yscrollcommand=self.executeBar.set,
                                            style="Filter.Treeview")
        self.executeBar.config(command=self.executeListTree.yview)
        self.executeListTree.pack(fill=BOTH, expand=YES)

        self.executeListTree.bind("<Button-3>", self.createMenu)

        for key, w in zip(headList, widthList):
            self.executeListTree.column(key, width=w, anchor=CENTER)
            self.executeListTree.heading(key, text=key)

    def createMenu(self, event):
        """创建运行策略右键菜单"""
        RunMenu(self._controller, self.executeListTree).popupmenu(event)

    def _formatMonitorInfo(self, dataDict):
        """
        格式化监控需要的信息
        :param dataDict: 策略的所有信息
        :return: 需要展示的信息
        """
        try:
            Id = dataDict['StrategyId']
            StName = dataDict['StrategyName']
            BenchCon = dataDict['Config']['Contract'][0]

            kLineType = FrequencyDict[dataDict['Config']['Sample']
                                      ['KLineType']]
            kLineSlice = dataDict['Config']['Sample']['KLineSlice']

            Frequency = str(kLineSlice) + kLineType
            RunType = "是" if dataDict['Config']['RunMode']['Actual'][
                'SendOrder2Actual'] else "否"
            Status = StrategyStatus[dataDict["StrategyState"]]
            InitFund = dataDict['Config']['Money']['InitFunds']

            if 'RunningData' in dataDict:
                # Available =  "{:.2f}".format(dataDict['RunningData']['Fund'][-1]['Available'])
                Available = "{:.2f}".format(
                    dataDict['RunningData']['Available'])
                # 年化单利收益率
                # AnnualizedReturns = "{:.2f}".format(dataDict['RunningData']['Detail']['AnnualizedSimple'])
                MaxRetrace = "{:.2f}".format(
                    (dataDict['RunningData']['MaxRetrace']))
                TotalProfit = "{:.2f}".format(
                    dataDict['RunningData']['NetProfit'])
                WinRate = "{:.2f}".format(dataDict['RunningData']['WinRate'])
            else:
                Available = InitFund
                # AnnualizedReturns = 0
                MaxRetrace = 0
                TotalProfit = 0
                WinRate = 0

        except KeyError:
            traceback.print_exc()
            return

        values = [
            Id, StName, BenchCon, Frequency, Status, RunType, InitFund,
            Available, MaxRetrace, TotalProfit, WinRate
        ]

        return values

    def updateSingleExecute(self, dataDict):
        values = self._formatMonitorInfo(dataDict)

        if not values:
            return

        strategyId = dataDict["StrategyId"]
        try:
            if self.executeListTree.exists(strategyId):
                self.updateStatus(strategyId, dataDict)
                return
        except Exception as e:
            self._logger.warn("updateSingleExecute exception")
        self.executeListTree.insert("",
                                    END,
                                    iid=strategyId,
                                    values=tuple(values),
                                    tag=0)

    def createErr(self):
        # 错误信息展示
        self.errText = ErrorText(self.errRecord, height=20, bd=0)
        self.errText.createScrollbar()
        self.errText.pack(fill=BOTH, expand=YES)

    def updateRun(self):
        pass

    def updateLogText(self):
        guiQueue = self._controller.get_logger().getGuiQ()

        try:
            data = guiQueue.get_nowait()
        except:
            return
        else:
            self.monText.setText(data)

    def updateSigText(self):
        sigQueue = self._controller.get_logger().getSigQ()
        try:
            sigData = sigQueue.get_nowait()
        except:
            return
        else:
            # self.toSigFrame()
            self.sigText.setText(sigData)

    def updateErrText(self):
        errQueue = self._controller.get_logger().getErrQ()
        try:
            errData = errQueue.get_nowait()
        except:
            return
        else:
            self.toErrFrame()
            self.errText.setText(errData)

    def toMonFrame(self):
        self.runBtn.config(bg="white")
        self.rColor = self.runBtn['bg']
        self.lColor = self.bgColor
        self.sColor = self.bgColor
        self.eColor = self.bgColor
        self.errBtn.config(bg=self.rColor)
        self.sigBtn.config(bg=self.sColor)
        self.logBtn.config(bg=self.lColor)
        self.monitorLog.pack_forget()
        self.sigRecord.pack_forget()
        self.errRecord.pack_forget()
        self.executeList.pack(side=TOP, fill=BOTH, expand=YES)

    def toLogFrame(self):
        self.logBtn.config(bg="white")
        self.lColor = self.logBtn['bg']
        self.rColor = self.bgColor
        self.sColor = self.bgColor
        self.eColor = self.bgColor
        self.runBtn.config(bg=self.rColor)
        self.sigBtn.config(bg=self.sColor)
        self.errBtn.config(bg=self.eColor)
        self.sigRecord.pack_forget()
        self.executeList.pack_forget()
        self.errRecord.pack_forget()
        self.monitorLog.pack(side=TOP, fill=BOTH, expand=YES)

    def toSigFrame(self):
        self.sigBtn.config(bg="white")
        self.sColor = self.sigBtn['bg']
        self.lColor = self.bgColor
        self.rColor = self.bgColor
        self.eColor = self.bgColor
        self.runBtn.config(bg=self.rColor)
        self.logBtn.config(bg=self.lColor)
        self.errBtn.config(bg=self.eColor)
        self.monitorLog.pack_forget()
        self.executeList.pack_forget()
        self.errRecord.pack_forget()
        self.sigRecord.pack(side=TOP, fill=BOTH, expand=YES)

    def toErrFrame(self):
        self.errBtn.config(bg="white")
        self.eColor = self.errBtn['bg']
        self.lColor = self.bgColor
        self.rColor = self.bgColor
        self.sColor = self.bgColor
        self.runBtn.config(bg=self.rColor)
        self.sigBtn.config(bg=self.sColor)
        self.logBtn.config(bg=self.lColor)
        self.parentFrame.update()
        self.monitorLog.pack_forget()
        self.executeList.pack_forget()
        self.sigRecord.pack_forget()
        self.errRecord.pack(side=TOP, fill=BOTH, expand=YES)

    def handlerAdaptor(self, fun, **kwargs):
        return lambda event, fun=fun, kwargs=kwargs: fun(event, **kwargs)

    def onEnter(self, event, button):
        if button == self.runBtn:
            button.config(bg='white')
            self.logBtn.config(bg=self.bgColor)
            self.sigBtn.config(bg=self.bgColor)
            self.errBtn.config(bg=self.bgColor)
        elif button == self.logBtn:
            button.config(bg='white')
            self.runBtn.config(bg=self.bgColor)
            self.sigBtn.config(bg=self.bgColor)
            self.errBtn.config(bg=self.bgColor)
        elif button == self.sigBtn:
            button.config(bg='white')
            self.runBtn.config(bg=self.bgColor)
            self.logBtn.config(bg=self.bgColor)
            self.errBtn.config(bg=self.bgColor)
        else:
            button.config(bg='white')
            self.runBtn.config(bg=self.bgColor)
            self.logBtn.config(bg=self.bgColor)
            self.sigBtn.config(bg=self.bgColor)

    def onLeave(self, event, button):
        button.config(bg=rgb_to_hex(227, 230, 233))
        if button == self.runBtn:
            button['bg'] = self.rColor
            self.logBtn['bg'] = self.lColor
            self.sigBtn['bg'] = self.sColor
            self.errBtn['bg'] = self.eColor
        elif button == self.logBtn:
            button['bg'] = self.lColor
            self.runBtn['bg'] = self.rColor
            self.sigBtn['bg'] = self.sColor
            self.errBtn['bg'] = self.eColor
        elif button == self.sigBtn:
            button['bg'] = self.sColor
            self.runBtn['bg'] = self.rColor
            self.logBtn['bg'] = self.lColor
            self.errBtn['bg'] = self.eColor
        else:
            button['bg'] = self.eColor
            self.runBtn['bg'] = self.rColor
            self.logBtn['bg'] = self.lColor
            self.sigBtn['bg'] = self.sColor

    def deleteStrategy(self, strategyId):
        """删除策略"""
        self.executeListTree.delete(strategyId)

    def updateStatus(self, strategyId, dataDict):
        """更新策略ID对应的策略状态"""
        values = self._formatMonitorInfo(dataDict)
        self.executeListTree.item(strategyId, values=values)
Beispiel #19
0
class SongGUI:
    def __init__(self, root):
        self.root = root
        self.root.title('Find my tune')
        self.root.geometry()
        self.root.minsize(800, 800)
        self.searchname = tkinter.StringVar()

        # creating help button
        help_button_img = PhotoImage(file='images/help_button.png')
        help_button_img = help_button_img.subsample(2)
        help_img_label = Label(image=help_button_img)
        help_img_label.image = help_button_img
        self.help_button = Button(self.root,
                                  image=help_button_img,
                                  command=self.helpFrame,
                                  border=0)
        self.help_button.pack(side=TOP, anchor=NE, padx=10, pady=10)

        # creating input frame
        self.input_frame = Frame(self.root)
        self.input_frame.pack()

        # creating heading
        heading = Label(self.input_frame,
                        text="Find My Tune",
                        font=("Helvetica", 30),
                        fg="black")
        heading.pack(pady=20, side=TOP)

        # creating search bar
        self.search_box_input = Entry(self.input_frame,
                                      font=("Helvetica", 20),
                                      textvariable=self.searchname)
        self.search_box_input.pack()

        # creating search button
        search_button_img = PhotoImage(file='images/search_button.png')
        search_button_img = search_button_img.subsample(2)
        search_img_label = Label(image=search_button_img)
        search_img_label.image = search_button_img
        self.search_button = Button(self.input_frame,
                                    image=search_button_img,
                                    border=0,
                                    command=self.searchSong)
        self.search_button.pack(pady=10, side=LEFT)

        # creating refresh button
        refresh_button_img = PhotoImage(file='images/refresh_button.png')
        refresh_button_img = refresh_button_img.subsample(2)
        refresh_img_label = Label(image=refresh_button_img)
        refresh_img_label.image = refresh_button_img
        self.refresh_button = Button(self.input_frame,
                                     image=refresh_button_img,
                                     fg='green',
                                     command=self.refreshFrame,
                                     border=0)
        self.refresh_button.pack(pady=10, side=RIGHT)

    def helpFrame(self):
        '''shows help Window in new frame'''

        self.help_button['state'] = DISABLED
        # Toplevel object which will be treated as a new window
        self.help_window = Toplevel(self.root)

        # sets the title of the Toplevel widget
        self.help_window.title("Help Window")

        # sets the geometry of toplevel
        self.help_window.geometry("550x800")

        # making help_window unresizable
        self.help_window.resizable(0, 0)

        # reading content from help_window.txt
        info_file = open("help_window.txt")
        lines = info_file.readlines()

        heading = Label(self.help_window,
                        font=("Helvetica 20 underline"),
                        text="HELP WINDOW")
        heading.pack(side=TOP, padx=10, pady=10)

        # code, to show content in help_window
        Label(self.help_window,
              wraplength=500,
              justify="left",
              font=("", 12),
              text=lines[0]).pack(side=TOP, pady=10, padx=5)
        Label(self.help_window,
              font=("Helvetica 16 underline bold"),
              text="INSTRUCTIONS").pack(anchor=W, padx=10, pady=10)

        for i in range(1, 9):
            Label(self.help_window,
                  wraplength=500,
                  justify="left",
                  font=("", 12),
                  text=str(i) + ". " + lines[i]).pack(anchor=W,
                                                      pady=2,
                                                      padx=10)
        Label(self.help_window, font=("Helvetica 16 underline"),
              text="NOTE").pack(anchor=W, padx=10, pady=10)
        for i in range(8, 11):
            Label(self.help_window,
                  wraplength=500,
                  justify="left",
                  font=("", 12),
                  text=str(i - 7) + ". " + lines[i]).pack(anchor=W,
                                                          pady=2,
                                                          padx=10)

        self.help_window.protocol("WM_DELETE_WINDOW", self.close_window)

    def close_window(self):
        '''function which closes the help_window'''
        self.help_window.destroy()
        self.help_button['state'] = NORMAL

    def searchSong(self):
        ''''function reads the search_input and searchs for the song'''
        self.songname = self.searchname.get()
        self.searchname.set('')

        # if the search box is not empty
        if (self.songname):

            self.songlist = findMySong(self.songname)
            self.search_button['state'] = DISABLED
            self.searchname.set('')
            self.result_frame = Frame(self.root)
            self.result_frame.pack()
            self.results = ttk.Treeview(self.result_frame)

            # if search is not empty
            if (self.songlist):

                # creates four cols, 1 phantom columns
                self.results['columns'] = ('S.NO', 'Name', 'Duration')

                style = ttk.Style()
                style.configure("Treeview", rowheight=18, columns=30000)

                self.results.column("#0", stretch=YES, width=0, minwidth=0)
                self.results.column("S.NO", stretch=YES, anchor=W, width=40)
                self.results.column("Name", anchor=W, stretch=YES, width=600)
                self.results.column("Duration",
                                    stretch=YES,
                                    anchor=W,
                                    width=80)

                # Create Headings
                self.results.heading("S.NO", text="S.NO", anchor=W)
                self.results.heading("Name", text="Name", anchor=CENTER)
                self.results.heading("Duration", text="Duration", anchor=W)

                self.results.pack(pady=10, expand=1, fill=BOTH)
                for i in range(len(self.songlist)):
                    self.results.insert(parent='',
                                        index='end',
                                        iid=i,
                                        text='',
                                        values=(str(i + 1),
                                                self.songlist[i]['title'],
                                                self.songlist[i]['duration']))

                self.down_button = Button(self.result_frame,
                                          text='DOWNLOAD',
                                          fg='white',
                                          bg='green',
                                          command=self.downloadSong)
                self.down_button.pack(padx=10, side=TOP)

            else:
                tkinter.messagebox.showerror(
                    'No Song Foumd',
                    "Could'nt find your song, please try again")
                self.search_button['state'] = NORMAL

        else:
            tkinter.messagebox.showerror('Search box Empty',
                                         "Please enter song name")
            self.search_button['state'] = NORMAL

    def downloadSong(self):
        '''Function which download the song'''

        self.down_button['state'] = DISABLED
        songNumber = self.results.focus()

        # if option is selected
        if (songNumber):
            songNumber = int(songNumber)
            downloadMySong(self.songlist[songNumber]['download-link'])
            filename = [f for f in os.listdir() if f.endswith('.mp3')]
            if (filename):
                # rename file and save in download folder
                os.rename(filename[0],
                          'downloads/' + filename[0][:-14] + ".mp3")
                tkinter.messagebox.showinfo('Song Downloaded Successfully',
                                            "Your song is downloaded.")
            else:
                tkinter.messagebox.showerror(
                    'Song Not Downloaded',
                    "Could'nt download your song, please try again later.")
                filename = [
                    f for f in os.listdir() if f.endswith('.crdownload')
                ]
                if (filename):
                    for file in filename:
                        os.remove(file)
        else:
            tkinter.messagebox.showerror(
                'Song Not Selected',
                "Please choose one item from list, then press download button")
        self.down_button['state'] = NORMAL

    def refreshFrame(self):
        '''clears the search window'''
        self.search_button['state'] = NORMAL
        self.searchname.set('')
        try:
            self.result_frame.pack_forget()
        except AttributeError:
            tkinter.messagebox.showinfo('Already Refreshed',
                                        "window already refreshed")
class LogicAnalyzer :
    def __init__(self,master) :
        self.master = master
        
        self.BLOCK_LEN = 2048 * 32

        self.RxTimerState = 1
        self.deviceIndex = -1
        self.dev = None
        self.rx_buffer = bytearray()
        
        self.timeout = 0;
        
        self.x  = np.arange(0, 30, 1)
        self.axis  = np.arange(25, 100, 1)
        self.z = [0] * 75
        
        self.index_max = 0
        self.results = []
        self.index = []
        for i in range(0,16):
            tempList = []
            self.results.append(tempList)
        
        self.startPosition = 0
        self.sampPitch = 1
        self.sampOnScreen = 30
        self.finishPosition = 0
        
        self.channelActiveMask = 0
        
        self.coreFrq = 300000000 #300MHz
        self.coreFrqPeriod = 1000000000/self.coreFrq
        self.sampFrq = 300000000.0
        self.AARate = 0;
        self.BBSamp = 0;
        self.HHTrigPos = 0;
        self.EEVolt = 0;
        
        self.decoder_instances = []
        self.dec_instance_state = []
        for i in range(0,8):
            inst_temp = i2c(self.master)
            self.decoder_instances.append(inst_temp)
            self.dec_instance_state.append("_")
        
        self.channel_count = 0
        self.channel_decode = [0]*16
        
        self.decode_count = 0
        self.decode_decode = [0]*8
        
        self.top1 = Frame(self.master, height = 500, width = 260, borderwidth=2,highlightbackground="gray" , highlightthickness=1)
        self.top1.pack(side="left", fill="both")
        self.top2 = Frame(self.master, height = 500, width = 500, borderwidth=2,highlightbackground="gray" , highlightthickness=1)
        self.top2.pack(side="right", fill="both")
        
        self.top_slider = Frame(self.top2, height = 5, width = 500)
        self.top_slider.pack(side="top", fill="x")
        
        self.plot_frame = Frame(self.top2) 
        self.plot_frame.pack(side="top", fill="both",expand = 1)
        
        self.right_slider = Frame(self.plot_frame)
        self.right_slider.pack(side="right", fill="y")
        
        self.AxisFrame = Frame(self.plot_frame, height = 5, width = 500)
        self.AxisFrame.pack(side="top")
        
        self.RSB1 = Button(self.right_slider, text = "+",height=1, width=4, command = self.zoomSliderP)
        self.RSB1.pack(side="top")
        
        self.w1 = Scale(self.right_slider, from_=1000, to=0,showvalue = 0,command = self.calcPosition)#command = self.calcPosition
        self.w1.set(0)
        self.w1.pack(side="top", fill="y",expand = 1)
        
        self.RSB2 = Button(self.right_slider, text = "-",height=1, width=4, command = self.zoomSliderM)
        self.RSB2.pack(side="top")
        
        self.w2 = Scale(self.top_slider, from_=0, to=100000, orient=HORIZONTAL, showvalue = 0,command = self.calcPosition) #command = self.calcPosition
        self.w2.set(0)

        self.SB1 = Button(self.top_slider, text = "<<<",height=1, width=3, command = self.shiftSliderMM)
        self.SB1.pack(side="left")
        self.SB2 = Button(self.top_slider, text = "<",height=1, width=3, command = self.shiftSliderM)
        self.SB2.pack(side="left")
        self.w2.pack(side="left", fill="both",expand=1)
        self.SB3 = Button(self.top_slider, text = ">>>",height=1, width=3, command = self.shiftSliderPP)
        self.SB3.pack(side="right")
        self.SB4 = Button(self.top_slider, text = ">",height=1, width=3, command = self.shiftSliderP)
        self.SB4.pack(side="right")
        
        self.AxisFig = plt.Figure(figsize=(25,2), dpi=100)
        self.AxisFig.set_figheight(0.25)
        self.AxisFig.subplots_adjust(left=-0.05, right=1.05, top=2, bottom=1)
        self.af = self.AxisFig.add_subplot(111)
        self.AxisFig.patch.set_facecolor('whitesmoke')
        self.af.axes.get_yaxis().set_visible(False)
        self.af.step(self.axis, self.z, where='post', label='post')
        self.af.set_frame_on(False)
        
        self.axVar = StringVar()
        self.axLab = Label(self.AxisFrame, textvariable=self.axVar,height = 1,width=2)
        self.axVar.set("sp")
        self.axLab.pack(side="left")
        
        self.AxCanvas = FigureCanvasTkAgg(self.AxisFig, self.AxisFrame)
        self.AxCanvas.get_tk_widget().pack(side = "left",pady=2)
        

        self.decode_frame = Frame(self.plot_frame) 
        self.decode_frame.pack(side="top", fill="both",expand = 0)
        self.channel_frame = Frame(self.plot_frame) 
        self.channel_frame.pack(side="top", fill="both",expand = 0)#<-----------------------------
        
        self.plot_frames = []
        for i in range(0,16):
            self.plotFrame = Frame(self.channel_frame)
            self.plot_frames.append(self.plotFrame)
        
        self.decode_frames = []
        for i in range(0,8):
            self.decodeFrame = Frame(self.decode_frame)
            self.decode_frames.append(self.decodeFrame)

        self.plot_figures = []
        self.plot_axes = []
        self.plot_canvases = []
        self.plot_labels = []
        self.plot_label_values = []
        for i in range(0,16):
            
            self.figure = plt.Figure(figsize=(25,2), dpi=150)
            self.plot_figures.append(self.figure)
            self.plot_figures[i].set_figheight(0.2)#<------------------------------------------------
            self.plot_figures[i].subplots_adjust(left=-0.05, right=1.05, top=1, bottom=0)
            self.plot_figures[i].patch.set_visible(False)
            
            self.ax = self.plot_figures[i].add_subplot(111)
            self.plot_axes.append(self.ax)
            self.canvas = FigureCanvasTkAgg(self.plot_figures[i], self.plot_frames[i])
            self.plot_canvases.append(self.canvas)
            
            self.insideVar = StringVar()
            self.plot_label_values.append(self.insideVar)
            self.plot_label_values[i].set(str(i))
            self.plotLabel = Label(self.plot_frames[i], textvariable=self.plot_label_values[i],height = 1,width=2)
            self.plot_labels.append(self.plotLabel)
            self.plot_labels[i].pack(side="left")
            
            self.plot_canvases[i].get_tk_widget().pack(side="right", fill="both", expand=1,pady=2)
        
        self.decode_figures = []
        self.decode_axes = []
        self.decode_canvases = []
        self.decode_labels = []
        self.decode_label_values = []
        for i in range(0,8):
            
            self.figure = plt.Figure(figsize=(25,2), dpi=100)
            self.decode_figures.append(self.figure)
            self.decode_figures[i].set_figheight(0.3)
            self.decode_figures[i].subplots_adjust(left=-0.05, right=1.05, top=1, bottom=0)
            self.decode_figures[i].patch.set_visible(False)
            
            self.ax = self.decode_figures[i].add_subplot(111)
            self.decode_axes.append(self.ax)
            self.canvas = FigureCanvasTkAgg(self.decode_figures[i], self.decode_frames[i])
            self.decode_canvases.append(self.canvas)
            
            self.insideVar = StringVar()
            self.decode_label_values.append(self.insideVar)
            self.decode_label_values[i].set(str(i+1))
            self.decodeLabel = Label(self.decode_frames[i], textvariable=self.decode_label_values[i],height = 1,width=2)
            self.decode_labels.append(self.decodeLabel)
            self.decode_labels[i].pack(side="left")
            
            self.decode_canvases[i].get_tk_widget().pack(side="right", fill="both", expand=1,pady=2)
        
        
        self.BStart = Button(self.top1, text = "Start",height=2, width=30, command = self.StartCallBack)
        self.BStart.place(x = 20,y = 10)
        
        self.L2var = StringVar()
        self.L2 = Label(self.top1, textvariable=self.L2var)
        self.L2var.set("Duration:")
        self.L2.place(x = 20,y = 70)
        
        self.STB1var = StringVar()
        self.STB1var.set("255")
        self.STB1 = Entry(self.top1, width=11,textvariable = self.STB1var)
        self.STB1.place(x = 85,y = 70)
        
        self.comboDuration = Combobox(self.top1, 
                                    values=[
                                            "samp", 
                                            "sec",
                                            "msec",
                                            "usec",
                                            "nsec"],
                                    state="readonly",
                                    width = 8)
        self.comboDuration.place(x = 170,y = 70)
        self.comboDuration.current(0)
        
        self.L3var = StringVar()
        self.L3 = Label(self.top1, textvariable = self.L3var)
        self.L3var.set("Samp. rate:")
        self.L3.place(x = 20,y = 90)
        
        self.STB2var = StringVar()
        self.STB2var.set("300")
        self.STB2 = Entry(self.top1, width=11,textvariable = self.STB2var)
        self.STB2.place(x = 85,y = 90)
        
        self.comboRate = Combobox(self.top1, 
                                    values=[
                                            "Hz", 
                                            "kHz",
                                            "MHz"],
                                    state="readonly",
                                    width = 8)
        self.comboRate.place(x = 170,y = 90)
        self.comboRate.current(2)
        
        self.L6var = StringVar()
        self.L6 = Label(self.top1, textvariable=self.L6var)
        self.L6var.set("Input threshold, V:")
        self.L6.place(x = 20,y = 110)
        
        self.STB3var = StringVar()
        self.STB3var.set("3")
        self.STB3 = Entry(self.top1, width=11,textvariable = self.STB3var)
        self.STB3.place(x = 170,y = 110)
        
        self.var1 = IntVar()
        self.CB1 = Checkbutton(self.top1, text='Trigger',variable=self.var1, onvalue=1, offvalue=0, command=self.TriggerCallBack) #
        self.CB1.place(x = 20,y = 145)
        
        self.L4var = StringVar()
        self.L4 = Label(self.top1, textvariable=self.L4var)
        self.L4var.set("Trigger type:")
        self.L4.place(x = 20,y = 165)
        
        self.comboTriggerT = Combobox(self.top1, 
                                    values=["Rising edge",
                                            "Falling edge",
                                            "High", 
                                            "Low"],
                                    state="disabled",
                                    width = 15)
        self.comboTriggerT.place(x = 125,y = 165)
        self.comboTriggerT.current(0)
        
        self.L5var = StringVar()
        self.L5 = Label(self.top1, textvariable=self.L5var)
        self.L5var.set("Trigger channel:")
        self.L5.place(x = 20,y = 185)
        
        self.comboTriggerCh = Combobox(self.top1, 
                                    values=["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"],
                                    state="disabled",
                                    width = 15)
        self.comboTriggerCh.place(x = 125,y = 185)
        self.comboTriggerCh.current(0)

        self.channel_active_int = []
        for i in range(0,16):
            self.channel_active_int.append(0)
            
        self.decode_active_int = []
        for i in range(0,8):
            self.decode_active_int.append(0)
        
        self.L61var = StringVar()
        self.L61 = Label(self.top1, textvariable=self.L61var)
        self.L61var.set("Samp. before trig:")
        self.L61.place(x = 20,y = 205)
        
        self.STB31var = StringVar()
        self.STB31var.set("3")
        self.STB31 = Entry(self.top1, width=18,state="disabled",textvariable = self.STB31var)
        self.STB31.place(x = 125,y = 205)
        
        self.L7var = StringVar()
        self.L7 = Label(self.top1, textvariable=self.L7var)
        self.L7var.set("Channels:")
        self.L7.place(x = 20,y = 240)
        
        self.channel_active = []
        self.channel_ch_box = []
        for i in range(0,16):
            self.chAct = IntVar()
            self.channel_active.append(self.chAct)
            self.chActChB = Checkbutton(self.top1, text=str(i),variable=self.channel_active[i], onvalue=1, offvalue=0, command=self.RefreshCh)
            self.channel_ch_box.append(self.chActChB)
            self.channel_ch_box[i].place(x = 20+(i%4)*60,y = 260+(i//4)*20)
        
        self.L8var = StringVar()
        self.L8 = Label(self.top1, textvariable=self.L8var)
        self.L8var.set("Decoders:")
        self.L8.place(x = 20,y = 355)
        
        self.decode_cb = []
        self.decode_cb_var = []
        self.decode_combo = []
        self.decode_buttons = []
        for i in range(0,8):
            dec_cb = IntVar()
            self.decode_cb_var.append(dec_cb)
            decActChB = Checkbutton(self.top1, text=str(i+1),variable=self.decode_cb_var[i], onvalue=1, offvalue=0, command=self.ResetDecodes) #
            self.decode_cb.append(decActChB)
            self.decode_cb[i].place(x = 20,y = 375+(i*28))
            decodeCombo = Combobox(self.top1, values=["i2c"],state="disabled",width = 20)
            self.decode_combo.append(decodeCombo)
            self.decode_combo[i].place(x = 60,y = 375+(i*28))
            self.decode_combo[i].current(0)
            self.decode_combo[i].bind("<<ComboboxSelected>>", self.ComboUpdate)
            self.decodeButton = Button(self.top1, text = "set",height=1, width=3, state="disabled")
            self.decode_buttons.append(self.decodeButton)
            self.decode_buttons[i].place(x = 210,y = 372+(i*28))            
            self.decode_buttons[i].configure(command=lambda:self.decoder_instances[i].set_decode(self.channel_active_int))
        
        self.BDecode = Button(self.top1, text = "Decode",height=2, width=30, command = self.ResetDecodes)
        self.BDecode.place(x = 20,y = 600)
        
        self.BFill = Button(self.top1, text = "Fill",height=2, width=13, command = self.FillCallBack)
        self.BFill.place(x = 20,y = 650)
        
        self.BSort = Button(self.top1, text = "Sort",height=2, width=13, command = self.SortCallBack)
        self.BSort.place(x = 140,y = 650)
        
        for root, dirs, files in os.walk("."):
            for filename in files:
                if(filename[0:3]== "la_" and filename[-3:]== ".py"):
                    print(filename)
                    module_name = filename[3:len(filename)-3]
                    for i in range(0,8):
                        if module_name not in self.decode_combo[i]['values']:
                            self.decode_combo[i]['values'] += (module_name,)    
        
        
        self.drawDecodes([1,0,0,0,0,0,0,0],0)
        self.drawPlots([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],1,1)
        self.drawDecodes([0,0,0,0,0,0,0,0],0)
        
        
        self.master.protocol("WM_DELETE_WINDOW",self.exit_handler)
    
    def calcPosition(self,*args):
        sampOnScreenMin = 30
        sampOnScreenMax = 10000
        self.index_max = 0
        for i in range(0,16):
            if(self.index_max < len(self.results[i])):
               self.index_max = len(self.results[i])
        
        if (self.index_max > sampOnScreenMin and self.index_max < sampOnScreenMax):
            self.sampOnScreen = sampOnScreenMin + int(((self.index_max-sampOnScreenMin) / 1000) * (1000-self.w1.get()))
        elif (self.index_max > sampOnScreenMax):
            self.sampOnScreen = sampOnScreenMin + int(((sampOnScreenMax-sampOnScreenMin) / 1000) * (1000-self.w1.get()))
        else:
            self.sampOnScreen = self.index_max
            
        self.sampPitch = (self.sampOnScreen // 1000) +1#
        
        if (self.index_max > sampOnScreenMin):
            self.startPosition = int((self.index_max - self.sampOnScreen)/100000 * self.w2.get())
        else:
            self.startPosition = 0
        
        self.finishPosition = self.startPosition + self.sampOnScreen
        self.drawPlots(self.channel_active_int,0,0)
    
    def RefreshCh(self):
        for i in range(0,16):
            if(self.index_max < len(self.results[i])):
               self.index_max = len(self.results[i])
               
        for i in range(0,16):
            if(len(self.results[i])<self.index_max and self.channel_active[i].get() == 1):
                self.results[i] = [0]*self.index_max

        self.calcPosition()
        self.ResetPlots()
    
    def ResetPlots(self):
        self.channelActiveMask = 0
        self.channel_count = 0
        for i in range(0,16):
            self.channel_active_int[i] = self.channel_active[i].get()
            if(self.channel_active_int[i]==1):
                self.channel_count += 1
                self.channel_decode[i] = self.channel_count-1
        for i in range(0,16):
            self.channelActiveMask = (self.channelActiveMask << 1) | self.channel_active_int[15-i]
        print(self.channel_active_int)
        self.drawPlots(self.channel_active_int,1,0)

    def ResetDecodes(self):
        self.decodeActiveMask = 0
        self.decode_count = 0
        for i in range(0,8):
            self.decode_active_int[i] = self.decode_cb_var[i].get()
            if(self.decode_active_int[i]==1):
                self.decode_count += 1
                self.decode_decode[i] = self.decode_count-1
                self.decode_combo[i]["state"] = "readonly"
                self.decode_buttons[i]["state"] = "normal"
            else:
                self.decode_combo[i]["state"] = "disabled"
                self.decode_buttons[i]["state"] = "disabled"
        self.UpdateDecodeInstances()
        for i in range(0,8):
            if(self.decode_active_int[i] == 1):
                self.decoder_instances[i].decode(self.results,self.index_max,self.sampFrq)
        self.drawDecodes(self.decode_active_int,0)
                  
    def drawPlots(self,plot_state,refreshFlag,sortFlag):
        
        self.index = np.arange(0, self.index_max, 1)
        self.z = [0] * self.index_max
        
        self.af.clear()
        self.af.axes.get_yaxis().set_visible(False)
        self.af.step(self.index[self.startPosition:self.finishPosition:1], 
                     self.z[self.startPosition:self.finishPosition:1],
                                 where='post', label='post')
        self.af.set_frame_on(False)

        self.AxCanvas.draw()
        self.AxisFrame.pack(side="top")
        
        if(sortFlag == 1):
            for i in range(0,16): 
                self.plot_frames[i].pack_forget()
        
        for i in range(0,16):     
            if(refreshFlag == 1):
                self.plot_axes[i].clear()
                self.plot_figures[i].patch.set_visible(False)
            
            if(plot_state[i]==1):
                self.plot_axes[i].clear()
                self.plot_figures[i].patch.set_visible(False)
                self.plot_axes[i].step(self.index[self.startPosition:self.finishPosition:1], #self.sampPitch
                                                  self.results[i][self.startPosition:self.finishPosition:1], #self.sampPitch
                                                  where='post', label='post')
                self.plot_axes[i].set_ylim(-0.01,1.01)
                self.plot_axes[i].axis('off')

                self.plot_canvases[i].draw()
                self.plot_canvases[i].get_tk_widget().update_idletasks()
                if(refreshFlag == 1):
                    self.plot_frames[i].pack(side="top", fill="both", expand=1)
            elif(refreshFlag == 1):
                self.plot_frames[i].pack_forget()
        self.ResetDecodes()
    
    def drawDecodes(self,decode_state,sortFlag):
        if(sortFlag == 1):
            for i in range(0,8): 
                self.decode_frames[i].pack_forget()  
                
        for i in range(0,8):
            self.decode_axes[i].clear()
            self.decode_figures[i].patch.set_visible(False)
            
            if(decode_state[i]==1):
                self.decode_ind_temp = []
                self.decode_state1_temp = []
                self.decode_state2_temp = []
                
                if(len(self.decoder_instances[i].decode_index)>0):
                    for f in range(0,len(self.decoder_instances[i].decode_index)):
                        if(self.decoder_instances[i].decode_index[f] > self.startPosition+0.5 and self.decoder_instances[i].decode_index[f] < self.finishPosition-0.5):
                           self.decode_ind_temp.append(self.decoder_instances[i].decode_index[f])
                           self.decode_state1_temp.append(self.decoder_instances[i].decode_state1[f])
                           self.decode_state2_temp.append(self.decoder_instances[i].decode_state2[f])
                    
                if(len(self.decode_ind_temp)==0):
                    self.decode_ind_temp.append(self.startPosition)
                    self.decode_state1_temp.append(0)
                    self.decode_state2_temp.append(1)

                self.decode_ind_temp.insert(0,self.startPosition)
                self.decode_state1_temp.insert(0,self.decode_state1_temp[0])
                self.decode_state2_temp.insert(0,self.decode_state2_temp[0])
    
                self.decode_ind_temp.append(self.finishPosition)
                self.decode_state1_temp.append(self.decode_state1_temp[-1])
                self.decode_state2_temp.append(self.decode_state2_temp[-1])                
                
                self.decode_axes[i].plot(self.decode_ind_temp, self.decode_state1_temp, color='r')
                self.decode_axes[i].plot(self.decode_ind_temp, self.decode_state2_temp, color='r')
                self.decode_axes[i].set_ylim(-0.01,1.01)
                self.decode_axes[i].axis('off')
                for d in range(0,len(self.decoder_instances[i].decode_position)):
                    self.decode_axes[i].text(self.decoder_instances[i].decode_position[d],0.1,self.decoder_instances[i].decode_text[d], fontsize=10)
                self.decode_canvases[i].draw()
                self.decode_frames[i].pack(side="top", fill="both", expand=1)
            else:
                self.decode_frames[i].pack_forget()

    def TriggerCallBack(self):
        if(self.var1.get() == 1):
            self.comboTriggerCh["state"] = "readonly"
            self.comboTriggerT["state"] = "readonly"
            self.STB31["state"] = "normal"
        else:
            self.comboTriggerCh["state"] = "disabled"
            self.comboTriggerT["state"] = "disabled"
            #self.STB31var.set(3)
            self.STB31["state"] = "disabled"

    def ft_init(self):
        #Get the device list and save the index of logic analyzer into deviceIndex
        self.deviceList = ftd2xx.listDevices(0) # returns the list of ftdi devices S/Ns 
        self.deviceIndex = -1;
        self.status = -1;
        if self.deviceList : 
             print(len(self.deviceList), 'ftdi devices found')
             for x in range(0,len(self.deviceList)):
                 if ( "LogicAnalyzer" in str(ftd2xx.getDeviceInfoDetail(x)['description'])) :
                     print("Device %d details: "%x)
                     print('-------------------------------------------------')
                     print("Serial : " + str(ftd2xx.getDeviceInfoDetail(x)['serial']))
                     print("Type : "  + str(ftd2xx.getDeviceInfoDetail(x)['type']))
                     print("ID : " + str(ftd2xx.getDeviceInfoDetail(x)['id']))
                     print("Description : " + str(ftd2xx.getDeviceInfoDetail(x)['description']))
                     print('-------------------------------------------------')
                     
                     if self.deviceIndex < 0:
                         self.deviceIndex = x
                     break
        else:
             print("no ftdi devices connected")
     
    def connect(self):
        if self.deviceIndex >= 0 :
             print('Connecting to device with index %d'% self.deviceIndex)
             self.dev = ftd2xx.open(self.deviceIndex) #FT4HNA7Z
             self.status = 1
             time.sleep(0.1)
             self.dev.setBitMode(0x00, 0x40)
             
             print('Device connected')
       
        elif ftd2xx.listDevices(0):
             print("no FTDI devices to be connected")
             self.messagebox.showinfo(title=None, message="Logic Analyzer was not found")


    def disconnect(self):
        self.dev.close()
        print("Device disconnected")

    def timerHandler(self): 
        self.read()
        print("check if all data collected %d"%len(self.rx_buffer))
        print("needed %d"%(self.BBSamp-self.BBSamp*0.01))
        if (len(self.rx_buffer) < (self.BBSamp-self.BBSamp*0.01) and (self.timeout < 50 or self.var1.get() == 1)) :
            self.timeout += 1
            self.master.after(1, self.timerHandler)
        else:
            print("data collected") 
            self.disconnect()
            self.w1.set(0)
            self.w2.set(0)
            self.calcPosition()
            
    def send(self):
        
        print("Send data")
        self.tx_data =  "#>HH"
        self.tx_data =  "#$FF" + self.HHTrigPosStr 
        self.tx_data += "#$EE" + self.EEVoltStr
        self.tx_data += "#$AA" + self.AARateStr
        self.tx_data += "#$BB" + self.BBSampStr
        self.tx_data += "#$CC" + self.CCTrigStr
        self.tx_data += "#$DD" + self.DDMaskStr
        self.tx_data += "#>GG"
        self.tx_data = self.tx_data.upper()
        self.tx_data += self.tx_data
        for a in range(0,16):
            self.results[a] = []
        
        print(self.tx_data)        
        b=bytearray()
        b.extend(map(ord,self.tx_data))
        if len(self.tx_data)>0 :
            print("\r\nSending %d bytes:"%len(self.tx_data))
            print('-------------------------------------------------')
            print(self.tx_data)
            print('-------------------------------------------------')
            self.written = self.dev.write(self.tx_data)
        else :
            print("Please enter data into a top text field")
        #self.timer1.start()
        self.timeout = 0
        self.rx_buffer = bytearray()
        self.timerHandler()

    def read(self):
        rx_data = bytearray()

        while self.dev.getQueueStatus()>0 :
             rx_data = self.dev.read(self.dev.getQueueStatus())

        if len(rx_data)>0 :
            self.rx_buffer += rx_data
            print("\r\nReceived %d bytes:"%len(rx_data))
            print('-------------------------------------------------')
            self.timeout = 0 # reset timeout if some data received
            if(self.channel_count <= 8):
                for i in range(0,len(rx_data),1):
                    x = bytearray()
                    x.append(rx_data[i]);
                
                    if(self.channel_count <= 2):
                        for ind in range(0,16):
                            if(self.channel_active_int[ind] == 1):
                                self.results[ind].append((int(int.from_bytes(x, byteorder='big', signed=False)>>self.channel_decode[ind]+6)&1))
                                self.results[ind].append((int(int.from_bytes(x, byteorder='big', signed=False)>>self.channel_decode[ind]+4)&1))
                                self.results[ind].append((int(int.from_bytes(x, byteorder='big', signed=False)>>self.channel_decode[ind]+2)&1))
                                self.results[ind].append((int(int.from_bytes(x, byteorder='big', signed=False)>>self.channel_decode[ind])&1))
                    elif(self.channel_count <= 4):
                        for ind in range(0,16):
                            if(self.channel_active_int[ind] == 1):
                                self.results[ind].append((int(int.from_bytes(x, byteorder='big', signed=False)>>self.channel_decode[ind]+4)&1))
                                self.results[ind].append((int(int.from_bytes(x, byteorder='big', signed=False)>>self.channel_decode[ind])&1))
                    elif(self.channel_count <= 8):
                        for ind in range(0,16):
                            if(self.channel_active_int[ind] == 1):
                                self.results[ind].append((int(int.from_bytes(x, byteorder='big', signed=False)>>self.channel_decode[ind])&1))
            elif(self.channel_count > 8 and self.channel_count <= 16):
                for i in range(0,len(rx_data)//2,2):
                    for ind in range(0,16):
                        x = bytearray()
                        x.append(rx_data[i])
                        x.append(rx_data[i+1])
                        self.results[ind].append((int(int.from_bytes(x, byteorder='big', signed=False)>>ind)&1))

    def updSet(self):
        temp1 = 1
        
        ##AA DATA RATE
        if (self.comboRate.get() == "Hz"):
            temp1 = 1
        elif(self.comboRate.get() == "kHz"):
            temp1 = 1000    
        elif(self.comboRate.get() == "MHz"):
            temp1 = 1000000
        
        self.AARate = self.coreFrq // (float(self.STB2var.get())*temp1)-1
        if (self.AARate > 16777215):
            self.AARate = 16777215
        elif(self.AARate < 0):
            self.AARate = 0
        self.sampFrq = self.coreFrq / ((self.AARate+1)*temp1)
        self.STB2var.set(str(self.sampFrq))
        self.sampFrq = self.coreFrq / (self.AARate+1)
        
        AARateByte = hex(int(self.AARate))
        self.AARateStr = str(AARateByte)
        self.AARateStr = self.AARateStr[2:]
        for ind in range(0,6-len(self.AARateStr)):
            self.AARateStr = '0' + self.AARateStr
        print("AA(Frq) = %d"%self.AARate)
        print(self.AARateStr)
        
        ##BB DURATION
        if (self.comboDuration.get() == "samp"):
            self.BBSamp = float(self.STB1var.get()) // 1
            self.STB1var.set(str(int(self.BBSamp)))
        else:
            if (self.comboDuration.get() == "sec"):
                temp1 = 1000000000
            elif(self.comboDuration.get() == "msec"):
                temp1 = 1000000    
            elif(self.comboDuration.get() == "usec"):
                temp1 = 1000
            elif(self.comboDuration.get() == "nsec"):
                temp1 = 1
            self.BBSamp = (temp1 * float(self.STB1var.get())) // self.coreFrqPeriod
            self.BBSamp += 1
            
        if(self.channel_count>0 and self.channel_count<=2):
            self.BBSamp = self.BBSamp / 4
            print("2")
        elif(self.channel_count>2 and self.channel_count<=4):
            self.BBSamp = self.BBSamp / 2
            print("4")
        elif(self.channel_count>8):
            self.BBSamp = self.BBSamp * 2
            print("16")
        
        if (self.BBSamp > 16777215):
            self.BBSamp = 16777215
        elif(self.BBSamp < 0):
            self.BBSamp = 0

        BBSampByte = hex(int(self.BBSamp))
        self.BBSampStr = str(BBSampByte)
        self.BBSampStr = self.BBSampStr[2:]
        for ind in range(0,6-len(self.BBSampStr)): #fill most sign bits with 0
            self.BBSampStr = '0' + self.BBSampStr
        print("BB(Samp) = %d"%self.BBSamp)
        print(self.BBSampStr)
        
        #CC TRIGGER CH
        if (self.var1.get() == 1):
            if(self.comboTriggerT.get()=="Rising edge"):
                CCTrigTStr = '0'
            elif(self.comboTriggerT.get()=="Falling edge"):
                CCTrigTStr = '1'
            elif(self.comboTriggerT.get()=="High"):
                CCTrigTStr = '2'
            elif(self.comboTriggerT.get()=="Low"):
                CCTrigTStr = '3'
        else: 
            CCTrigTStr = 'F'
            
        CCTrigChByte = hex(int(self.comboTriggerCh.get()))
        CCTrigChStr = str(CCTrigChByte)    
        self.CCTrigStr = "0000" + CCTrigTStr + CCTrigChStr[2:]
        print("CC(TrigCh) = %d"%int(self.comboTriggerCh.get()))
        print(self.CCTrigStr)
        
        #HH TRIGGER POSITION
        self.HHTrigPos = int(self.STB31var.get())
        
        if(self.channel_count>0 and self.channel_count<=2):
            self.HHTrigPos = self.HHTrigPos // 8
            print("2")
        elif(self.channel_count>2 and self.channel_count<=4):
            self.HHTrigPos = self.HHTrigPos // 4
            print("4")
        elif(self.channel_count>4 and self.channel_count<=8):
            self.HHTrigPos = self.HHTrigPos // 2
            print("8")
        
        if (self.HHTrigPos > 64000):
            self.HHTrigPos = 64000
        elif(self.HHTrigPos < 0):
            self.HHTrigPos = 0
        
        HHTrigPosByte = hex(self.HHTrigPos)
        self.HHTrigPosStr = str(HHTrigPosByte)
        self.HHTrigPosStr = self.HHTrigPosStr[2:]
        for ind in range(0,6-len(self.HHTrigPosStr)):
            self.HHTrigPosStr = '0' + self.HHTrigPosStr
        print("лала(TrigPos) = %d"%self.HHTrigPos)
        print(self.HHTrigPosStr)
        
        
        #DD CH BITMAP
        DDMaskByte = hex(self.channelActiveMask)
        self.DDMaskStr = str(DDMaskByte)
        self.DDMaskStr = self.DDMaskStr[2:]
        for i in range(0,6-len(self.DDMaskStr)):
            self.DDMaskStr = '0' + self.DDMaskStr
        print("DD(Mask) = %d"%self.channelActiveMask)
        print(self.DDMaskStr)
        
        #EE VOLTAGE
        EEVoltFl = float(self.STB3var.get())
        if (EEVoltFl > 5):
            self.STB3var.set("5")
        if (EEVoltFl > 3.6):    
            EEVoltFl = 3.6
        elif (EEVoltFl < 0.6):
            self.STB3var.set("0.6")
            EEVoltFl = 0.6
        self.EEVolt = (EEVoltFl-0.6) * 65
        self.EEVolt = int(255 - self.EEVolt)
        
        EEVoltByte = hex(self.EEVolt)
        self.EEVoltStr = str(EEVoltByte)    
        self.EEVoltStr = "0000" + self.EEVoltStr[2:]
        
        print("EE(Volt) = %d"%self.EEVolt)
        print(self.EEVoltStr)
 
    def StartCallBack(self):
        self.updSet()
        self.ft_init()
        self.connect()
        self.send()
    
    def FillCallBack(self):
        self.decode_frame.pack_forget()
        self.channel_frame.pack_forget()
        if(self.BFill['text'] == "Fill"):
            self.BFill['text'] = "standart view"
            self.decode_frame.pack(side="top", fill="both",expand = 1)
            self.channel_frame.pack(side="top", fill="both",expand = 1)
        else:
            self.BFill['text'] = "Fill"
            self.decode_frame.pack(side="top", fill="both",expand = 0)
            self.channel_frame.pack(side="top", fill="both",expand = 0)
        
    def SortCallBack(self):
        self.drawDecodes(self.decode_active_int,1)
        self.drawPlots(self.channel_active_int,1,1)
                
    def ComboUpdate(self,event):
        self.UpdateDecodeInstances()
        
    def UpdateDecodeInstances(self):
        for i in range(0,8):
            if(self.dec_instance_state[i] != self.decode_combo[i].get() and self.decode_cb_var[i].get() == 1):
                self.dec_instance_state[i] = self.decode_combo[i].get()
                if(self.decode_combo[i].get() == "i2c"):
                    self.decoder_instances[i] = i2c(self.master)
                else:
                    filename = "la_" + self.decode_combo[i].get()
                    module = importlib.import_module(filename)
                    class_ = getattr(module, filename[3:])
                    self.decoder_instances[i] = class_(self.master)
                    
                self.decode_buttons[i].configure(command=lambda x=i :self.setDecode(x))
    
    def setDecode(self,ch):
        self.decoder_instances[ch].set_decode(self.channel_active_int)
        
    def zoomSliderP(self):
        temp = self.w1.get()
        temp += 1
        self.w1.set(temp)
    
    def zoomSliderM(self):
        temp = self.w1.get()
        temp -= 1
        self.w1.set(temp)
        
    def shiftSliderMM(self):
        temp1 = self.index_max/100000
        temp2 = int(self.sampOnScreen/temp1)
        temp = self.w2.get()
        temp -= temp2
        self.w2.set(temp)
    def shiftSliderM(self):
        temp1 = self.index_max/100000
        temp2 = int(self.sampOnScreen/temp1/10)
        temp = self.w2.get()
        temp -= temp2
        self.w2.set(temp)
    def shiftSliderP(self):
        temp1 = self.index_max/100000
        temp2 = int(self.sampOnScreen/temp1/10)
        temp = self.w2.get()
        temp += temp2
        self.w2.set(temp)
    def shiftSliderPP(self):
        temp1 = self.index_max/100000
        temp2 = int(self.sampOnScreen/temp1)
        temp = self.w2.get()
        temp += temp2
        self.w2.set(temp)
   
    def disconnectCallBack(self):
        self.disconnect()

    def sendCallBack(self):
        self.send()
    
    def exit_handler(self):
        #disconnect() #add checking if connected
        self.drawPlots([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],1,0)
        self.drawDecodes([0,0,0,0,0,0,0,0],0)
        print('Bye! :)')
        self.master.destroy()
Beispiel #21
0
class UserInterface():
    '''用户界面,包括图形化窗口与交互逻辑'''
    def __init__(self, main):
        self.main = main
        self.window = Tk()
        self.window.withdraw()  #隐藏窗口(等到窗口宽高位置设定好后再显示)
        self.window.title('Period Calculator V%s' % self.main.version)  #窗口标题
        with open('temp.ico', 'wb') as temp_ico:  #生成临时ico图标文件
            temp_ico.write(base64.b64decode(icon.encoded_img))
        self.window.iconbitmap('temp.ico')  #设置窗口左上角图标
        os.remove('temp.ico')  #删除临时ico图标文件

        self.scale_factor = 1  #缩放因子
        self.dpi_adapt()  #高DPI适配
        self.window_width = int(self.main.window_width * self.scale_factor)
        self.window_height = int(self.main.window_height * self.scale_factor)
        window_x = int((self.window.winfo_screenwidth() * self.scale_factor -
                        self.window_width) / 2)
        window_y = int((self.window.winfo_screenheight() * self.scale_factor -
                        self.window_height) / 2)
        self.window.geometry('{}x{}+{}+{}'.format(
            self.window_width,  #窗口宽
            self.window_height,  #窗口高
            window_x,  #窗口位置x
            window_y  #窗口位置y
        ))
        self.window.resizable(False, False)  #锁定窗口大小
        self.window.deiconify()  #显示窗口

        self.init_frame_left()  #初始化左边栏
        self.init_frame_stats()  #默认初始页=数据统计页
        self.current_frame = self.frame_stats  #记录当前页面引用
        #弹窗通知记录文件加载异常(如有)
        if self.main.load_error:
            messagebox.showwarning(message=self.main.error_msg)

    def dpi_adapt(self):
        '''解决高分屏下程序界面模糊问题(高DPI适配)'''
        if self.main.dpi_adapt:
            try:
                #设置由应用程序自己控制缩放
                ctypes.windll.shcore.SetProcessDpiAwareness(1)
                #获得显示设置的缩放因子
                self.scale_factor = ctypes.windll.shcore.GetScaleFactorForDevice(
                    0) / 100
                #设置缩放
                self.window.tk.call('tk', 'scaling', self.scale_factor * 1.6)
            except Exception:
                pass

    def init_frame_left(self):
        '''左边栏框架'''
        self.frame_left = Frame(
            self.window,
            bd=self.window_width / 120,
            relief='groove',
            width=self.window_width * 0.3,
            height=self.window_height,
            bg='#FFC0CB'  #pink
        )
        self.frame_left.pack(side='left')
        self.frame_left.pack_propagate(0)
        self.init_btn_add()
        self.init_btn_calendar()
        self.init_btn_stats()
        self.init_btn_list()
        self.init_btn_settings()
        self.init_btn_about()
        self.init_indicator()

    def init_btn_add(self):
        '''左边栏新增开始/结束按钮'''
        self.btn_add = Button(
            self.frame_left,
            text='新增开始/结束',
            bd=self.window_width / 150,
            relief='groove',
            width=14,
            height=3,
            bg='#DA70D6',  #orchid
            fg='#FFFFFF',  #white
            activebackground='#DA70D6',
            activeforeground='#FFFFFF',
            command=self.click_add)
        self.btn_add.place(relx=0.5, rely=0.17, anchor='center')

    def init_btn_calendar(self):
        '''左边栏日历按钮'''
        self.btn_calendar = Button(
            self.frame_left,
            text='日历',
            bd=self.window_width / 150,
            relief='groove',
            width=10,
            height=1,
            bg='#FFF0F5',  #lavenderblush
            fg='#FF1493',  #deeppink
            activebackground='#FFF0F5',
            activeforeground='#FF1493',
            command=self.click_calendar)
        self.btn_calendar.place(relx=0.5, rely=0.35, anchor='center')

    def init_btn_stats(self):
        '''左边栏统计数据按钮'''
        self.btn_stats = Button(
            self.frame_left,
            text='统计数据',
            bd=self.window_width / 150,
            relief='groove',
            width=10,
            height=1,
            bg='#FFF0F5',  #lavenderblush
            fg='#FF1493',  #deeppink
            activebackground='#FFF0F5',
            activeforeground='#FF1493',
            command=self.click_stats)
        self.btn_stats.place(relx=0.5, rely=0.48, anchor='center')

    def init_btn_list(self):
        '''左边栏查看记录按钮'''
        self.btn_list = Button(
            self.frame_left,
            text='查看记录',
            bd=self.window_width / 150,
            relief='groove',
            width=10,
            height=1,
            bg='#FFF0F5',  #lavenderblush
            fg='#FF1493',  #deeppink
            activebackground='#FFF0F5',
            activeforeground='#FF1493',
            command=self.click_list)
        self.btn_list.place(relx=0.5, rely=0.61, anchor='center')

    def init_btn_settings(self):
        '''左边栏设置按钮'''
        self.btn_settings = Button(
            self.frame_left,
            text='设置',
            bd=self.window_width / 150,
            relief='groove',
            width=10,
            height=1,
            bg='#FFF0F5',  #lavenderblush
            fg='#FF1493',  #deeppink
            activebackground='#FFF0F5',
            activeforeground='#FF1493',
            command=self.click_settings)
        self.btn_settings.place(relx=0.5, rely=0.74, anchor='center')

    def init_btn_about(self):
        '''左边栏关于按钮'''
        self.btn_about = Button(
            self.frame_left,
            text='关于',
            bd=self.window_width / 150,
            relief='groove',
            width=10,
            height=1,
            bg='#FFF0F5',  #lavenderblush
            fg='#FF1493',  #deeppink
            activebackground='#FFF0F5',
            activeforeground='#FF1493',
            command=self.click_about)
        self.btn_about.place(relx=0.5, rely=0.87, anchor='center')

    def init_indicator(self):
        '''左边栏指示标志(爱心)'''
        self.indicator = Canvas(
            self.frame_left,
            highlightthickness=0,
            width=14 * self.window_width / 375,
            height=14 * self.window_width / 375,
            bg='#FFC0CB'  #pink
        )
        self.indicator.create_polygon(
            2 * self.window_width / 375,
            0,
            5 * self.window_width / 375,
            0,
            7 * self.window_width / 375,
            2 * self.window_width / 375,
            9 * self.window_width / 375,
            0,
            12 * self.window_width / 375,
            0,
            13 * self.window_width / 375,
            1 * self.window_width / 375,
            14 * self.window_width / 375,
            3 * self.window_width / 375,
            14 * self.window_width / 375,
            6 * self.window_width / 375,
            13 * self.window_width / 375,
            8 * self.window_width / 375,
            7 * self.window_width / 375,
            14 * self.window_width / 375,
            1 * self.window_width / 375,
            8 * self.window_width / 375,
            0,
            6 * self.window_width / 375,
            0,
            3 * self.window_width / 375,
            1 * self.window_width / 375,
            1 * self.window_width / 375,
            fill='#DA70D6',  #orchid
        )  #画一个多边形爱心
        self.indicator.place(relx=0.9, rely=0.48, anchor='center')

    def init_frame_calendar(self):
        '''日历页框架'''
        self.frame_calendar = Frame(
            self.window,
            bd=self.window_width / 120,
            relief='groove',
            width=self.window_width * 0.7,
            height=self.window_height,
            bg='#FFF0F5'  #lavenderblush
        )
        self.frame_calendar.pack(side='right')
        self.frame_calendar.pack_propagate(0)
        self.init_calendar()

    def init_calendar(self):
        '''日历页'''
        text_calendar = Label(
            self.frame_calendar,
            text='此功能开发中...',
            justify='left',
            bg='#FFF0F5'  #lavenderblush
        )
        text_calendar.place(relx=0.5, rely=0.4, anchor='n')

    def init_frame_stats(self):
        '''统计数据页框架'''
        self.frame_stats = Frame(
            self.window,
            bd=self.window_width / 120,
            relief='groove',
            width=self.window_width * 0.7,
            height=self.window_height,
            bg='#FFF0F5'  #lavenderblush
        )
        self.frame_stats.pack(side='right')
        self.frame_stats.pack_propagate(0)
        self.init_stats()

    def init_stats(self):
        '''统计数据页'''
        self.main.show_stats()

        #子框架,实现所有控件上下排列的同时整体居中
        frame_stats_amid = Frame(
            self.frame_stats,
            bg='#FFF0F5'  #lavenderblush
        )
        frame_stats_amid.pack(side='top', expand='yes')

        text_ongoing = Label(
            frame_stats_amid,
            text=self.main.print_ongoing,
            bg='#FFF0F5'  #lavenderblush
        )
        text_ongoing.pack(side='top')

        def click_reset():
            ans = messagebox.askokcancel(message='确定要取消进行中的经期吗?')
            if ans:
                self.main.reset()
                self.click_stats()

        if self.main.ongoing_date is not None:
            #重置按钮,点击后重置进行中的经期并刷新本页面
            btn_reset = Button(
                frame_stats_amid,
                text='重置',
                bd=2,
                relief='groove',
                bg='#FFFFFF',  #white
                fg='#FF1493',  #deeppink
                activebackground='#FFFFFF',
                activeforeground='#FF1493',
                command=click_reset)
            btn_reset.pack(side='top', pady=self.window_height / 60)

        text_stats = Label(
            frame_stats_amid,
            text=self.main.print_stats,
            justify='left',
            bg='#FFF0F5'  #lavenderblush
        )
        text_stats.pack(side='top')

        text_future = Label(
            frame_stats_amid,
            text=self.main.print_future,
            justify='left',
            bg='#FFF0F5'  #lavenderblush
        )
        text_future.pack(side='top')

    def init_frame_list(self):
        '''查看记录页框架'''
        self.frame_list = Frame(
            self.window,
            bd=self.window_width / 120,
            relief='groove',
            width=self.window_width * 0.7,
            height=self.window_height,
            bg='#FFF0F5'  #lavenderblush
        )
        self.frame_list.pack(side='right')
        self.frame_list.pack_propagate(0)
        self.init_list()

    def init_list(self):
        '''查看记录页'''
        self.main.show_list()

        label_list_titles = Label(
            self.frame_list,
            text='\n序号        起始日期       持续天数    间隔天数',
            bg='#FFF0F5'  #lavenderblush
        )
        label_list_titles.pack(side='top',
                               anchor='w',
                               padx=self.window_width / 40)

        frame_list_top = Frame(
            self.frame_list,
            padx=self.window_width / 40,
            bg='#FFF0F5'  #lavenderblush
        )
        frame_list_top.pack(side='top', fill='x')

        #滚动条控件
        scrollbar_list = Scrollbar(frame_list_top, orient='vertical')
        scrollbar_list.pack(side='right', anchor='n', fill='y')

        listbox_list = Listbox(
            frame_list_top,
            activestyle='none',
            selectmode='single',
            height=20,
            font=('consolas', 10),
            yscrollcommand=scrollbar_list.set  #列表绑定滚动条
        )
        listbox_list.insert('end', *self.main.print_list)  #载入全部记录
        listbox_list.insert('end', '  +')  #末尾空行方便插入最新记录
        listbox_list.pack(side='right', anchor='n', expand='yes', fill='x')

        scrollbar_list.configure(command=listbox_list.yview)  #滚动条绑定列表
        listbox_list.yview_moveto(1)  #视图默认滚动到底
        # listbox_list.selection_set(self.main.count - 1)
        # listbox_list.event_generate("<<ListboxSelect>>")    #默认选择最后一条记录

        frame_list_bottom = Frame(
            self.frame_list,
            padx=self.window_width / 40,
            pady=self.window_height / 20,
            bg='#FFF0F5'  #lavenderblush
        )
        frame_list_bottom.pack(side='top', fill='x')

        def click_insert():
            '''点击插入记录'''
            if len(listbox_list.curselection()) == 1:
                index = listbox_list.curselection()[0]

                dialog_insert = Toplevel()  #弹出对话框
                dialog_insert.wm_transient(self.window)  #与父窗口关联,窗口管理器不会当成独立窗口
                dialog_insert.focus_set()  #焦点切换到对话框
                dialog_insert.grab_set()  #事件不会传入父窗口(父窗口无法点击)
                dialog_insert.withdraw()  #隐藏窗口(等到窗口宽高位置设定好后再显示)
                dialog_insert.title('插入经期记录 (第{}行)'.format(index + 1))  #窗口标题

                frame_insert = Frame(
                    dialog_insert,
                    padx=self.window_width / 20,
                    pady=self.window_width / 20,
                    bg='#FFF0F5'  #lavenderblush
                )
                frame_insert.pack()

                #以下为开始日期控件组

                frame_insert_fromdate = Frame(
                    frame_insert,
                    bg='#FFF0F5'  #lavenderblush
                )
                frame_insert_fromdate.pack(side='top', anchor='s')

                label_from = Label(frame_insert_fromdate,
                                   text='开始日期:  ',
                                   bg='#FFF0F5')
                label_from.pack(side='left', anchor='n')

                box_yyyy1 = Combobox(frame_insert_fromdate,
                                     width=4,
                                     state='readonly')  #年选项框
                box_yyyy1['value'] = tuple(range(2000, date.today().year + 1))
                box_yyyy1.current(date.today().year - 2000)  #默认值为今天
                box_yyyy1.pack(side='left', anchor='n')

                label_year1 = Label(frame_insert_fromdate,
                                    text='年  ',
                                    bg='#FFF0F5')
                label_year1.pack(side='left', anchor='n')

                box_mm1 = Combobox(frame_insert_fromdate,
                                   width=2,
                                   state='readonly')  #月选项框
                box_mm1['value'] = tuple(range(1, 13))
                box_mm1.current(date.today().month - 1)  #默认值为今天
                box_mm1.pack(side='left', anchor='n')

                label_month1 = Label(frame_insert_fromdate,
                                     text='月  ',
                                     bg='#FFF0F5')
                label_month1.pack(side='left', anchor='n')

                box_dd1 = Combobox(frame_insert_fromdate,
                                   width=2,
                                   state='readonly')  #日选项框
                box_dd1['value'] = tuple(range(1, 32))
                box_dd1.current(date.today().day - 1)  #默认值为今天
                box_dd1.pack(side='left', anchor='n')

                label_day1 = Label(frame_insert_fromdate,
                                   text='日\n',
                                   bg='#FFF0F5')
                label_day1.pack(side='left', anchor='n')

                #以下为结束日期控件组

                frame_insert_todate = Frame(
                    frame_insert,
                    bg='#FFF0F5'  #lavenderblush
                )
                frame_insert_todate.pack(side='top', anchor='s')

                label_to = Label(frame_insert_todate,
                                 text='结束日期:  ',
                                 bg='#FFF0F5')
                label_to.pack(side='left', anchor='n')

                box_yyyy2 = Combobox(frame_insert_todate,
                                     width=4,
                                     state='readonly')  #年选项框
                box_yyyy2['value'] = tuple(range(2000, date.today().year + 1))
                box_yyyy2.current(date.today().year - 2000)  #默认值为今天
                box_yyyy2.pack(side='left', anchor='n')

                label_year2 = Label(frame_insert_todate,
                                    text='年  ',
                                    bg='#FFF0F5')
                label_year2.pack(side='left', anchor='n')

                box_mm2 = Combobox(frame_insert_todate,
                                   width=2,
                                   state='readonly')  #月选项框
                box_mm2['value'] = tuple(range(1, 13))
                box_mm2.current(date.today().month - 1)  #默认值为今天
                box_mm2.pack(side='left', anchor='n')

                label_month2 = Label(frame_insert_todate,
                                     text='月  ',
                                     bg='#FFF0F5')
                label_month2.pack(side='left', anchor='n')

                box_dd2 = Combobox(frame_insert_todate,
                                   width=2,
                                   state='readonly')  #日选项框
                box_dd2['value'] = tuple(range(1, 32))
                box_dd2.current(date.today().day - 1)  #默认值为今天
                box_dd2.pack(side='left', anchor='n')

                label_day2 = Label(frame_insert_todate,
                                   text='日\n\n',
                                   bg='#FFF0F5')
                label_day2.pack(side='left', anchor='n')

                def insert():
                    '''点击对话框中的插入记录按钮'''
                    #获取开始日期
                    yyyy1 = int(box_yyyy1.get())
                    mm1 = int(box_mm1.get())
                    dd1 = int(box_dd1.get())

                    #获取结束日期
                    yyyy2 = int(box_yyyy2.get())
                    mm2 = int(box_mm2.get())
                    dd2 = int(box_dd2.get())

                    self.main.insert(index, yyyy1, mm1, dd1, yyyy2, mm2, dd2)
                    if self.main.add_error:
                        #插入记录异常
                        messagebox.showinfo(message=self.main.error_msg,
                                            parent=dialog_insert)
                    else:
                        #插入记录成功
                        dialog_insert.destroy()  #关闭对话框
                        self.refresh()  #刷新页面相关信息
                        messagebox.showinfo(message='插入记录成功!')

                #对话框的插入记录按钮
                btn_insert_enter = Button(
                    frame_insert,
                    text='插入记录',
                    bd=2,
                    relief='groove',
                    bg='#FFFFFF',  #white
                    fg='#FF1493',  #deeppink
                    activebackground='#FFFFFF',
                    activeforeground='#FF1493',
                    command=insert)
                btn_insert_enter.pack(side='top', anchor='n')

                dialog_insert.update_idletasks()  #手动更新显示,以获得布局后的窗口宽高来设置窗口位置
                dialog_insert_x = int(
                    (dialog_insert.winfo_screenwidth() * self.scale_factor -
                     dialog_insert.winfo_width()) / 2)
                dialog_insert_y = int(
                    (dialog_insert.winfo_screenheight() * self.scale_factor -
                     dialog_insert.winfo_height()) / 2)
                dialog_insert.geometry('+{}+{}'.format(
                    dialog_insert_x, dialog_insert_y))  #设置窗口位置
                dialog_insert.resizable(False, False)  #锁定窗口大小
                dialog_insert.deiconify()  #显示窗口
                # dialog_insert.wait_window()

        #插入记录按钮
        btn_insert = Button(
            frame_list_bottom,
            text='在选中行上方\n插入记录',
            height=2,
            bd=2,
            relief='groove',
            bg='#FFFFFF',  #white
            fg='#FF1493',  #deeppink
            activebackground='#FFFFFF',
            activeforeground='#FF1493',
            command=click_insert)
        btn_insert.pack(side='left', expand='yes')

        def delete():
            '''点击删除选中记录'''
            if len(listbox_list.curselection()) == 1:
                index = listbox_list.curselection()[0]
                if index < self.main.count:
                    ans = messagebox.askokcancel(message='确定要删除选中的记录吗?')
                    if ans:
                        self.main.delete(index)
                        self.click_list()

        #删除选中记录按钮
        btn_delete = Button(
            frame_list_bottom,
            text='删除选中记录',
            height=2,
            bd=2,
            relief='groove',
            bg='#FFFFFF',  #white
            fg='#FF1493',  #deeppink
            activebackground='#FFFFFF',
            activeforeground='#FF1493',
            command=delete)
        btn_delete.pack(side='left', expand='yes')

        def delete_all():
            '''点击删除全部记录'''
            if self.main.count > 0:
                ans = messagebox.showwarning(title='警告', message='危险操作')
                if ans:
                    ans = messagebox.askokcancel(title='警告:危险操作',
                                                 message='确定要删除全部记录吗?')
                    if ans:
                        ans = messagebox.askokcancel(title='点击确定将删除全部记录',
                                                     message='真的要删除全部记录吗?')
                        if ans:
                            self.main.delete_all()
                            self.click_list()

        #删除全部记录按钮
        btn_delete_all = Button(
            frame_list_bottom,
            text='删除全部记录',
            height=2,
            bd=2,
            relief='groove',
            bg='#FFFFFF',  #white
            fg='#FF1493',  #deeppink
            activebackground='#FFFFFF',
            activeforeground='#FF1493',
            command=delete_all)
        btn_delete_all.pack(side='left', expand='yes')

    def init_frame_settings(self):
        '''设置页框架'''
        self.frame_settings = Frame(
            self.window,
            bd=self.window_width / 120,
            relief='groove',
            width=self.window_width * 0.7,
            height=self.window_height,
            bg='#FFF0F5'  #lavenderblush
        )
        self.frame_settings.pack(side='right')
        self.frame_settings.pack_propagate(0)
        self.init_settings()

    def init_settings(self):
        '''设置页'''
        def change_dpi_adapt():
            '''更改dpi_adapt设置项'''
            self.main.dpi_adapt = self.dpi_adapt.get()
            self.main.save_settings()

        #设置项:高dpi屏幕显示缩放适配
        self.dpi_adapt = BooleanVar(
            value=self.main.dpi_adapt)  #选框默认值。必须设为实例变量,否则会被回收
        checkbox_dpi_adapt = Checkbutton(
            self.frame_settings,
            text='高dpi屏幕显示缩放适配(重启应用后生效)',
            variable=self.dpi_adapt,
            onvalue=True,
            offvalue=False,
            bg='#FFF0F5',  #lavenderblush
            activebackground='#FFF0F5',
            command=change_dpi_adapt)
        checkbox_dpi_adapt.pack(side='top',
                                padx=self.window_width / 20,
                                pady=self.window_height / 20,
                                anchor='nw')

    def init_frame_about(self):
        '''关于页框架'''
        self.frame_about = Frame(
            self.window,
            bd=self.window_width / 120,
            relief='groove',
            width=self.window_width * 0.7,
            height=self.window_height,
            bg='#FFF0F5'  #lavenderblush
        )
        self.frame_about.pack(side='right')
        self.frame_about.pack_propagate(0)
        self.init_about()

    def init_about(self):
        '''关于页'''
        self.click_count = 0  #hidden触发计数器
        text_about = Text(
            self.frame_about,
            width=45,
            height=15,
            bd=0,
            relief='flat',
            cursor='arrow',
            bg='#FFF0F5'  #lavenderblush
        )
        text_about.insert('end', '作者: HansenH\n\n')
        text_about.insert('end', '邮箱: [email protected]\n\n')
        text_about.insert('end', '源码(Python3): \n')
        text_about.insert('end',
                          'https://github.com/HansenH/PeriodCalculator\n\n')
        text_about.insert('end', '\n\nMIT License\nCopyright (c) 2021 HansenH')

        text_about.tag_add('link', '6.0', '6.43')  #第六行超链接加tag
        text_about.tag_config('link', foreground='blue', underline=True)
        text_about.tag_add('hidden', '1.4', '1.11')  #第一行HansenH加tag

        def show_hand_cursor(event):
            text_about.configure(cursor='hand2')

        def show_arrow_cursor(event):
            text_about.configure(cursor='arrow')

        def click_link(event):
            webbrowser.open_new_tab(
                'https://github.com/HansenH/PeriodCalculator')

        def show_heart_cursor(event):
            text_about.configure(cursor='heart')
            self.click_count = 0  #鼠标进入或离开'HansenH'都会重置计数器self.self.click_count

        def show_arrow_cursor2(event):
            text_about.configure(cursor='arrow')
            self.click_count = 0

        def click_hidden_5_times(event):
            self.click_count += 1
            if self.click_count == 5:
                self.hidden()  #触发hidden Easter Egg!

        text_about.tag_bind('link', '<Enter>', show_hand_cursor)  #鼠标指向
        text_about.tag_bind('link', '<Leave>', show_arrow_cursor)  #鼠标离开
        text_about.tag_bind('link', '<Button-1>', click_link)  #左键点击
        text_about.tag_bind('hidden', '<Enter>', show_heart_cursor)  #鼠标指向
        text_about.tag_bind('hidden', '<Leave>', show_arrow_cursor2)  #鼠标离开
        text_about.tag_bind('hidden', '<Button-1>',
                            click_hidden_5_times)  #触发hidden
        text_about.place(relx=0.5, rely=0.2, anchor='n')
        text_about.configure(state='disabled')

    def click_add(self):
        '''点击新增按钮,创建模态对话框'''
        dialog_add = Toplevel()  #弹出对话框
        dialog_add.wm_transient(self.window)  #与父窗口关联,窗口管理器不会当成独立窗口
        dialog_add.focus_set()  #焦点切换到对话框
        dialog_add.grab_set()  #事件不会传入父窗口(父窗口无法点击)
        dialog_add.withdraw()  #隐藏窗口(等到窗口宽高位置设定好后再显示)
        dialog_add.title('添加经期开始/结束')  #窗口标题

        frame_add = Frame(
            dialog_add,
            padx=self.window_width / 20,
            pady=self.window_width / 20,
            bg='#FFF0F5'  #lavenderblush
        )
        frame_add.pack()

        def add():
            '''点击对话框中的添加记录按钮'''
            yyyy = int(box_yyyy.get())  #从下拉选项框获取数据
            mm = int(box_mm.get())
            dd = int(box_dd.get())
            self.main.add(yyyy, mm, dd)  #添加经期开始/结束
            if self.main.add_error:
                #添加记录异常
                messagebox.showinfo(message=self.main.error_msg,
                                    parent=dialog_add)
            else:
                #添加记录成功
                dialog_add.destroy()  #关闭对话框
                self.refresh()  #刷新页面相关信息
                messagebox.showinfo(message='添加记录成功!')

        #添加记录的按钮
        btn_add_enter = Button(
            frame_add,
            bd=2,
            relief='groove',
            bg='#FFFFFF',  #white
            fg='#FF1493',  #deeppink
            activebackground='#FFFFFF',
            activeforeground='#FF1493',
            command=add)
        btn_add_enter.pack(side='bottom', anchor='s')
        if self.main.ongoing_date is None:
            btn_add_enter.configure(text='添加经期开始日期')
        else:
            btn_add_enter.configure(text='添加经期结束日期')

        box_yyyy = Combobox(frame_add, width=4, state='readonly')  #年选项框
        box_yyyy['value'] = tuple(range(2000, date.today().year + 1))
        box_yyyy.current(date.today().year - 2000)  #默认值为今天
        box_yyyy.pack(side='left', anchor='n')

        label_year = Label(frame_add, text='年  ', bg='#FFF0F5')
        label_year.pack(side='left', anchor='n')

        box_mm = Combobox(frame_add, width=2, state='readonly')  #月选项框
        box_mm['value'] = tuple(range(1, 13))
        box_mm.current(date.today().month - 1)  #默认值为今天
        box_mm.pack(side='left', anchor='n')

        label_month = Label(frame_add, text='月  ', bg='#FFF0F5')
        label_month.pack(side='left', anchor='n')

        box_dd = Combobox(frame_add, width=2, state='readonly')  #日选项框
        box_dd['value'] = tuple(range(1, 32))
        box_dd.current(date.today().day - 1)  #默认值为今天
        box_dd.pack(side='left', anchor='n')

        label_day = Label(frame_add, text='日\n\n', bg='#FFF0F5')
        label_day.pack(side='left', anchor='n')

        dialog_add.update_idletasks()  #手动更新显示,以获得布局后的窗口宽高来设置窗口位置
        dialog_add_x = int(
            (dialog_add.winfo_screenwidth() * self.scale_factor -
             dialog_add.winfo_width()) / 2)
        dialog_add_y = int(
            (dialog_add.winfo_screenheight() * self.scale_factor -
             dialog_add.winfo_height()) / 2)
        dialog_add.geometry('+{}+{}'.format(dialog_add_x,
                                            dialog_add_y))  #设置窗口位置
        dialog_add.resizable(False, False)  #锁定窗口大小
        dialog_add.deiconify()  #显示窗口
        # dialog_add.wait_window()

    def click_calendar(self):
        '''点击日历按钮'''
        self.indicator.place(relx=0.9, rely=0.35, anchor='center')  #移动爱心位置
        self.current_frame.destroy()  #关闭当前的右侧页面
        self.init_frame_calendar()  #打开新的右侧页面
        self.current_frame = self.frame_calendar

    def click_stats(self):
        '''点击统计数据按钮'''
        self.indicator.place(relx=0.9, rely=0.48, anchor='center')  #移动爱心位置
        self.current_frame.destroy()  #关闭当前的右侧页面
        self.init_frame_stats()  #打开新的右侧页面
        self.current_frame = self.frame_stats

    def click_list(self):
        '''点击查看记录'''
        self.indicator.place(relx=0.9, rely=0.61, anchor='center')  #移动爱心位置
        self.current_frame.destroy()  #关闭当前的右侧页面
        self.init_frame_list()  #打开新的右侧页面
        self.current_frame = self.frame_list

    def click_settings(self):
        '''点击设置按钮'''
        self.indicator.place(relx=0.9, rely=0.74, anchor='center')  #移动爱心位置
        self.current_frame.destroy()  #关闭当前的右侧页面
        self.init_frame_settings()  #打开新的右侧页面
        self.current_frame = self.frame_settings

    def click_about(self):
        '''点击关于按钮'''
        self.indicator.place(relx=0.9, rely=0.87, anchor='center')  #移动爱心位置
        self.current_frame.destroy()  #关闭当前的右侧页面
        self.init_frame_about()  #打开新的右侧页面
        self.current_frame = self.frame_about

    def hidden(self):
        '''Easter Egg!'''
        self.current_frame.destroy()  #销毁原右侧页面
        self.frame_left.pack_forget()  #暂时隐藏左边栏
        heart_rain = Canvas(
            self.window,
            highlightthickness=0,
            width=self.window_width,
            height=self.window_height,
            cursor='heart',
            bg='#FFF0F5'  #lavenderblush
        )
        heart_rain.place(relx=0.5, rely=0.5, anchor='center')
        heart_rain.focus_set()  #焦点切换到对话框

        heart_rain.create_text(
            0.5 * self.window_width,
            0.35 * self.window_height,
            text='This app is made for my beloved girl Wang Ting.',
            font=('Times', 12, 'bold italic'),
            anchor='center')
        heart_rain.create_text(0.5 * self.window_width,
                               0.85 * self.window_height,
                               text='<返回>',
                               anchor='center',
                               tag='back')

        def create_heart(size_factor, relx, rely):
            '''生成爱心(尺寸倍率, 相对x坐标, 相对y坐标),锚点=S'''
            heart = heart_rain.create_polygon(
                -5 * size_factor * self.window_width / 375 +
                relx * self.window_width,
                -14 * size_factor * self.window_width / 375 +
                rely * self.window_height,
                -2 * size_factor * self.window_width / 375 +
                relx * self.window_width,
                -14 * size_factor * self.window_width / 375 +
                rely * self.window_height,
                0 * size_factor * self.window_width / 375 +
                relx * self.window_width,
                -12 * size_factor * self.window_width / 375 +
                rely * self.window_height,
                2 * size_factor * self.window_width / 375 +
                relx * self.window_width,
                -14 * size_factor * self.window_width / 375 +
                rely * self.window_height,
                5 * size_factor * self.window_width / 375 +
                relx * self.window_width,
                -14 * size_factor * self.window_width / 375 +
                rely * self.window_height,
                6 * size_factor * self.window_width / 375 +
                relx * self.window_width,
                -13 * size_factor * self.window_width / 375 +
                rely * self.window_height,
                7 * size_factor * self.window_width / 375 +
                relx * self.window_width,
                -11 * size_factor * self.window_width / 375 +
                rely * self.window_height,
                7 * size_factor * self.window_width / 375 +
                relx * self.window_width,
                -8 * size_factor * self.window_width / 375 +
                rely * self.window_height,
                6 * size_factor * self.window_width / 375 +
                relx * self.window_width,
                -6 * size_factor * self.window_width / 375 +
                rely * self.window_height,
                0 * size_factor * self.window_width / 375 +
                relx * self.window_width,
                0 * size_factor * self.window_width / 375 +
                rely * self.window_height,
                -6 * size_factor * self.window_width / 375 +
                relx * self.window_width,
                -6 * size_factor * self.window_width / 375 +
                rely * self.window_height,
                -7 * size_factor * self.window_width / 375 +
                relx * self.window_width,
                -8 * size_factor * self.window_width / 375 +
                rely * self.window_height,
                -7 * size_factor * self.window_width / 375 +
                relx * self.window_width,
                -11 * size_factor * self.window_width / 375 +
                rely * self.window_height,
                -6 * size_factor * self.window_width / 375 +
                relx * self.window_width,
                -13 * size_factor * self.window_width / 375 +
                rely * self.window_height,
                fill='#FF1493',  #deeppink
            )
            return heart

        # 尺寸--速度--出现概率
        # 0.5--1--0.533  1--2--0.267  2--4--0.133  4--8--0.067
        # 生成位置:relx范围 -0.1~1.1  rely=-0.1
        hearts = []  #爱心队列
        speed = []  #每个爱心的速度
        PRODUCTION_RATE = 10  #每一帧生成新爱心的概率(%)
        SEPPD_FACTOR = 0.75  #下落速度系数

        def heart_drop_loop():
            '''实现爱心不断下落的循环'''
            #生成爱心
            if random.randint(0, 99) < PRODUCTION_RATE:
                rand_num = random.randint(0, 999)  #四种爱心按不同概率生成
                if rand_num < 533:
                    hearts.append(
                        create_heart(0.5,
                                     random.randint(-100, 1100) / 1000, 0))
                    speed.append(1)
                elif 533 <= rand_num < 800:
                    hearts.append(
                        create_heart(1,
                                     random.randint(-100, 1100) / 1000, 0))
                    speed.append(2)
                elif 800 <= rand_num < 933:
                    hearts.append(
                        create_heart(2,
                                     random.randint(-100, 1100) / 1000, 0))
                    speed.append(4)
                else:
                    hearts.append(
                        create_heart(4,
                                     random.randint(-100, 1100) / 1000, 0))
                    speed.append(8)
            #下移爱心
            for i in range(len(hearts) - 1, -1, -1):
                heart_rain.move(hearts[i], 0, speed[i] * SEPPD_FACTOR)
                #删除出界的爱心(注意应当在倒序循环中删除元素)
                if heart_rain.coords(hearts[i])[1] > self.window_height:
                    heart_rain.delete(hearts.pop(i))
                    del speed[i]

            heart_rain.after(10, heart_drop_loop)  #after实现一段时间后再次调用自己
            #如果改用while和time.sleep()实现,会形成阻塞,无法在循环中监测事件!

        def back(event):
            '''返回'''
            heart_rain.destroy()
            self.frame_left.pack(side='left')
            self.frame_left.pack_propagate(0)
            self.init_frame_about()
            self.current_frame = self.frame_about

        heart_rain.tag_bind('back', '<Button-1>', back)
        heart_drop_loop()

    def refresh(self):
        '''(在记录改动后)刷新当前页面'''
        if self.current_frame == self.frame_stats:
            self.click_stats()
        elif self.current_frame == self.frame_list:
            self.click_list()
Beispiel #22
0
class QuantMonitor(object):

    # 背景色
    bgColor = rgb_to_hex(245, 245, 245)
    bgColorW = "white"

    def __init__(self, frame, control, language):
        self.parentFrame = frame
        self._controller = control
        self._logger = self._controller.get_logger()
        self.language = language

        # Monitor不同标签的背景色
        self.rColor = self.bgColorW
        self.lColor = self.bgColor
        self.eColor = self.bgColor
        self.pColor = self.bgColor
        # 日志不同标签背景色
        self.yColor = self.bgColor   # 系统日志标签颜色
        self.sColor = self.bgColor
        self.uColor = self.bgColorW

        self.createButtonFrame()

        # 执行列表、监控日志、信号记录、错误
        self.executeList  = Frame(self.parentFrame)
        self.errRecord    = Frame(self.parentFrame)
        self.posMonitor   = Frame(self.parentFrame)
        self.logRecord    = Frame(self.parentFrame)

        self.sysLog       = Frame(self.logRecord)
        self.sigRecord    = Frame(self.logRecord)
        self.usrLog       = Frame(self.logRecord)

        self.executeList.pack(side=TOP, fill=BOTH, expand=YES)

        self.sysText = None
        self.sigText = None
        self.usrText = None
        self.errText = None

        # 日志功能区
        self.createLogBtnFrame()
        self.usrLog.pack(side=TOP, fill=BOTH, expand=YES)

    def createButtonFrame(self):
        btnFrame = Frame(self.parentFrame, height=30, bg=self.bgColor)
        btnFrame.pack_propagate(0)
        btnFrame.pack(side=TOP, fill=X)

        self.runBtn = Button(btnFrame, text="策略运行", relief=FLAT, padx=14, pady=1.5, bg=self.rColor,
                             bd=0, highlightthickness=1, command=self.toMonFrame)
        self.logBtn = Button(btnFrame, text="运行日志", relief=FLAT, padx=14, pady=1.5, bg=self.lColor,
                             bd=0, highlightthickness=1, command=self.toLogFrame)
        self.errBtn = Button(btnFrame, text="错误信息", relief=FLAT, padx=14, pady=1.5, bg=self.eColor,
                             bd=0, highlightthickness=1, command=self.toErrFrame)

        self.posBtn = Button(btnFrame, text="组合监控", relief=FLAT, padx=14, pady=1.5, bg=self.pColor,
                             bd=0, highlightthickness=1, command=self.toPosFrame)
        self.runBtn.pack(side=LEFT, expand=NO)
        self.logBtn.pack(side=LEFT, expand=NO)
        self.errBtn.pack(side=LEFT, expand=NO)
        self.posBtn.pack(side=LEFT, expand=NO)

        for btn in (self.runBtn, self.logBtn, self.errBtn, self.posBtn):
            btn.bind("<Enter>", self.handlerAdaptor(self.onEnter, button=btn))
            btn.bind("<Leave>", self.handlerAdaptor(self.onLeave, button=btn))

    def createLogBtnFrame(self):
        """创建日志按钮Frame"""
        lBtnFrame = Frame(self.logRecord, height=30, bg=self.bgColor)
        lBtnFrame.pack_propagate(0)
        lBtnFrame.pack(side=BOTTOM, fill=X)

        self.usrBtn = Button(lBtnFrame, text="用户日志", relief=FLAT, padx=14, pady=1.5, bg=self.rColor,
                             bd=0, highlightthickness=1, command=self.toUsrFrame)
        self.sigBtn = Button(lBtnFrame, text="信号记录", relief=FLAT, padx=14, pady=1.5, bg=self.lColor,
                             bd=0, highlightthickness=1, command=self.toSigFrame)
        self.sysBtn = Button(lBtnFrame, text="系统日志", relief=FLAT, padx=14, pady=1.5, bg=self.sColor,
                             bd=0, highlightthickness=1, command=self.toSysFrame)

        self.usrBtn.pack(side=LEFT, expand=NO)
        self.sigBtn.pack(side=LEFT, expand=NO)
        self.sysBtn.pack(side=LEFT, expand=NO)

        # for btn in (self.usrBtn, self.sigBtn, self.sysBtn):
            # btn.bind("<Enter>", self.handlerAdaptor(self.onEnter, button=btn))
            # btn.bind("<Leave>", self.handlerAdaptor(self.onLeave, button=btn))
            # pass

    def createLog(self):
        self.createSysLog()
        self.createSignal()
        self.createUsrLog()

    def createSysLog(self):
        """系统日志"""
        self.sysText = MonitorText(self.sysLog, height=20, bd=0)
        self.sysText.createScrollbar()
        self.sysText.pack(fill=BOTH, expand=YES)

    def createSignal(self):
        """信号记录"""
        self.sigText = LogText(self.sigRecord, height=20, bd=0)
        self.sigText.createScrollbar()
        self.sigText.pack(fill=BOTH, expand=YES)

    def createUsrLog(self):
        """用户日志"""
        self.usrText = LogText(self.usrLog, height=20, bd=0)
        self.usrText.createScrollbar()
        self.usrText.pack(fill=BOTH, expand=YES)

    def createPos(self):
        headList = ["账号", "合约", "账户仓", "策略仓", "仓差",
                    "策略多", "策略空","策略今多", "策略今空", "账户多", "账户空", "账户今多", "账户今空"]
        widthList = [20, 20, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]

        funcFrame = Frame(self.posMonitor, relief=RAISED, bg=rgb_to_hex(245, 245, 245), height=25)
        funcFrame.pack(side=TOP, fill=X, expand=YES, padx=1, pady=2)
        treeFrame = Frame(self.posMonitor, relief=RAISED, bg=rgb_to_hex(245, 245, 245))
        treeFrame.pack(side=TOP, fill=X, expand=YES, padx=1, pady=2)
        self.posTree = ttk.Treeview(treeFrame, show="headings", height=28, columns=headList)
        self.posTree.pack(fill=BOTH, expand=YES, padx=5)

        for key, w in zip(headList, widthList):
            self.posTree.column(key, width=w, anchor=W)
            self.posTree.heading(key, text=key, anchor=W)

        self.createPosFunc(funcFrame)

    def createPosFunc(self, frame):
        cbV    = StringVar()
        sbV    = IntVar()
        timeV  = IntVar()

        cbV.set("对盘价")
        sbV.set(0)
        timeV.set(5000)

        # buttonborder = Frame(frame, highlightbackground="lightblue", highlightthickness=2, bd=0)
        # buttonborder.pack(side=LEFT, padx=2)

        synBtn = Button(frame, text="持仓一键同步", relief=FLAT, activebackground="lightblue",
                        overrelief="groove",
                        bg=rgb_to_hex(230, 230, 230))
        synBtn.pack(side=LEFT, padx=2)

        Label(frame, text="同步设置:", bg=rgb_to_hex(245, 245, 245), justify=LEFT, anchor=W, width=8).pack(side=LEFT)

        cbValues = ["对盘价", "最新价", "市价"]

        cb = ttk.Combobox(frame, values=cbValues, width=11, textvariable=cbV, state="readonly")
        cb.pack(side=LEFT, padx=2)

        Label(frame, text="+", bg=rgb_to_hex(245, 245, 245), justify=LEFT, anchor=W, width=1).pack(side=LEFT)

        sb = ttk.Spinbox(frame, values=list(range(0, 101, 1)), width=4, textvariable=sbV)
        sb.pack(side=LEFT, padx=2)

        Label(frame, text="跳", bg=rgb_to_hex(245, 245, 245), justify=LEFT, anchor=W, width=2).pack(side=LEFT)

        disCheck = Checkbutton(frame, text="间隔", bg=rgb_to_hex(245, 245, 245), width=10, bd=1, anchor=E)
        disCheck.pack(side=LEFT, padx=2)

        timeEntry = Entry(frame, relief=GROOVE, bd=2, width=5, textvariable=timeV)
        timeEntry.pack(side=LEFT)

        Label(frame, text="毫秒自动同步", bg=rgb_to_hex(245, 245, 245), justify=LEFT, anchor=W, width=12)\
            .pack(side=LEFT, padx=2)

        subCheck = Checkbutton(frame, text="仅自动减仓", bg=rgb_to_hex(245, 245, 245), bd=1, anchor=W)
        subCheck.pack(side=LEFT, padx=5)

    def createExecute(self):
        headList  = ["编号", "账号", "策略名称", "基准合约", "频率", "运行状态", "实盘运行",
                    "初始资金", "可用资金", "最大回撤", "累计收益", "胜率"]
        widthList = [5, 50, 50, 50, 5, 10, 5, 20, 10, 20, 20, 5]

        self.executeBar = ttk.Scrollbar(self.executeList, orient="vertical")
        self.executeBar.pack(side=RIGHT, fill=Y)

        self.executeListTree = ttk.Treeview(self.executeList, show="headings", height=28, columns=tuple(headList),
                                            yscrollcommand=self.executeBar.set, style="Filter.Treeview")
        self.executeBar.config(command=self.executeListTree.yview)
        self.executeListTree.pack(fill=BOTH, expand=YES)

        self.executeListTree.bind("<Button-3>", self.createMenu)

        for key, w in zip(headList, widthList):
            self.executeListTree.column(key, width=w, anchor=CENTER)
            self.executeListTree.heading(key, text=key)

    def createMenu(self, event):
        """创建运行策略右键菜单"""
        RunMenu(self._controller, self.executeListTree).popupmenu(event)

    def _formatMonitorInfo(self, dataDict):
        """
        格式化监控需要的信息
        :param dataDict: 策略的所有信息
        :return: 需要展示的信息
        """

        try:
            Id          = dataDict['StrategyId']
            UserNo      = dataDict["Config"]["Money"]["UserNo"]
            StName      = dataDict['StrategyName']
            BenchCon    = dataDict['ContractNo']
            kLineType   = dataDict['KLineType']
            kLineSlice  = dataDict['KLinceSlice']

            Frequency   = str(kLineSlice) + kLineType

            RunType     = "是" if dataDict['IsActualRun'] else "否"
            Status      = StrategyStatus[dataDict["StrategyState"]]
            InitFund    = dataDict['InitialFund']

            Available   = "{:.2f}".format(InitFund)
            MaxRetrace  = 0.0
            TotalProfit = 0.0
            WinRate     = 0.0

            return [
                Id,
                UserNo,
                StName,
                BenchCon,
                Frequency,
                Status,
                RunType,
                InitFund,
                Available,
                MaxRetrace,
                TotalProfit,
                WinRate
            ]

        except KeyError:
            traceback.print_exc()
            return []

    def addExecute(self, dataDict):
        values = self._formatMonitorInfo(dataDict)

        if not values:
            return

        strategyId = dataDict["StrategyId"]
        try:
            if self.executeListTree.exists(strategyId):
                self.updateStatus(strategyId, dataDict[5])
                return
        except Exception as e:
            self._logger.warn("addExecute exception")
        else:
            self.executeListTree.insert("", END, iid=strategyId, values=tuple(values), tag=0)

    def createErr(self):
        # 错误信息展示
        self.errText = ErrorText(self.errRecord, height=20, bd=0)
        self.errText.createScrollbar()
        self.errText.pack(fill=BOTH, expand=YES)

    def updateLogText(self):
        guiQueue = self._controller.get_logger().getGuiQ()
        data = ""
        flag = True
        try:
            # data = guiQueue.get_nowait()
            while flag:
                data += guiQueue.get_nowait()+"\n"
                if guiQueue.empty():
                    flag = False
        except:
            return
        else:
            self.sysText.setText(data)

    def updateSigText(self):
        """更新信号记录"""
        sigQueue = self._controller.get_logger().getSigQ()
        sigData = ''
        flag = True
        try:
            # sigData = sigQueue.get_nowait()
            while flag:
                sigData += sigQueue.get_nowait()+"\n"
                if sigQueue.empty():
                    flag = False

        except Exception as e:
            return
        else:
            # self.toSigFrame()
            self.sigText.setText(sigData)

    def updateUsrText(self):
        """更新用户日志"""
        usrQueue = self._controller.get_logger().getUsrQ()
        usrData = ''
        flag = True
        try:
            while flag:
                usrData += usrQueue.get_nowait()+"\n"
                if usrQueue.empty():
                    flag = False

        except Exception as e:
            return
        else:
            self.usrText.setText(usrData)

    def updateErrText(self):
        errQueue = self._controller.get_logger().getErrQ()
        try:
            errData = errQueue.get_nowait()
        except:
            return
        else:
            self.toErrFrame()
            self.errText.setText(errData)

    def clearErrorText(self):
        self.errText.setText("")

    def toMonFrame(self):
        self.runBtn.config(bg="white")
        self.rColor = self.runBtn['bg']
        self.lColor = self.bgColor
        self.eColor = self.bgColor
        self.pColor = self.bgColor
        self.errBtn.config(bg=self.rColor)
        self.logBtn.config(bg=self.lColor)
        self.posBtn.config(bg=self.pColor)
        self.logRecord.pack_forget()
        self.errRecord.pack_forget()
        self.posMonitor.pack_forget()
        self.executeList.pack(side=TOP, fill=BOTH, expand=YES)

    # def toLogFrame(self, event, button):
    #     buttons = [self.runBtn, self.logBtn, self.errBtn, self.posBtn]
    #     colors = [self.rColor, self.lColor, self.eColor, self.pColor]
    #     frames = [self.executeList, self.logRecord, self.errRecord, self.posMonitor]
    #
    #     button.config(bg="white")
    #     index = buttons.index(button)
    #     colors[index] = button['bg']
    #     frames[index].pack(side=TOP, fill=BOTH, expand=YES)
    #     buttons.remove(button)
    #     colors.remove(colors[index])
    #     frames.remove(frames[index])
    #     #TODO:怎么pop呢?
    #
    #     for btn in buttons:
    #         i = buttons.index(btn)
    #         colors[i] = self.bgColor
    #         btn.config(bg=self.bgColor)
    #         frames[i].pack_forget()

    def toLogFrame(self):
        self.logBtn.config(bg="white")
        self.lColor = self.logBtn['bg']
        self.rColor = self.bgColor
        self.eColor = self.bgColor
        self.pColor = self.bgColor
        self.runBtn.config(bg=self.rColor)
        self.errBtn.config(bg=self.eColor)
        self.posBtn.config(bg=self.pColor)
        self.executeList.pack_forget()
        self.errRecord.pack_forget()
        self.posMonitor.pack_forget()
        self.logRecord.pack(side=TOP, fill=BOTH, expand=YES)

    def toSysFrame(self):
        self.sysBtn.config(bg="white")
        self.yColor = self.sysBtn['bg']
        self.sColor = self.bgColor
        self.uColor = self.bgColor

        self.sigBtn.config(bg=self.sColor)
        self.usrBtn.config(bg=self.uColor)

        self.sigRecord.pack_forget()
        self.usrLog.pack_forget()

        self.sysLog.pack(side=TOP, fill=BOTH, expand=YES)

    def toSigFrame(self):
        self.sigBtn.config(bg="white")
        self.sColor = self.sigBtn['bg']
        self.uColor = self.bgColor
        self.yColor = self.bgColor

        self.sysBtn.config(bg=self.yColor)
        self.usrBtn.config(bg=self.uColor)

        self.sysLog.pack_forget()
        self.usrLog.pack_forget()

        self.sigRecord.pack(side=TOP, fill=BOTH, expand=YES)

    def toUsrFrame(self):
        self.usrBtn.config(bg="white")
        self.uColor = self.sysBtn['bg']
        self.sColor = self.bgColor
        self.yColor = self.bgColor

        self.sigBtn.config(bg=self.sColor)
        self.sysBtn.config(bg=self.yColor)

        self.sigRecord.pack_forget()
        self.sysLog.pack_forget()

        self.usrLog.pack(side=TOP, fill=BOTH, expand=YES)

    def toErrFrame(self):
        self.errBtn.config(bg="white")
        self.eColor = self.errBtn['bg']
        self.lColor = self.bgColor
        self.rColor = self.bgColor
        self.pColor = self.bgColor
        self.runBtn.config(bg=self.rColor)
        self.logBtn.config(bg=self.lColor)
        self.posBtn.config(bg=self.pColor)
        self.parentFrame.update()
        self.logRecord.pack_forget()
        self.executeList.pack_forget()
        self.posMonitor.pack_forget()
        self.errRecord.pack(side=TOP, fill=BOTH, expand=YES)

    def toPosFrame(self):
        self.posBtn.config(bg="white")
        self.pColor = self.posBtn['bg']
        self.lColor = self.bgColor
        self.rColor = self.bgColor
        self.eColor = self.bgColor
        self.runBtn.config(bg=self.rColor)
        self.logBtn.config(bg=self.lColor)
        self.errBtn.config(bg=self.eColor)
        self.parentFrame.update()
        self.logRecord.pack_forget()
        self.executeList.pack_forget()
        self.errRecord.pack_forget()
        self.posMonitor.pack(side=TOP, fill=BOTH, expand=YES)

    def handlerAdaptor(self, fun, **kwargs):
        return lambda event, fun=fun, kwargs=kwargs: fun(event, **kwargs)

    def onEnter(self, event, button):
        """鼠标进入事件"""
        buttons = [self.runBtn, self.logBtn, self.errBtn, self.posBtn]
        button.config(bg='white')
        buttons.remove(button)
        for btn in buttons:
            btn.config(bg=self.bgColor)

    def onLeave(self, event, button):
        """鼠标离开事件"""
        buttons = [self.runBtn, self.logBtn, self.errBtn, self.posBtn]
        #TODO: 类实例作为字典键值有问题!
        btnColorDict = {
            self.runBtn: self.rColor,
            self.logBtn: self.lColor,
            self.errBtn: self.eColor,
            self.posBtn: self.pColor
        }
        button.config(bg=rgb_to_hex(227, 230, 233))
        button['bg'] = btnColorDict[button]

        buttons.remove(button)
        for btn in buttons:
            btn['bg'] = btnColorDict[btn]

    def deleteStrategy(self, strategyId):
        """删除策略"""
        if str(strategyId) in self.executeListTree.get_children():
            self.executeListTree.delete(strategyId)
            self._logger.info(f"[UI][{strategyId}]: Delete strategy {strategyId} successfully!")

    def updateValue(self, strategyId, dataDict):
        """更新策略ID对应的运行数据"""

        colValues = {
                       "#9": "{:.2f}".format(dataDict["Available"]),
                       "#10": "{:.2f}".format(dataDict["MaxRetrace"]),
                       "#11": "{:.2f}".format(dataDict["NetProfit"]),
                       "#12": "{:.2f}".format(dataDict["WinRate"])
                   }

        if str(strategyId) in self.executeListTree.get_children():
            for k, v in colValues.items():
                self.executeListTree.set(strategyId, column=k, value=v)

    def updateStatus(self, strategyId, status):
        """更新策略状态"""
        if str(strategyId) in self.executeListTree.get_children():
            self.executeListTree.set(strategyId, column="#6", value=StrategyStatus[status])

    def updatePos(self, positions):
        for itemId in self.posTree.get_children():
            self.posTree.delete(itemId)

        strategyPos = {}
        accountPos  = {}
        strategyAccount = set()
        # 重组策略仓
        for sid in positions["Strategy"]:
            for user in positions["Strategy"][sid]:
                strategyAccount.add(user)

                if user not in strategyPos:
                    strategyPos.update(
                        {
                            #TODO:结构和下面的不一致
                            user: positions["Strategy"][sid][user]
                        }
                    )
                else:
                    for pCont, pInfo in positions["Strategy"][sid][user].items():
                        if pCont not in strategyPos[user]:
                            strategyPos[user].update(
                                {
                                    pCont: pInfo
                                }
                            )
                        else:
                            strategyPos[user][pCont]["TotalBuy"] += pInfo["TotalBuy"]
                            strategyPos[user][pCont]["TotalSell"] += pInfo["TotalSell"]
                            strategyPos[user][pCont]["TodayBuy"] += pInfo["TodayBuy"]
                            strategyPos[user][pCont]["TodaySell"] += pInfo["TodaySell"]
        #print("sssssss: ", strategyPos)

        # 重组账户仓
        for user in positions["Account"]:
            if user not in strategyAccount:
                continue

            if user not in accountPos:
                accountPos[user] = {}

            for pCont, pInfo in positions["Account"][user].items():
                if pCont[-1] == "T":    # 只关注账户中的投机单的持仓
                    if pCont[:-2] not in accountPos[user]:
                        if pCont[-2] == "S":
                            accountPos[user][pCont[:-2]] = {
                                "TotalSell": pInfo["PositionQty"],
                                "TodaySell": pInfo["PositionQty"] - pInfo["PrePositionQty"],
                                "TotalBuy" : 0,
                                "TodayBuy" : 0
                            }
                        else:
                            accountPos[user][pCont[:-2]] = {
                                "TotalBuy" : pInfo["PositionQty"],
                                "TodayBuy" : pInfo["PositionQty"] - pInfo["PrePositionQty"],
                                "TotalSell": 0,
                                "TodaySell": 0
                            }

                    else:
                        if pCont[-2] == "S":
                            accountPos[user][pCont[:-2]]["TotalSell"] += pInfo["PositionQty"]
                            accountPos[user][pCont[:-2]]["TodaySell"] += pInfo["PositionQty"] - pInfo["PrePositionQty"]

                        else:
                            accountPos[user][pCont[:-2]]["TotalBuy"] += pInfo["PositionQty"]
                            accountPos[user][pCont[:-2]]["TodayBuy"] += pInfo["PositionQty"] - pInfo["PrePositionQty"]

        #print("tttttttttt: ", accountPos)

        rlt = []

        for user in strategyAccount:
            for c, p in strategyPos[user].items():

                if user in accountPos:
                    if c in accountPos[user]:
                        aTPos = accountPos[user][c]["TotalBuy"] - (-accountPos[user][c]["TotalSell"]) # 账户仓
                        sTPos = p["TotalBuy"] - (-p["TotalSell"])   # 策略仓
                        posDif = sTPos - aTPos                      # 仓差
                        rlt.append([user, c, aTPos, sTPos, posDif,
                                    p["TotalBuy"], p["TotalSell"], p["TodayBuy"], p["TodaySell"],
                                    accountPos[user][c]["TotalBuy"], accountPos[user][c]["TotalSell"],
                                    accountPos[user][c]["TodayBuy"], accountPos[user][c]["TodaySell"]])
                        continue

                rlt.append([user, c, 0, p["TotalBuy"] - (-p["TotalSell"]), p["TotalBuy"] - (-p["TotalSell"]),
                            p["TotalBuy"], p["TotalSell"], p["TodayBuy"], p["TodaySell"], 0, 0, 0, 0])

        # print("BBBBBBBBBBB: ", rlt)
        for v in rlt:
            self.posTree.insert("", 'end', values=v)
Beispiel #23
0
class FullScreenWindow:
    def __init__(self):
        self.dbManager = DatabaseManager('DBSystem')
        self.btManager = BluetoothManager()
        self.initUi()

    def initUi(self):
        self.tk = Tk()
        self.tk.geometry("480x320")
        self.tk.title(
            "Sistema de Precisión Mixológica para la Preparación de Bebidas Alcohólicas"
        )
        #~ self.tk.attributes("-zoomed", True)#PARA TRABAJAR EN LCD
        self.tk.attributes("-zoomed", False)  #PARA TRABAJAR EN HDMI
        self.tk.attributes("-fullscreen", False)
        self.tk.configure(bg="#eaebf1")
        self.tk.protocol("WM_DELETE_WINDOW", self.btManager.Close)

        #FRAME PRINCIPAL
        self.labelBienvenida = Label(self.tk, text="Bienvenido")
        self.labelBienvenida.configure(bg="#eaebf1")
        self.labelBienvenida.pack()
        self.framePrincipal = Frame(self.tk)
        self.framePrincipal.configure(bg="#eaebf1")
        self.framePrincipal.pack(fill=BOTH, expand=1)

        self.btn1 = Button(self.framePrincipal,
                           text="Admin",
                           command=self.AdminVentana,
                           height=5,
                           width=10)
        self.btn2 = Button(self.framePrincipal,
                           text="User",
                           command=self.UserVentana,
                           height=5,
                           width=10)
        self.btn1.grid(column=0, row=0, padx=80, pady=40)
        self.btn2.grid(column=1, row=0, padx=10, pady=40)
        self.btn1.configure(bg="#f1f0ea")
        self.btn2.configure(bg="#f1f0ea")

        self.state = False
        self.tk.bind("<F11>", self.toggle_fullscreen)
        self.tk.bind("<Escape>", self.end_fullscreen)

        #FRAME USUARIO
        self.diccionarioPedido = {
        }  # { "Nombre de bebida unico" : cantidad de bebida  }

        self.frameUser = Frame(self.tk)
        self.frameUser.configure(bg="#eaebf1")
        self.labelUser = Label(self.tk, text="Realiza tu pedido")
        self.labelUser.configure(bg="#eaebf1")
        self.labelBebidasDisponibles = Label(self.frameUser,
                                             text="Bebidas Disponibles")
        self.labelBebidasDisponibles.grid(row=0, column=0)
        self.labelBebidasDisponibles.configure(bg="#eaebf1")
        self.listboxBebidasDisponibles = Listbox(self.frameUser,
                                                 height=6,
                                                 width=18)
        self.listboxBebidasDisponibles.grid(row=1, column=0)
        self.scrollList = Scrollbar(
            self.frameUser, command=self.listboxBebidasDisponibles.yview)
        self.scrollList.grid(row=1, column=1, sticky="nesw")
        self.listboxBebidasDisponibles.config(
            yscrollcommand=self.scrollList.set)
        self.labelIngredientes = Label(self.frameUser, text="Ingredientes")
        self.labelIngredientes.grid(row=0, column=2)
        self.labelIngredientes.configure(bg="#eaebf1")
        self.listboxIngredientes = Listbox(self.frameUser, height=6, width=15)
        self.listboxIngredientes.grid(row=1, column=2, padx=15)
        self.labelPedido = Label(self.frameUser, text="Pedido")
        self.labelPedido.grid(row=0, column=3, padx=10)
        self.labelPedido.configure(bg="#eaebf1")
        self.listboxPedido = Listbox(self.frameUser, height=6, width=18)
        self.listboxPedido.grid(row=1, column=3)
        self.scrollList = Scrollbar(self.frameUser,
                                    command=self.listboxPedido.yview)
        self.scrollList.grid(row=1, column=4, sticky="nesw")
        self.listboxPedido.config(yscrollcommand=self.scrollList.set)

        self.labelCantidad = Label(self.frameUser, text="Cantidad")
        self.labelCantidad.grid(row=2, column=0)
        self.labelCantidad.configure(bg="#eaebf1")
        self.txtCantidadBebidas = Entry(self.frameUser, width=16)
        self.txtCantidadBebidas.grid(row=3, column=0)
        self.btnAgregar = Button(self.frameUser,
                                 text="Agregar",
                                 height=5,
                                 width=10,
                                 command=self.AgregarBebidaPedido)
        self.btnVolverUser = Button(
            self.frameUser,
            text="Volver",
            height=5,
            width=10,
            command=lambda: self.PrincipalVolver(False))
        self.btnVolverUser.grid(column=3, row=4, pady=10)
        self.btnRealizarPedido = Button(self.frameUser,
                                        text="Realizar Pedido",
                                        height=5,
                                        width=10,
                                        command=self.RealizarPedido)
        self.btnAgregar.grid(column=0, row=4, pady=10)
        self.btnRealizarPedido.grid(column=2, row=4, pady=10)

        self.listboxBebidasDisponibles.bind(
            "<<ListboxSelect>>",
            lambda y: self.VerBebida(self.listboxIngredientes))
        self.listboxPedido.bind("<Double-Button-1>",
                                lambda x: self.EliminarItemPedido())

        #<<ListboxSelect>>

        #FRAME ADMIN

        self.frameAdmin = Frame(self.tk)

        self.labelAdmin = Label(self.tk, text="Admin")
        self.labelAdmin.configure(bg="#eaebf1")

        self.frameAdmin.configure(bg="#eaebf1")

        self.textoVaciadoContenedores = """Vaciado de Contenedores"""

        self.btnContenedores = Button(self.frameAdmin,
                                      text="Contenedores",
                                      command=self.ContenedorVentana,
                                      height=5,
                                      width=10)
        self.btnVaciadoContenedores = Button(
            self.frameAdmin,
            text=self.textoVaciadoContenedores,
            command=self.VaciadoContenedorVentana,
            height=5,
            width=10)
        self.btnRecetas = Button(self.frameAdmin,
                                 text="Recetas",
                                 command=self.RecetasVentana,
                                 height=5,
                                 width=10)
        self.btnContenedores.grid(column=0, row=0, padx=23, pady=40)
        self.btnRecetas.grid(column=1, row=0, padx=23, pady=40)
        self.btnVaciadoContenedores.grid(column=2, row=0, padx=23, pady=40)
        self.btnVolverPrincipal = Button(
            self.frameAdmin,
            text="Volver",
            command=lambda: self.PrincipalVolver(True))
        self.btnVolverPrincipal.grid(column=2, row=1)

        #FRAME RECETA

        self.frameReceta = Frame(self.tk)
        self.listboxRecetasGeneral = Listbox(self.frameReceta)

        self.labelReceta = Label(self.tk, text="Recetas")
        self.labelReceta.configure(bg="#eaebf1")

        self.frameReceta.configure(bg="#eaebf1")

        self.textoBotonEliminarReceta = """Eliminar
        Receta        
        """
        self.textoBotonEditarReceta = """Editar
        Receta        
        """
        self.textoBotonVerReceta = """Ver
        Receta        
        """
        self.textoBotonCrearReceta = """Crear
        Receta        
        """

        self.btnVerReceta = Button(
            self.frameReceta,
            text=self.textoBotonVerReceta,
            command=lambda: self.VerReceta(self.diccionarioListaGeneral[
                self.listboxRecetasGeneral.get(ACTIVE)]),
            height=5,
            width=5)
        self.btnEditarReceta = Button(
            self.frameReceta,
            text=self.textoBotonEditarReceta,
            command=lambda: self.RecetasEditarReceta(
                self.diccionarioListaGeneral[self.listboxRecetasGeneral.get(
                    ACTIVE)]),
            height=5,
            width=5)
        self.btnEliminarReceta = Button(self.frameReceta,
                                        text=self.textoBotonEliminarReceta,
                                        command=self.EliminarReceta,
                                        height=5,
                                        width=5)
        self.btnCrearReceta = Button(self.frameReceta,
                                     text=self.textoBotonCrearReceta,
                                     command=self.RecetasCrearReceta,
                                     height=5,
                                     width=5)
        self.btnVolverAdmin = Button(self.frameReceta,
                                     text="Volver",
                                     command=self.AdminVolver)
        self.btnVerReceta.grid(column=0, row=0, padx=5)
        self.btnEditarReceta.grid(column=1, row=0, padx=5)
        self.btnEliminarReceta.grid(column=2, row=0, padx=5)
        self.btnVolverAdmin.grid(column=3, row=1, pady=10)
        self.btnCrearReceta.grid(column=0, row=1, padx=5)

        self.listboxRecetasGeneral.grid(column=3, row=0)
        self.scrollList = Scrollbar(self.frameReceta,
                                    command=self.listboxRecetasGeneral.yview)
        self.scrollList.grid(column=4, row=0, sticky="nesw")
        self.listboxRecetasGeneral.config(yscrollcommand=self.scrollList.set)

        #~ self.listBox.insert(END,'ELEMENTO1')

        #FRAME RECETA-CREAR

        #Array para llevar la logica para crear la receta que basicamente poseera ingrediente id.ingrediente y cantidad

        self.frameRecetaCrear = Frame(self.tk)
        self.diccionarioIngredientes = {}

        self.labelRecetaCrear = Label(self.tk, text="Crear Receta")
        self.labelRecetaCrear.configure(bg="#eaebf1")

        self.frameRecetaCrear.configure(bg="#eaebf1")

        self.labelIngredientesCrear = Label(self.frameRecetaCrear,
                                            text="Ingredientes")
        self.labelCantidadCrear = Label(self.frameRecetaCrear, text="Cantidad")
        self.labelRecetaActualCrear = Label(self.frameRecetaCrear,
                                            text="Receta Actual")
        self.labelRecetaNombreCrear = Label(self.frameRecetaCrear,
                                            text="Nombre de la Receta")
        self.labelIngredientesCrear.configure(bg="#eaebf1")
        self.labelCantidadCrear.configure(bg="#eaebf1")
        self.labelRecetaActualCrear.configure(bg="#eaebf1")
        self.labelRecetaNombreCrear.configure(bg="#eaebf1")

        self.labelIngredientesCrear.grid(row=0, column=0, padx=5)
        self.labelCantidadCrear.grid(row=0, column=1)
        self.labelRecetaActualCrear.grid(row=0, column=2)
        self.labelRecetaNombreCrear.grid(row=2, column=0)

        self.comboIngredientesCrear = ttk.Combobox(self.frameRecetaCrear,
                                                   width=16,
                                                   state="readonly")
        self.comboIngredientesCrear.grid(row=1, column=0, padx=2, sticky=N)

        self.vcmd = (self.tk.register(self.validate), '%d', '%i', '%P', '%s',
                     '%S', '%v', '%V', '%W')

        self.txtCantidadCrear = Entry(self.frameRecetaCrear,
                                      width=16,
                                      validate='key',
                                      validatecommand=self.vcmd)
        self.txtRecetaNombreCrear = Entry(self.frameRecetaCrear, width=16)
        self.txtCantidadCrear.grid(row=1, column=1, padx=2, sticky=N)
        self.txtRecetaNombreCrear.grid(row=3, column=0)
        self.txtCantidadCrear.bind("<FocusIn>", lambda x: self.AbrirTeclado())
        self.txtRecetaNombreCrear.bind("<FocusIn>",
                                       lambda x: self.AbrirTeclado())

        self.listBoxRecetaActualCrear = Listbox(self.frameRecetaCrear,
                                                height=6)
        self.listBoxRecetaActualCrear.grid(row=1, column=2)

        #~ self.listBoxRecetaActualCrear.bind("<Double-Button-1>", lambda: self.EliminarItemListbox(self.listBoxRecetaActualCrear))
        self.listBoxRecetaActualCrear.bind(
            "<Double-Button-1>",
            lambda x: self.EliminarItemListbox(self.listBoxRecetaActualCrear))
        #~ command=lambda:self.clicked('Eliminar \n' + 'Receta')
        self.btnVolverRecetaCrear = Button(
            self.frameRecetaCrear,
            text="Volver",
            command=lambda: self.RecetasVolver(1))
        self.btnVolverRecetaCrear.grid(row=4, column=2)
        #BOTON AGREGAR ------------------------------------------------------------
        self.btnAgregarRecetaCrear = Button(
            self.frameRecetaCrear,
            text="Agregar",
            command=lambda: self.AgregarIngrediente(
                self.comboIngredientesCrear.get(), self.txtCantidadCrear.get(),
                self.listBoxRecetaActualCrear))
        self.btnAgregarRecetaCrear.grid(row=4, column=1)
        #BOTON CREAR -------------------------------------------------------------------
        self.btnCrearRecetaCrear = Button(self.frameRecetaCrear,
                                          text="Crear Receta",
                                          command=self.CrearReceta,
                                          width=55)
        self.btnCrearRecetaCrear.grid(row=5, column=0, columnspan=3, pady=8)

        #FRAME RECETA-EDITAR

        #Array para llevar la logica para crear la receta que basicamente poseera ingrediente id.ingrediente y cantidad

        self.frameRecetaEditar = Frame(self.tk)

        self.labelRecetaEditar = Label(self.tk, text="Editar Receta")
        self.labelRecetaEditar.configure(bg="#eaebf1")

        self.frameRecetaEditar.configure(bg="#eaebf1")

        self.labelIngredientesEditar = Label(self.frameRecetaEditar,
                                             text="Ingredientes")
        self.labelCantidadEditar = Label(self.frameRecetaEditar,
                                         text="Cantidad")
        self.labelRecetaActualEditar = Label(self.frameRecetaEditar,
                                             text="Receta Actual")
        self.labelRecetaNombreEditar = Label(self.frameRecetaEditar,
                                             text="Nombre de la Receta")
        self.labelIngredientesEditar.configure(bg="#eaebf1")
        self.labelCantidadEditar.configure(bg="#eaebf1")
        self.labelRecetaActualEditar.configure(bg="#eaebf1")
        self.labelRecetaNombreEditar.configure(bg="#eaebf1")

        self.labelIngredientesEditar.grid(row=0, column=0, padx=5)
        self.labelCantidadEditar.grid(row=0, column=1)
        self.labelRecetaActualEditar.grid(row=0, column=2)
        self.labelRecetaNombreEditar.grid(row=2, column=0)

        self.comboIngredientesEditar = ttk.Combobox(self.frameRecetaEditar,
                                                    width=16,
                                                    state="readonly")
        self.comboIngredientesEditar.grid(row=1, column=0, padx=2, sticky=N)

        self.txtCantidadEditar = Entry(self.frameRecetaEditar,
                                       width=16,
                                       validate='key',
                                       validatecommand=self.vcmd)
        self.txtRecetaNombreEditar = Entry(self.frameRecetaEditar, width=16)
        self.txtCantidadEditar.grid(row=1, column=1, padx=2, sticky=N)
        self.txtRecetaNombreEditar.grid(row=3, column=0)

        self.listBoxRecetaActualEditar = Listbox(self.frameRecetaEditar,
                                                 height=6)
        self.listBoxRecetaActualEditar.grid(row=1, column=2)

        self.btnVolverRecetaEditar = Button(
            self.frameRecetaEditar,
            text="Volver",
            command=lambda: self.RecetasVolver(2))
        self.btnVolverRecetaEditar.grid(row=4, column=2)

        self.listBoxRecetaActualEditar.bind(
            "<Double-Button-1>",
            lambda x: self.EliminarItemListbox(self.listBoxRecetaActualEditar))
        #BOTON AGREGAR ------------------------------------------------------------
        self.btnAgregarRecetaEditar = Button(
            self.frameRecetaEditar,
            text="Agregar",
            command=lambda: self.AgregarIngrediente(
                self.comboIngredientesEditar.get(), self.txtCantidadEditar.get(
                ), self.listBoxRecetaActualEditar))
        self.btnAgregarRecetaEditar.grid(row=4, column=1)
        #BOTON CREAR -------------------------------------------------------------------
        self.btnEditarRecetaEditar = Button(self.frameRecetaEditar,
                                            text="Editar Receta",
                                            command=self.EditarReceta,
                                            width=55)
        self.btnEditarRecetaEditar.grid(row=5, column=0, columnspan=3, pady=8)

        #FRAME RECETA-VER

        self.textoLabelVer = StringVar()

        self.frameRecetaVer = Frame(self.tk)
        self.labelRecetaVer = Label(self.tk, text="Ver Receta")
        self.labelRecetaVer.configure(bg="#eaebf1")
        self.frameRecetaVer.configure(bg="#eaebf1")
        self.labelNombreReceta = Label(self.frameRecetaVer,
                                       text="Nombre de la Receta:",
                                       anchor="center")
        self.labelNombreReceta.grid(row=0, column=0, padx=30)
        self.labelNombreRecetaReal = Label(self.frameRecetaVer,
                                           text="aqui se ve el nombre",
                                           textvariable=self.textoLabelVer,
                                           height=15,
                                           wraplength=150,
                                           padx=20)
        self.labelNombreRecetaReal.grid(row=1, column=0, padx=30)
        self.labelIngredientesVer = Label(self.frameRecetaVer,
                                          text="Ingredientes")
        self.labelIngredientesVer.grid(row=0, column=3, padx=55, columnspan=2)
        self.listBoxRecetaVer = Listbox(self.frameRecetaVer, height=6)
        self.listBoxRecetaVer.grid(row=1,
                                   column=3,
                                   sticky="e",
                                   columnspan=2,
                                   padx=55)
        self.labelNombreReceta.configure(bg="#eaebf1")
        self.labelNombreRecetaReal.configure(bg="#eaebf1")
        self.labelIngredientesVer.configure(bg="#eaebf1")
        self.btnVolverRecetaVer = Button(self.frameRecetaVer,
                                         text="Volver",
                                         command=lambda: self.RecetasVolver(3))
        self.btnVolverRecetaVer.grid(row=4, column=4)

        #FRAME CONTENEDOR

        self.contenedor1Nombre = StringVar()
        self.contenedor2Nombre = StringVar()
        self.contenedor3Nombre = StringVar()
        self.contenedor4Nombre = StringVar()
        self.contenedor5Nombre = StringVar()
        self.contenedor6Nombre = StringVar()

        self.frameContenedor = Frame(self.tk)
        self.labelContenedor1 = Label(self.frameContenedor,
                                      text="Contenedor 1")
        self.labelContenedor1.grid(column=0, row=1)
        self.labelContenedor2 = Label(self.frameContenedor,
                                      text="Contenedor 2")
        self.labelContenedor2.grid(column=0, row=2)
        self.labelContenedor3 = Label(self.frameContenedor,
                                      text="Contenedor 3")
        self.labelContenedor3.grid(column=0, row=3)
        self.labelContenedor4 = Label(self.frameContenedor,
                                      text="Contenedor 4")
        self.labelContenedor4.grid(column=0, row=4)
        self.labelContenedor5 = Label(self.frameContenedor,
                                      text="Contenedor 5")
        self.labelContenedor5.grid(column=0, row=5)
        self.labelContenedor6 = Label(self.frameContenedor,
                                      text="Contenedor 6")
        self.labelContenedor6.grid(column=0, row=6)
        self.TextBoxContenedor1 = Entry(self.frameContenedor,
                                        textvariable=self.contenedor1Nombre)
        self.TextBoxContenedor1.grid(column=1, row=1)
        self.TextBoxContenedor2 = Entry(self.frameContenedor,
                                        textvariable=self.contenedor2Nombre)
        self.TextBoxContenedor2.grid(column=1, row=2)
        self.TextBoxContenedor3 = Entry(self.frameContenedor,
                                        textvariable=self.contenedor3Nombre)
        self.TextBoxContenedor3.grid(column=1, row=3)
        self.TextBoxContenedor4 = Entry(self.frameContenedor,
                                        textvariable=self.contenedor4Nombre)
        self.TextBoxContenedor4.grid(column=1, row=4)
        self.TextBoxContenedor5 = Entry(self.frameContenedor,
                                        textvariable=self.contenedor5Nombre)
        self.TextBoxContenedor5.grid(column=1, row=5)
        self.TextBoxContenedor6 = Entry(self.frameContenedor,
                                        textvariable=self.contenedor6Nombre)
        self.TextBoxContenedor6.grid(column=1, row=6)
        self.btn4 = Button(self.frameContenedor,
                           text="Guardar Cambios",
                           command=self.ActualizarContenedores)
        self.btn4.grid(column=2, row=7)
        self.btn3 = Button(self.frameContenedor,
                           text="Volver",
                           command=self.AdminVolver)
        self.btn3.grid(column=2, row=0)
        self.TextBoxContenedor1.bind("<FocusIn>",
                                     lambda x: self.AbrirTeclado())
        self.TextBoxContenedor2.bind("<FocusIn>",
                                     lambda x: self.AbrirTeclado())
        self.TextBoxContenedor3.bind("<FocusIn>",
                                     lambda x: self.AbrirTeclado())
        self.TextBoxContenedor4.bind("<FocusIn>",
                                     lambda x: self.AbrirTeclado())
        self.TextBoxContenedor5.bind("<FocusIn>",
                                     lambda x: self.AbrirTeclado())
        self.TextBoxContenedor6.bind("<FocusIn>",
                                     lambda x: self.AbrirTeclado())
        #~ self.hilo1.terminate()

        #FRAME VACIADO CONTENEDOR
        self.frameVaciadoContenedor = Frame(self.tk)
        self.labelVaciadoContenedor1 = Label(self.frameVaciadoContenedor,
                                             text="Contenedor 1")
        self.labelVaciadoContenedor1.grid(column=0, row=1)
        self.labelVaciadoContenedor2 = Label(self.frameVaciadoContenedor,
                                             text="Contenedor 2")
        self.labelVaciadoContenedor2.grid(column=0, row=2)
        self.labelVaciadoContenedor3 = Label(self.frameVaciadoContenedor,
                                             text="Contenedor 3")
        self.labelVaciadoContenedor3.grid(column=0, row=3)
        self.labelVaciadoContenedor4 = Label(self.frameVaciadoContenedor,
                                             text="Contenedor 4")
        self.labelVaciadoContenedor4.grid(column=0, row=4)
        self.labelVaciadoContenedor5 = Label(self.frameVaciadoContenedor,
                                             text="Contenedor 5")
        self.labelVaciadoContenedor5.grid(column=0, row=5)
        self.labelVaciadoContenedor6 = Label(self.frameVaciadoContenedor,
                                             text="Contenedor 6")
        self.labelVaciadoContenedor6.grid(column=0, row=6)
        self.btnVolverVaciado = Button(self.frameVaciadoContenedor,
                                       text="Volver",
                                       command=self.AdminVolver)
        self.btnVolverVaciado.grid(column=2, row=0)
        self.TextBoxVaciadoContenedor1 = Entry(self.frameVaciadoContenedor)
        self.TextBoxVaciadoContenedor1.grid(column=1, row=1)
        self.TextBoxVaciadoContenedor2 = Entry(self.frameVaciadoContenedor)
        self.TextBoxVaciadoContenedor2.grid(column=1, row=2)
        self.TextBoxVaciadoContenedor3 = Entry(self.frameVaciadoContenedor)
        self.TextBoxVaciadoContenedor3.grid(column=1, row=3)
        self.TextBoxVaciadoContenedor4 = Entry(self.frameVaciadoContenedor)
        self.TextBoxVaciadoContenedor4.grid(column=1, row=4)
        self.TextBoxVaciadoContenedor5 = Entry(self.frameVaciadoContenedor)
        self.TextBoxVaciadoContenedor5.grid(column=1, row=5)
        self.TextBoxVaciadoContenedor6 = Entry(self.frameVaciadoContenedor)
        self.TextBoxVaciadoContenedor6.grid(column=1, row=6)

        self.rbOpcionVaciado = IntVar()

        self.rbContenedor1 = Radiobutton(self.frameVaciadoContenedor,
                                         text="         ",
                                         variable=self.rbOpcionVaciado,
                                         value=1,
                                         command=self.MostarV,
                                         indicatoron=False)
        self.rbContenedor2 = Radiobutton(self.frameVaciadoContenedor,
                                         text="         ",
                                         variable=self.rbOpcionVaciado,
                                         value=2,
                                         command=self.MostarV,
                                         indicatoron=False)
        self.rbContenedor3 = Radiobutton(self.frameVaciadoContenedor,
                                         text="         ",
                                         variable=self.rbOpcionVaciado,
                                         value=3,
                                         command=self.MostarV,
                                         indicatoron=False)
        self.rbContenedor4 = Radiobutton(self.frameVaciadoContenedor,
                                         text="         ",
                                         variable=self.rbOpcionVaciado,
                                         value=4,
                                         command=self.MostarV,
                                         indicatoron=False)
        self.rbContenedor5 = Radiobutton(self.frameVaciadoContenedor,
                                         text="         ",
                                         variable=self.rbOpcionVaciado,
                                         value=5,
                                         command=self.MostarV,
                                         indicatoron=False)
        self.rbContenedor6 = Radiobutton(self.frameVaciadoContenedor,
                                         text="         ",
                                         variable=self.rbOpcionVaciado,
                                         value=6,
                                         command=self.MostarV,
                                         indicatoron=False)
        self.rbContenedor1.grid(column=2, row=1)
        self.rbContenedor2.grid(column=2, row=2)
        self.rbContenedor3.grid(column=2, row=3)
        self.rbContenedor4.grid(column=2, row=4)
        self.rbContenedor5.grid(column=2, row=5)
        self.rbContenedor6.grid(column=2, row=6)

        self.btnVaciado = Button(self.frameVaciadoContenedor,
                                 text="Vaciar",
                                 command=self.AdminVolver,
                                 height=5,
                                 width=10)
        self.btnVaciado.grid(column=3, row=7)

        self.labelContenedor1ml = Label(self.frameVaciadoContenedor,
                                        text="1200 ml")
        self.labelContenedor1ml.grid(column=3, row=1)
        self.labelContenedor2ml = Label(self.frameVaciadoContenedor,
                                        text="1200 ml")
        self.labelContenedor2ml.grid(column=3, row=2)
        self.labelContenedor3ml = Label(self.frameVaciadoContenedor,
                                        text="1200 ml")
        self.labelContenedor3ml.grid(column=3, row=3)
        self.labelContenedor4ml = Label(self.frameVaciadoContenedor,
                                        text="1200 ml")
        self.labelContenedor4ml.grid(column=3, row=4)
        self.labelContenedor5ml = Label(self.frameVaciadoContenedor,
                                        text="1200 ml")
        self.labelContenedor5ml.grid(column=3, row=5)
        self.labelContenedor6ml = Label(self.frameVaciadoContenedor,
                                        text="1200 ml")
        self.labelContenedor6ml.grid(column=3, row=6)

    def TecladoVirtual(self):
        self.hiloVentana = subprocess.call("/usr/bin/matchbox-keyboard",
                                           shell=False)

    def MostrarXs(self, segs=5):
        while True:
            sleep(segs)
            print("Han pasado %d segundos" % segs)

    def AbrirTeclado(self, event=None):
        self.hilo1 = threading.Thread(target=self.TecladoVirtual)
        self.hilo1.start()

    def clicked(self, t):
        self.admin = Toplevel(self.tk)
        self.admin.title(t)
        print(t)

    def AdminVentana(self):
        self.labelBienvenida.pack_forget()
        self.framePrincipal.pack_forget()
        self.labelAdmin.pack()
        self.frameAdmin.pack(fill=BOTH, expand=1)

    def UserVentana(self):
        self.LogicaListaGeneral(self.listboxBebidasDisponibles)
        self.labelBienvenida.pack_forget()
        self.framePrincipal.pack_forget()

        self.labelUser.pack()
        self.frameUser.pack(fill=BOTH, expand=1)

        self.listboxIngredientes.delete(0, END)
        receta = self.listboxBebidasDisponibles.get(ACTIVE)
        id = self.diccionarioListaGeneral[receta]
        temp = self.dbManager.VerReceta(id)
        for nombre, cantidad, caracterEspecial in temp["Ingredientes"]:
            self.diccionarioIngredientes[nombre] = cantidad
        self.MostrarIngredientes(self.listboxIngredientes)
        self.diccionarioIngredientes = {}

    def LogicaListaGeneral(self, lista):
        self.listboxRecetasGeneral.delete(0, 'end')
        self.diccionarioListaGeneral = self.dbManager.ObtenerRecetas()
        print(self.diccionarioListaGeneral)
        for i in self.diccionarioListaGeneral:
            lista.insert(END, i)

    def RecetasVentana(self):
        self.LogicaListaGeneral(self.listboxRecetasGeneral)
        self.labelAdmin.pack_forget()
        self.frameAdmin.pack_forget()
        self.labelReceta.pack()
        self.frameReceta.pack()
        #Se nos paso colocar fill=BOTH,expand=1
        #por lo tanto este frame no sigue los estandares de diseño del resto

    def RecetasCrearReceta(self):
        self.labelReceta.pack_forget()
        self.frameReceta.pack_forget()
        self.labelRecetaCrear.pack()
        self.frameRecetaCrear.pack(fill=BOTH, expand=1)
        ingredientes = self.dbManager.ObtenerIngredientes()
        self.diccionarioIngredientesCrear = {
            ingredientes[0][1]: ingredientes[0][0],
            ingredientes[1][1]: ingredientes[1][0],
            ingredientes[2][1]: ingredientes[2][0],
            ingredientes[3][1]: ingredientes[3][0],
            ingredientes[4][1]: ingredientes[4][0],
            ingredientes[5][1]: ingredientes[5][0]
        }
        print(self.diccionarioIngredientesCrear)
        print("##### Arriba self.diccionarioIngredientesCrear #####")
        self.comboIngredientesCrear['values'] = (ingredientes[0][1],
                                                 ingredientes[1][1],
                                                 ingredientes[2][1],
                                                 ingredientes[3][1],
                                                 ingredientes[4][1],
                                                 ingredientes[5][1])
        self.comboIngredientesCrear.current(0)

    def RecetasEditarReceta(self, id):
        self.RecetaId = id
        temp = self.dbManager.VerReceta(id)
        #~ self.diccionarioIngredientes
        self.txtRecetaNombreEditar.delete(0, END)
        self.txtRecetaNombreEditar.insert(0, temp["Receta"])
        for nombre, cantidad, caracter in temp["Ingredientes"]:
            self.diccionarioIngredientes[nombre] = cantidad
        self.MostrarIngredientes(self.listBoxRecetaActualEditar)
        print(self.diccionarioIngredientes)
        self.labelReceta.pack_forget()
        self.frameReceta.pack_forget()
        self.labelRecetaEditar.pack()
        self.frameRecetaEditar.pack(fill=BOTH, expand=1)
        ingredientes = self.dbManager.ObtenerIngredientes()
        self.diccionarioIngredientesCrear = {
            ingredientes[0][1]: ingredientes[0][0],
            ingredientes[1][1]: ingredientes[1][0],
            ingredientes[2][1]: ingredientes[2][0],
            ingredientes[3][1]: ingredientes[3][0],
            ingredientes[4][1]: ingredientes[4][0],
            ingredientes[5][1]: ingredientes[5][0]
        }
        self.comboIngredientesEditar['values'] = (ingredientes[0][1],
                                                  ingredientes[1][1],
                                                  ingredientes[2][1],
                                                  ingredientes[3][1],
                                                  ingredientes[4][1],
                                                  ingredientes[5][1])
        self.comboIngredientesEditar.current(0)

    def VaciadoContenedorVentana(self):
        self.labelBienvenida.pack_forget()
        self.frameAdmin.pack_forget()
        self.labelAdmin.pack_forget()
        self.frameVaciadoContenedor.pack(fill=BOTH, expand=1)
        ingredientes = self.dbManager.ObtenerIngredientes()
        #~ self.comboIngredientesCrear['values'] = (ingredientes[0][1],ingredientes[1][1],ingredientes[2][1],ingredientes[3][1],ingredientes[4][1],ingredientes[5][1])
        self.labelVaciadoContenedor1['text'] = ingredientes[0][1]
        self.labelVaciadoContenedor2['text'] = ingredientes[1][1]
        self.labelVaciadoContenedor3['text'] = ingredientes[2][1]
        self.labelVaciadoContenedor4['text'] = ingredientes[3][1]
        self.labelVaciadoContenedor5['text'] = ingredientes[4][1]
        self.labelVaciadoContenedor6['text'] = ingredientes[5][1]

    def ContenedorVentana(self):
        self.labelBienvenida.pack_forget()
        contenedores = self.dbManager.Select('Contenedores')
        print(contenedores)
        self.contenedor1Nombre.set(contenedores[0][1])
        self.contenedor2Nombre.set(contenedores[1][1])
        self.contenedor3Nombre.set(contenedores[2][1])
        self.contenedor4Nombre.set(contenedores[3][1])
        self.contenedor5Nombre.set(contenedores[4][1])
        self.contenedor6Nombre.set(contenedores[5][1])
        self.frameAdmin.pack_forget()
        self.labelAdmin.pack_forget()
        self.frameContenedor.pack(fill=BOTH, expand=1)

    def VerReceta(self, id):
        temp = self.dbManager.VerReceta(id)
        for nombre, cantidad, caracter in temp["Ingredientes"]:
            self.diccionarioIngredientes[nombre] = cantidad
        self.MostrarIngredientes(self.listBoxRecetaVer)
        self.textoLabelVer.set(temp["Receta"])
        self.labelReceta.pack_forget()
        self.frameReceta.pack_forget()
        self.labelRecetaVer.pack()
        self.frameRecetaVer.pack(fill=BOTH, expand=1)

    #CRUD RECETAS
    def EliminarItemListbox(self, lista):
        texto = lista.get(ACTIVE)
        busqueda = texto.find(" " + chr(0), 0, len(texto))
        key = texto[:busqueda]
        del self.diccionarioIngredientes[key]
        print(self.diccionarioIngredientes)
        lista.delete(ACTIVE)

    def EliminarReceta(self):
        receta = self.listboxRecetasGeneral.get(ACTIVE)
        id = self.diccionarioListaGeneral[receta]
        self.dbManager.EliminarReceta(id)
        self.diccionarioListaGeneral = {}
        self.LogicaListaGeneral(self.listboxRecetasGeneral)

    def VerBebida(self, lista):
        lista.delete(0, END)
        receta = self.listboxBebidasDisponibles.get(ACTIVE)
        id = self.diccionarioListaGeneral[receta]
        temp = self.dbManager.VerReceta(id)
        for nombre, cantidad, k in temp["Ingredientes"]:
            self.diccionarioIngredientes[nombre] = cantidad
        self.MostrarIngredientes(lista)
        self.diccionarioIngredientes = {}
        return

    def MostrarIngredientes(self, lista):
        lista.delete(0, 'end')
        for i in self.diccionarioIngredientes:
            ingredientecantidad = i + " " + chr(0) + " " + str(
                self.diccionarioIngredientes[i])
            print(ingredientecantidad)
            lista.insert('end', ingredientecantidad)

    def AgregarIngrediente(self, ingrediente, cantidad, lista):
        if len(cantidad) == 0:
            return
        self.diccionarioIngredientes[ingrediente] = cantidad
        print(self.diccionarioIngredientes)
        print("Arriba se mostro diccionarioIngredientes")
        self.MostrarIngredientes(lista)

    def EditarReceta(self):
        if len(self.diccionarioIngredientes) == 0:
            messagebox.showerror(
                "Error", "No se puede crear una receta sin ingredientes.")
            return False
        if len(self.txtRecetaNombreEditar.get()) == 0:
            messagebox.showerror(
                "Error",
                "Debe ingresar el nombre de la receta antes de continuar.")
            return False
        if self.dbManager.VerificarNombreEditar(
                self.RecetaId, self.txtRecetaNombreEditar.get()) == False:
            messagebox.showerror("Error",
                                 "Ya existe una receta con ese nombre.")
            return False
        self.dbManager.ActualizarNombreReceta(self.txtRecetaNombreEditar.get(),
                                              self.RecetaId)
        self.dbManager.EliminarTodosIngredientes(self.RecetaId)

        dicc = {}  #DICCIONARIO PARA AGREGAR LOS INGREDIENTES DE LA RECETA
        print(self.diccionarioIngredientesCrear)
        print("##############################")
        for i in self.diccionarioIngredientes:  #CICLO PARA RELLENAR DICCIONARIO
            print(i)
            print("########################")
            dicc[self.diccionarioIngredientesCrear[
                i]] = self.diccionarioIngredientes[i]
        print(dicc)
        print("Arriba impreso dicc")
        self.dbManager.AgregarIngrediente(dicc, self.RecetaId)
        messagebox.showinfo(
            "Tarea Realizada",
            "La receta %s ha sido actualizada correctamente." %
            self.txtRecetaNombreEditar.get())
        self.diccionarioIngredientes = {}
        self.txtCantidadEditar.config(validate="none")
        self.txtCantidadEditar.delete(0, END)
        self.txtRecetaNombreEditar.delete(0, END)
        self.listBoxRecetaActualEditar.delete(0, 'end')
        self.txtCantidadEditar.config(validate='key')
        self.RecetasVolver(2)
        return

    def CrearReceta(self):
        if len(self.diccionarioIngredientes) == 0:
            messagebox.showerror(
                "Error", "No se puede crear una receta sin ingredientes.")
            return False
        if len(self.txtRecetaNombreCrear.get()) == 0:
            messagebox.showerror(
                "Error",
                "Debe ingresar el nombre de la receta antes de continuar.")
            return False
        recetaId = self.dbManager.CrearReceta(
            self.txtRecetaNombreCrear.get())  #CREAMOS LA RECETA
        if recetaId == False:
            messagebox.showerror("Error",
                                 "Ya existe una receta con ese nombre.")
            return False
        dic = {}  #DICCIONARIO PARA AGREGAR LOS INGREDIENTES DE LA RECETA

        for i in self.diccionarioIngredientes:  #CICLO PARA RELLENAR DICCIONARIO
            dic[self.diccionarioIngredientesCrear[
                i]] = self.diccionarioIngredientes[i]
        print(dic)
        print("Arriba impreso dic")
        self.dbManager.AgregarIngrediente(dic, recetaId)
        #~ self.diccionarioIngredientesCrear
        messagebox.showinfo(
            "Tarea Realizada", "La receta %s ha sido creada correctamente." %
            self.txtRecetaNombreCrear.get())
        self.diccionarioIngredientes = {}
        self.txtCantidadCrear.config(validate="none")
        self.txtCantidadCrear.delete(0, END)
        self.txtRecetaNombreCrear.delete(0, END)
        self.listBoxRecetaActualCrear.delete(0, 'end')
        self.txtCantidadCrear.config(validate='key')
        self.RecetasVolver(True)

    def RecetasVolver(self, i):
        self.LogicaListaGeneral(self.listboxRecetasGeneral)
        self.diccionarioIngredientes = {}
        if i == 1:
            self.labelRecetaCrear.pack_forget()
            self.frameRecetaCrear.pack_forget()
        elif i == 2:
            self.labelRecetaEditar.pack_forget()
            self.frameRecetaEditar.pack_forget()
        else:
            self.labelRecetaVer.pack_forget()
            self.frameRecetaVer.pack_forget()
        self.labelReceta.pack()
        self.frameReceta.pack(fill=BOTH, expand=1)

    def AdminVolver(self):
        self.frameContenedor.pack_forget()
        self.frameReceta.pack_forget()
        self.frameVaciadoContenedor.pack_forget()
        #~ self.frameVaciadoContenedor.pack_forget()
        self.labelReceta.pack_forget()

        self.labelAdmin.pack()

        self.frameAdmin.pack(fill=BOTH, expand=1)

    #~ def AdminVolverVaciado(self):
    #~ self.frameContenedor.pack_forget()
    #~ self.frameReceta.pack_forget()
    #~ self.labelReceta.pack_forget()

    #~ self.labelAdmin.pack()
    #~ self.frameAdmin.pack(fill=BOTH,expand=1)

    def PrincipalVolver(self, isAdmin):
        if isAdmin:
            self.frameAdmin.pack_forget()
            self.labelAdmin.pack_forget()
        else:
            self.frameUser.pack_forget()
            self.labelUser.pack_forget()
        self.labelBienvenida.pack()
        self.framePrincipal.pack(fill=BOTH, expand=1)

    def ActualizarContenedores(self):

        contenedores = [
            self.contenedor1Nombre.get(),
            self.contenedor2Nombre.get(),
            self.contenedor3Nombre.get(),
            self.contenedor4Nombre.get(),
            self.contenedor5Nombre.get(),
            self.contenedor6Nombre.get()
        ]
        print(len(contenedores))
        print(len(set(contenedores)))
        if (len(contenedores) == len(set(contenedores))):
            self.dbManager.ActualizarContenedores(contenedores)
        else:
            print("iguales")
            messagebox.showerror(
                "Error",
                "NO pueden existir dos ingredientes con el mismo nombre")
            return

    def MostarV(self):
        print(self.rbOpcionVaciado.get())

    def RealizarPedido(self):
        print("Entramos en REALIZAR PEDIDO")
        trama = "" + chr(1)  #Inicio de trama 3
        print(self.diccionarioPedido)
        for NombreReceta in self.diccionarioPedido.keys():
            print("Iniciamos primer for")
            id = self.diccionarioListaGeneral[NombreReceta]
            receta = self.dbManager.VerReceta(id)
            for contenedor, cant, caracter in receta["Ingredientes"]:
                #~ el separador entre contenedor y cantidad viene siendo donde esta chr(0)
                print("Muestro caracter")
                print(caracter)
                trama += caracter + chr(29) + str(cant) + chr(29)
            trama += chr(7) + str(self.diccionarioPedido[NombreReceta]) + chr(
                8)  #Aqui agregamos final de receta 1
        trama += chr(4)  # fin de transmision 2
        print(trama)
        self.btManager.Send(trama)
        #~ self.diccionarioPedido {Nombre receta : cantidad}
        #~ self.diccionarioListaGeneral {Nombre receta : id}

    def AgregarBebidaPedido(self):
        self.diccionarioPedido[self.listboxBebidasDisponibles.get(
            ACTIVE)] = self.txtCantidadBebidas.get()
        print(self.diccionarioPedido)
        print(self.txtCantidadBebidas.get())
        #~ self.listboxPedido.delete(0,'end')
        self.listboxPedido.delete(0, END)
        for i in self.diccionarioPedido:
            print(i)
            self.listboxPedido.insert(
                END, i + " " + chr(0) + " " + self.diccionarioPedido[i])
        return

    def EliminarItemPedido(self):
        texto = self.listboxPedido.get(ACTIVE)
        busqueda = texto.find(" " + chr(0), 0, len(texto))
        key = texto[:busqueda]
        del self.diccionarioPedido[key]
        self.listboxPedido.delete(ACTIVE)
        return

    def validate(self, action, index, value_if_allowed, prior_value, text,
                 validation_type, trigger_type, widget_name):
        if text in '0123456789.-+':
            try:
                float(value_if_allowed)
                return True
            except ValueError:
                return False
        else:
            return False

    def toggle_fullscreen(self, event=None):
        self.state = not self.state
        self.tk.attributes("-fullscreen", self.state)
        return "break"

    def end_fullscreen(self, event=None):
        self.state = False
        self.tk.attributes("-fullscreen", False)
        return "break"
Beispiel #24
0
class ipGUI:
    def __init__(self, master):
        self.master = master
        self.master.minsize(width=800, height=600)

        menu = Menu(self.master)
        master.config(menu=menu)

        # ***** Main Menu *****
        # *** file menu ***
        fileMenu = Menu(menu)
        menu.add_cascade(label='File', menu=fileMenu)
        fileMenu.add_command(label="Open", command=self.openImage)
        fileMenu.add_command(label="Load Blur Kernel", command=self.loadKernel)
        fileMenu.add_command(label="Save", command=self.saveImage)
        fileMenu.add_command(label="Exit", command=master.destroy)

        # *** edit menu ***
        editMenu = Menu(menu)
        menu.add_cascade(label='Space', menu=editMenu)
        editMenu.add_command(label="Histogram Equalization",
                             command=self.histWrap)
        editMenu.add_command(label="Gamma Correction",
                             command=self.gammaCorWrap)
        editMenu.add_command(label="Log Transform", command=self.logTranWrap)
        editMenu.add_command(label="Sharpen", command=self.sharpWrap)
        editMenu.add_command(label="Cartoonify", command=self.cartoonifyWrap)

        # *** blur menu ***
        blurMenu = Menu(editMenu)
        editMenu.add_cascade(label='Blur', menu=blurMenu)
        blurMenu.add_command(label="Box", command=self.boxBlurWrap)
        blurMenu.add_command(label="Gaussian", command=self.gaussianBlurWrap)
        blurMenu.add_command(label="Median", command=self.medianBlurWrap)

        # *** frequency filtering ***
        freqMenu = Menu(menu)
        menu.add_cascade(label='Frequency', menu=freqMenu)
        freqMenu.add_command(label="DFT", command=self.dftWrap)
        freqMenu.add_command(label="Load Mask", command=self.freqMaskWrap)

        # *** Mask Menu ***
        maskMenu = Menu(freqMenu)
        freqMenu.add_cascade(label='Create Mask', menu=maskMenu)
        maskMenu.add_command(label='Low Pass', command=self.lpmWrap)
        maskMenu.add_command(label='High Pass', command=self.hpmWrap)
        maskMenu.add_command(label='Band Pass', command=self.bppmWrap)
        maskMenu.add_command(label='Band Stop', command=self.bspmWrap)

        # *** frequency filtering ***
        restorationMenu = Menu(menu)
        menu.add_cascade(label='Restoration', menu=restorationMenu)
        restorationMenu.add_command(label="Full Inverse",
                                    command=self.fullInverseWrap)
        restorationMenu.add_command(label="Radially Limited Inverse",
                                    command=self.truncatedInverseWrap)
        restorationMenu.add_command(label="Approximate Weiner",
                                    command=self.approximateWeinerWrap)
        restorationMenu.add_command(label="Constrained LS",
                                    command=self.contrainedLSWrap)

        # ***** Toolbar *****
        toolbar = Frame(master, bg="grey")
        undoButton = Button(toolbar, text="Undo", command=self.undoFunc)
        undoButton.pack(side=LEFT)
        origButton = Button(toolbar, text="Original", command=self.origFunc)
        origButton.pack(side=LEFT)
        toolbar.pack(side=TOP, fill=X)

        # ***** Image Display Area *****
        self.frame = Frame(self.master)
        self.frame.pack()
        self.panel = Label(self.frame)
        self.panel.pack(padx=10, pady=10)
        self.img = None
        self.origImg = None
        self.prevImg = None

        # ***** Gamma Controls *****
        self.gammaFrame = Frame(self.master)
        self.gammaSlider = Scale(self.gammaFrame,
                                 from_=0.1,
                                 to=2,
                                 orient=HORIZONTAL,
                                 resolution=0.1)
        self.gammaSlider.pack(side=TOP)
        self.gammaExitButton = Button(self.gammaFrame,
                                      text="Exit",
                                      command=self.gammaFrame.pack_forget)
        self.gammaExitButton.pack(side=TOP)

        # ***** Box Blur Controls *****
        self.boxFrame = Frame(self.master)
        self.boxSlider = Scale(self.boxFrame, from_=1, to=5, orient=HORIZONTAL)
        self.boxSlider.pack(side=TOP)
        self.boxExitButton = Button(self.boxFrame,
                                    text="Exit",
                                    command=self.boxFrame.pack_forget)
        self.boxExitButton.pack(side=TOP)

        # ***** Truncated Inverse Controls *****
        self.truncatedInverseFrame = Frame(self.master)
        self.truncatedInverseSlider = Scale(self.truncatedInverseFrame,
                                            from_=-3,
                                            to=2,
                                            orient=HORIZONTAL,
                                            resolution=0.1)
        self.truncatedInverseSlider.pack(side=TOP)
        self.truncatedInverseExitButton = Button(
            self.truncatedInverseFrame,
            text="Exit",
            command=self.truncatedInverseFrame.pack_forget)
        self.truncatedInverseExitButton.pack(side=TOP)

        # ***** Weiner Controls *****
        self.weinerFrame = Frame(self.master)
        self.weinerSlider = Scale(self.weinerFrame,
                                  from_=-3,
                                  to=2,
                                  orient=HORIZONTAL,
                                  resolution=0.1)
        self.weinerSlider.pack(side=TOP)
        self.weinerExitButton = Button(self.weinerFrame,
                                       text="Exit",
                                       command=self.weinerFrame.pack_forget)
        self.weinerExitButton.pack(side=TOP)

        # ***** CLS Controls *****
        self.clsFrame = Frame(self.master)
        self.clsSlider = Scale(self.clsFrame,
                               from_=-3,
                               to=2,
                               orient=HORIZONTAL,
                               resolution=0.1)
        self.clsSlider.pack(side=TOP)
        self.clsExitButton = Button(self.clsFrame,
                                    text="Exit",
                                    command=self.clsFrame.pack_forget)
        self.clsExitButton.pack(side=TOP)

        # ***** DFT Display Area ******
        self.dftFrame = Frame(self.master)
        self.magPanel = Label(self.dftFrame)
        self.magPanel.pack(padx=10, pady=10, side=TOP)
        self.freqPanel = Label(self.dftFrame)
        self.freqPanel.pack(padx=10, pady=10, side=TOP)
        self.dftExitButton = Button(
            self.dftFrame,
            text="Exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.dftExitButton.pack(side=TOP, fill=X)

        # ***** Low Pass Mask Creation *****
        self.lpmFrame = Frame(self.master)
        self.lpmPanel = Label(self.lpmFrame)
        self.lpmPanel.pack(padx=10, pady=10, side=TOP)
        self.lpmSubButton = Button(self.lpmFrame, text="submit")
        self.lpmSubButton.pack(side=TOP)
        self.lpmExitButton = Button(
            self.lpmFrame,
            text="Exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.lpmExitButton.pack(side=TOP)
        self.lpmSlider = Scale(self.lpmFrame,
                               from_=1,
                               to=2,
                               orient=HORIZONTAL,
                               resolution=1)

        # ***** High Pass Mask Creation *****
        self.hpmFrame = Frame(self.master)
        self.hpmPanel = Label(self.hpmFrame)
        self.hpmPanel.pack(padx=10, pady=10, side=TOP)
        self.hpmSubButton = Button(self.hpmFrame, text="submit")
        self.hpmSubButton.pack(side=TOP)
        self.hpmExitButton = Button(
            self.hpmFrame,
            text="Exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.hpmExitButton.pack(side=TOP)
        self.hpmSlider = Scale(self.hpmFrame,
                               from_=1,
                               to=2,
                               orient=HORIZONTAL,
                               resolution=1)

        # ***** Band Pass Mask Creation *****
        self.bppmFrame = Frame(self.master)
        self.bppmPanel = Label(self.bppmFrame)
        self.bppmPanel.pack(padx=10, pady=10, side=TOP)
        self.bppmSubButton = Button(self.bppmFrame, text="submit")
        self.bppmSubButton.pack(side=TOP)
        self.bppmExitButton = Button(
            self.bppmFrame,
            text="Exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.bppmExitButton.pack(side=TOP)
        self.bppmSliderLow = Scale(self.bppmFrame,
                                   from_=1,
                                   to=2,
                                   orient=HORIZONTAL,
                                   resolution=1)
        self.bppmSliderHigh = Scale(self.bppmFrame,
                                    from_=1,
                                    to=2,
                                    orient=HORIZONTAL,
                                    resolution=1)

        # ***** Band Pass Mask Creation *****
        self.bspmFrame = Frame(self.master)
        self.bspmPanel = Label(self.bspmFrame)
        self.bspmPanel.pack(padx=10, pady=10, side=TOP)
        self.bspmSubButton = Button(self.bspmFrame, text="submit")
        self.bspmSubButton.pack(side=TOP)
        self.bspmExitButton = Button(
            self.bspmFrame,
            text="exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.bspmExitButton.pack(side=TOP)
        self.bspmSliderLow = Scale(self.bspmFrame,
                                   from_=1,
                                   to=2,
                                   orient=HORIZONTAL,
                                   resolution=1)
        self.bspmSliderHigh = Scale(self.bspmFrame,
                                    from_=1,
                                    to=2,
                                    orient=HORIZONTAL,
                                    resolution=1)

    def displayImg(self, img):
        # input image in RGB
        self.frame.pack()
        self.dftFrame.pack_forget()
        self.lpmFrame.pack_forget()
        self.hpmFrame.pack_forget()
        self.bppmFrame.pack_forget()
        self.bspmFrame.pack_forget()
        self.img = Image.fromarray(img)
        imgtk = ImageTk.PhotoImage(self.img)

        self.panel.configure(image=imgtk)
        self.panel.image = imgtk

    def openImage(self):
        # can change the image
        path = filedialog.askopenfilename()
        if len(path) > 0:
            imgRead = cv2.imread(path)
            if imgRead is not None:
                imgRead = cv2.cvtColor(imgRead, cv2.COLOR_BGR2RGB)
                self.origImg = Image.fromarray(imgRead)
                self.prevImg = Image.fromarray(imgRead)
                self.displayImg(imgRead)
            else:
                raise ValueError("Not a valid image")
        else:
            raise ValueError("Not a valid path")

    def loadKernel(self):
        path = filedialog.askopenfilename()
        if len(path) > 0:
            self.filter_kernel = np.mean(cv2.imread(path), axis=-1)
            self.filter_kernel = self.filter_kernel / np.sum(
                self.filter_kernel)
        else:
            raise ValueError("Not a valid path")

    def saveImage(self):
        if self.img is not None:
            toSave = filedialog.asksaveasfilename()
            self.img.save(toSave)
        else:
            messagebox.showerror(title="Save Error",
                                 message="No image to be saved!")

    def histWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.histEqlFunc(img)
        self.displayImg(imgNew)

    # Gamma Correction
    def gammaCallback(self, event, img):
        gamma = self.gammaSlider.get()
        self.prevImg = self.img
        imgNew = image_utils.gammaCorFunc(img, 255.0 / (255.0**gamma), gamma)
        self.displayImg(imgNew)

    def truncatedInverseCallback(self, event, img):
        th = 10**self.truncatedInverseSlider.get()
        imgNew = self.truncatedInverseFilter(th)
        self.displayImg(imgNew)

    def weinerCallback(self, event, img):
        gamma = 10**self.weinerSlider.get()
        imgNew = self.weinerFilter(gamma)
        self.displayImg(imgNew)

    def clsCallback(self, event, img):
        K = 10**self.clsSlider.get()
        imgNew = self.clsFilter(K)
        self.displayImg(imgNew)

    def gammaCorWrap(self):
        img = np.array(self.img)
        self.gammaFrame.pack()
        self.gammaSlider.set(1.0)
        self.gammaSlider.bind(
            "<ButtonRelease-1>",
            lambda event, img=img: self.gammaCallback(event, img))

    def logTranWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.logTranFunc(img, 255.0 / np.log10(256))
        self.displayImg(imgNew)

    def sharpWrap(self):
        # Sharpen Wrapper
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.sharpFunc(img)
        self.displayImg(imgNew)

    def boxBlurWrap(self):
        # Box Blur Wrapper
        img = np.array(self.img)
        self.prevImg = self.img
        self.boxFrame.pack()
        self.boxSlider.set(1)
        self.boxSlider.bind("<ButtonRelease-1>",
                            lambda event, img=img: self.displayImg(
                                image_utils.boxBlurFunc(
                                    event, img, 2 * self.boxSlider.get() + 1)))

    def gaussianBlurWrap(self):
        # Gaussian Blur Wrapper
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.gaussianBlurFunc(img)
        self.displayImg(imgNew)

    def medianBlurWrap(self):
        # Median Blur Wrapper
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.medianBlurFunc(img)
        self.displayImg(imgNew)

    def cartoonifyWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.cartoonifyFunc(img)
        self.displayImg(imgNew)

    def undoFunc(self):
        self.img = self.prevImg
        self.displayImg(np.array(self.img))

    def origFunc(self):
        self.prevImg = self.img
        self.img = self.origImg
        self.displayImg(np.array(self.img))

    def displayDFT(self, x_fft):
        m, n = x_fft.shape[:]
        self.frame.pack_forget()
        self.dftFrame.pack()

        x_mag = np.log10(np.absolute(x_fft)) * 255 / np.log10(m * n * 255)
        x_mag = Image.fromarray(x_mag)
        x_mag = x_mag.resize((min(256, m), min(int(256 * n / m), n)),
                             Image.ANTIALIAS)
        x_mag = ImageTk.PhotoImage(x_mag)

        x_freq = (np.angle(x_fft) % 360) * 255 / 360
        x_freq = Image.fromarray(x_freq)
        x_freq = x_freq.resize((min(256, m), min(int(256 * n / m), n)),
                               Image.ANTIALIAS)
        x_freq = ImageTk.PhotoImage(x_freq)

        self.magPanel.configure(image=x_mag)
        self.magPanel.image = x_mag

        self.freqPanel.configure(image=x_freq)
        self.freqPanel.image = x_freq

    def dftWrap(self):
        img = np.array(self.img)
        x = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
        x_outp_img = fft.fft2d_img(x)
        self.displayDFT(x_outp_img)

    def freqMaskWrap(self):
        m, n = np.array(self.img).shape[:2]
        lm, ln = np.log2(m), np.log2(m)
        dm, dn = int(2**np.ceil(lm)) + 1, int(2**np.ceil(ln)) + 1
        messagebox.showinfo(
            "Mask Size",
            "Mask Size should be (" + str(dm) + "," + str(dn) + ")")
        path = filedialog.askopenfilename()
        if len(path) > 0:
            maskRead = cv2.imread(path, 0)
            if (maskRead.shape != (dm, dn)):
                messagebox.showerror(
                    title="Shape Error",
                    message="Shape of mask and image don't match")
            else:
                self.prevImg = self.img
                self.display(image_utils.freqMask(np.array(self.img),
                                                  maskRead))
        else:
            raise ValueError("Not a valid path")

    def maskWrap(self):
        img = np.array(self.img)
        x = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
        x_outp_img = fft.fft2d_img(x)
        x_mag = image_utils.xMagCreate(x_outp_img)

        return x_outp_img, x_mag

    def maskFinal(self, x_outp_img):
        self.prevImg = self.img
        img = np.array(self.img)
        img = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
        m = len(img)
        res = fft.ifft2d_img(x_outp_img)
        res = np.array(res * 255 / np.max(res), dtype=np.uint8)
        res = np.array([[[img[i][j][0], img[i][j][1], res[i][j]]
                         for j in range(m)] for i in range(m)])
        res = cv2.cvtColor(res, cv2.COLOR_HSV2RGB)
        self.displayImg(res)

    def lpmCallBack(self, event, slider, x_outp_img):
        m = len(x_outp_img)
        m2 = int((m - 1) / 2)
        r = slider.get()
        x_outp_copy = np.copy(x_outp_img)

        nCircle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(m)]
                            for i in range(m)])
        nCircle = np.where(nCircle > r**2)
        x_outp_copy[nCircle] = 1

        x_mag = image_utils.xMagCreate(x_outp_copy)

        self.lpmPanel.configure(image=x_mag)
        self.lpmPanel.image = x_mag

    def lpmFinal(self, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r = self.lpmSlider.get()
        nCircle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nCircle = np.where(nCircle > r**2)
        x_outp_img[nCircle] = 0

        self.maskFinal(x_outp_img)

    def lpmWrap(self):
        x_outp_img, x_mag = self.maskWrap()
        m = len(x_outp_img)

        self.lpmPanel.configure(image=x_mag)
        self.lpmPanel.image = x_mag

        self.lpmSlider.configure(to=int(np.ceil(m / 2)))
        self.lpmSlider.set(1)
        self.lpmSlider.pack(side=TOP)
        self.lpmSlider.bind(
            "<ButtonRelease-1>",
            lambda event, slider=self.lpmSlider, x_outp_img=x_outp_img: self.
            lpmCallBack(event, slider, x_outp_img))

        self.lpmSubButton.configure(
            command=lambda x_outp_img=x_outp_img: self.lpmFinal(x_outp_img))

        self.dftFrame.pack_forget()
        self.frame.pack_forget()
        self.hpmFrame.pack_forget()
        self.bppmFrame.pack_forget()
        self.bspmFrame.pack_forget()
        self.lpmFrame.pack()

    def hpmCallBack(self, event, slider, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r = slider.get()
        x_outp_copy = np.copy(x_outp_img)

        circle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                           for i in range(mx)])
        circle = np.where(circle <= r**2)
        x_outp_copy[circle] = 1

        x_mag = image_utils.xMagCreate(x_outp_copy)

        self.hpmPanel.configure(image=x_mag)
        self.hpmPanel.image = x_mag

    def hpmFinal(self, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r = self.hpmSlider.get()
        circle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                           for i in range(mx)])
        circle = np.where(circle <= r**2)
        x_outp_img[circle] = 0

        self.maskFinal(x_outp_img)

    def hpmWrap(self):
        x_outp_img, x_mag = self.maskWrap()
        m = len(x_outp_img)

        self.hpmPanel.configure(image=x_mag)
        self.hpmPanel.image = x_mag

        self.hpmSlider.configure(to=m // 2)
        self.hpmSlider.set(1)
        self.hpmSlider.pack(side=TOP)
        self.hpmSlider.bind(
            "<ButtonRelease-1>",
            lambda event, slider=self.hpmSlider, x_outp_img=x_outp_img: self.
            hpmCallBack(event, slider, x_outp_img))

        self.hpmSubButton.configure(
            command=lambda x_outp_img=x_outp_img: self.hpmFinal(x_outp_img))

        self.dftFrame.pack_forget()
        self.frame.pack_forget()
        self.lpmFrame.pack_forget()
        self.bppmFrame.pack_forget()
        self.bspmFrame.pack_forget()
        self.hpmFrame.pack()

    def bppmCallBack(self, event, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r1 = self.bppmSliderLow.get()
        r2 = self.bppmSliderHigh.get()
        assert (r1 <= r2)

        self.bppmSliderLow.configure(to=r2)
        self.bppmSliderHigh.configure(from_=r1)

        x_outp_copy = np.copy(x_outp_img)
        allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nullVals = np.where(allVals < r1**2)
        x_outp_copy[nullVals] = 1
        nullVals = np.where(allVals > r2**2)
        x_outp_copy[nullVals] = 1

        x_mag = image_utils.xMagCreate(x_outp_copy)

        self.bppmPanel.configure(image=x_mag)
        self.bppmPanel.image = x_mag

    def bppmFinal(self, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r1 = self.bppmSliderLow.get()
        r2 = self.bppmSliderHigh.get()

        allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nullVals = np.where(allVals < r1**2)
        x_outp_img[nullVals] = 0
        nullVals = np.where(allVals > r2**2)
        x_outp_img[nullVals] = 0

        self.maskFinal(x_outp_img)

    def bppmWrap(self):
        x_outp_img, x_mag = self.maskWrap()
        m = len(x_outp_img)

        self.bppmPanel.configure(image=x_mag)
        self.bppmPanel.image = x_mag

        self.bppmSliderHigh.configure(from_=1)
        self.bppmSliderHigh.configure(to=m // 2)
        self.bppmSliderHigh.set(m // 2)
        self.bppmSliderHigh.pack(side=TOP)
        self.bppmSliderHigh.bind("<ButtonRelease-1>",
                                 lambda event, x_outp_img=x_outp_img: self.
                                 bppmCallBack(event, x_outp_img))

        self.bppmSliderLow.configure(from_=1)
        self.bppmSliderLow.configure(to=m // 2)
        self.bppmSliderLow.set(1)
        self.bppmSliderLow.pack(side=TOP)
        self.bppmSliderLow.bind("<ButtonRelease-1>",
                                lambda event, x_outp_img=x_outp_img: self.
                                bppmCallBack(event, x_outp_img))

        self.bppmSubButton.configure(
            command=lambda x_outp_img=x_outp_img: self.bppmFinal(x_outp_img))

        self.dftFrame.pack_forget()
        self.frame.pack_forget()
        self.lpmFrame.pack_forget()
        self.hpmFrame.pack_forget()
        self.bspmFrame.pack_forget()
        self.bppmFrame.pack()

    def bspmCallBack(self, event, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r1 = self.bspmSliderLow.get()
        r2 = self.bspmSliderHigh.get()
        assert (r1 <= r2)

        self.bspmSliderLow.configure(to=r2)
        self.bspmSliderHigh.configure(from_=r1)

        x_outp_copy = np.copy(x_outp_img)
        allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nullVals = np.where((allVals - r1**2) * (allVals - r2**2) < 0)
        x_outp_copy[nullVals] = 1

        x_mag = image_utils.xMagCreate(x_outp_copy)

        self.bspmPanel.configure(image=x_mag)
        self.bspmPanel.image = x_mag

    def bspmFinal(self, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r1 = self.bspmSliderLow.get()
        r2 = self.bspmSliderHigh.get()

        allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nullVals = np.where((allVals - r1**2) * (allVals - r2**2) < 0)
        x_outp_img[nullVals] = 0

        self.maskFinal(x_outp_img)

    def bspmWrap(self):
        x_outp_img, x_mag = self.maskWrap()
        m = len(x_outp_img)

        self.bspmPanel.configure(image=x_mag)
        self.bspmPanel.image = x_mag

        self.bspmSliderHigh.configure(from_=1)
        self.bspmSliderHigh.configure(to=m // 2)
        self.bspmSliderHigh.set(m // 2)
        self.bspmSliderHigh.pack(side=TOP)
        self.bspmSliderHigh.bind("<ButtonRelease-1>",
                                 lambda event, x_outp_img=x_outp_img: self.
                                 bspmCallBack(event, x_outp_img))

        self.bspmSliderLow.configure(from_=1)
        self.bspmSliderLow.configure(to=m // 2)
        self.bspmSliderLow.set(1)
        self.bspmSliderLow.pack(side=TOP)
        self.bspmSliderLow.bind("<ButtonRelease-1>",
                                lambda event, x_outp_img=x_outp_img: self.
                                bspmCallBack(event, x_outp_img))

        self.bspmSubButton.configure(
            command=lambda x_outp_img=x_outp_img: self.bspmFinal(x_outp_img))

        self.dftFrame.pack_forget()
        self.frame.pack_forget()
        self.lpmFrame.pack_forget()
        self.hpmFrame.pack_forget()
        self.bppmFrame.pack_forget()
        self.bspmFrame.pack()

    def fullInverseWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = filtering.inverseFilter2D(img, self.filter_kernel)
        self.displayImg(imgNew)

    def truncatedInverseWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        self.truncatedInverseFilter = filtering.getTruncatedInverseFilter2D(
            img, self.filter_kernel)
        self.truncatedInverseFrame.pack()
        self.truncatedInverseSlider.set(1.0)
        self.truncatedInverseSlider.bind(
            "<ButtonRelease-1>",
            lambda event, img=img: self.truncatedInverseCallback(event, img))

    def approximateWeinerWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        self.weinerFilter = filtering.getApproximateWeinerFilter2D(
            img, self.filter_kernel)
        self.weinerFrame.pack()
        self.weinerSlider.set(1.0)
        self.weinerSlider.bind(
            "<ButtonRelease-1>",
            lambda event, img=img: self.weinerCallback(event, img))

    def contrainedLSWrap(self):  # TODO: implement
        img = np.array(self.img)
        self.prevImg = self.img
        self.clsFilter = filtering.getConstrainedLSFilter2D(
            img, self.filter_kernel)
        self.clsFrame.pack()
        self.clsSlider.set(1.0)
        self.clsSlider.bind(
            "<ButtonRelease-1>",
            lambda event, img=img: self.clsCallback(event, img))
Beispiel #25
0
class ShopEngine:
    def __init__(self, window):
        self.window = window
        self.normalShop = True
        self.f = Frame(self.window.root,
                       bg="blue",
                       width=self.window.width,
                       height=self.window.height)
        self.f.pack_propagate(0)

        self.backgroundImage = ImageTk.PhotoImage(file="Backgrounds/shop.png")
        self.backgroundLabel = Label(self.f, image=self.backgroundImage)

        self.shopScale = self.window.width / 1280
        self.save = self.window.save
        barScale = self.shopScale / 5
        buttonScale = self.shopScale / 2

        self.barImageList = []
        self.barImageList.append(
            self.openTkImage("Images/Shop/levelBar1.png", barScale))
        self.barImageList.append(
            self.openTkImage("Images/Shop/levelBar2.png", barScale))
        self.barImageList.append(
            self.openTkImage("Images/Shop/levelBar3.png", barScale))
        self.barImageList.append(
            self.openTkImage("Images/Shop/levelBar4.png", barScale))
        self.barImageList.append(
            self.openTkImage("Images/Shop/levelBar5.png", barScale))
        self.barImageList.append(
            self.openTkImage("Images/Shop/levelBar6.png", barScale))

        self.buttonList = []

        self.sideBar = Label(self.window.root,
                             bg="#%02x%02x%02x" % (121, 202, 249),
                             width=self.window.width // 5,
                             height=self.window.height)
        self.sideBar.pack(in_=self.f, side=LEFT, pady=25, padx=25)

        self.buttonGrid = Label(self.window.root,
                                bg="#%02x%02x%02x" % (121, 202, 249),
                                width=self.window.width // 5 * 3,
                                height=self.window.height)
        self.buttonGrid.pack(in_=self.f, side=TOP)

        self.moneyL = Label(self.window.root,
                            text="Mass: " + str(self.save.mass),
                            bg="#%02x%02x%02x" % (121, 202, 249),
                            font="Helvetica 15 bold",
                            width=self.window.width // 5)
        self.moneyL.pack(side=TOP, in_=self.sideBar, pady=25)

        self.achievementB = Button(self.window.root,
                                   text="Star Shop",
                                   command=self.achievement,
                                   bg="#%02x%02x%02x" % (255, 165, 0),
                                   width=self.window.width // 5,
                                   font="Helvetica 15 bold")
        self.achievementB.pack(side=BOTTOM, in_=self.sideBar, pady=25)

        self.accept = Button(self.window.root,
                             text="Accept",
                             command=self.accept,
                             bg="#%02x%02x%02x" % (255, 0, 0),
                             width=self.window.width // 5,
                             font="Helvetica 15 bold")
        self.accept.pack(side=BOTTOM, in_=self.sideBar)

        self.shieldButtonImage = ImageTk.PhotoImage(
            self.scale(Image.open("Images/Shop/shieldButton.png"),
                       buttonScale))
        ShopButton(self.window,
                   self.window.save.shieldLevel,
                   self.buttonGrid,
                   self.sideBar,
                   self.save,
                   self.buttonList,
                   self.barImageList,
                   self.backgroundImage,
                   0,
                   0,
                   """Shield Capacity:
Increases the amount of sheilds you are able to hold""",
                   self.window.root,
                   image=self.shieldButtonImage)
        self.airResistButtonImage = ImageTk.PhotoImage(
            self.scale(Image.open("Images/Shop/airResistButton.png"),
                       buttonScale))
        ShopButton(self.window,
                   self.window.save.airResistLevel,
                   self.buttonGrid,
                   self.sideBar,
                   self.save,
                   self.buttonList,
                   self.barImageList,
                   self.backgroundImage,
                   1,
                   0,
                   """Aerodynamics:
Reduces air resistance, allowing you to fly farther and faster""",
                   self.window.root,
                   image=self.airResistButtonImage)
        self.antiGravButtonImage = ImageTk.PhotoImage(
            self.scale(Image.open("Images/Shop/antiGravButton.png"),
                       buttonScale))
        ShopButton(self.window,
                   self.window.save.antiGravLevel,
                   self.buttonGrid,
                   self.sideBar,
                   self.save,
                   self.buttonList,
                   self.barImageList,
                   self.backgroundImage,
                   2,
                   0,
                   """Anit-gravity:
Reduces the effect of gravity, causing increased time between bounces""",
                   self.window.root,
                   image=self.antiGravButtonImage)
        self.frictionButtonImage = ImageTk.PhotoImage(
            self.scale(Image.open("Images/Shop/frictionButton.png"),
                       buttonScale))
        ShopButton(self.window,
                   self.window.save.frictionLevel,
                   self.buttonGrid,
                   self.sideBar,
                   self.save,
                   self.buttonList,
                   self.barImageList,
                   self.backgroundImage,
                   0,
                   1,
                   """Oil:
Reduces the friction between you and the ground, allowing you to bounce farther""",
                   self.window.root,
                   image=self.frictionButtonImage)
        self.launchSpeedButtonImage = ImageTk.PhotoImage(
            self.scale(Image.open("Images/Shop/launchSpeedButton.png"),
                       buttonScale))
        ShopButton(self.window,
                   self.window.save.launchLevel,
                   self.buttonGrid,
                   self.sideBar,
                   self.save,
                   self.buttonList,
                   self.barImageList,
                   self.backgroundImage,
                   1,
                   1,
                   """Launch Speed:
Increases the speed at which you launch, greatly increasing your trip length""",
                   self.window.root,
                   image=self.launchSpeedButtonImage)
        self.maxMassButtonImage = ImageTk.PhotoImage(
            self.scale(Image.open("Images/Shop/maxMassButton.png"),
                       buttonScale))
        ShopButton(self.window,
                   self.window.save.maxMassLevel,
                   self.buttonGrid,
                   self.sideBar,
                   self.save,
                   self.buttonList,
                   self.barImageList,
                   self.backgroundImage,
                   2,
                   1,
                   """Maximum Size:
Increases the size that you start your launch with, causing increased visibility and accelerated growth""",
                   self.window.root,
                   image=self.maxMassButtonImage)
        self.growthRateButtonImage = ImageTk.PhotoImage(
            self.scale(Image.open("Images/Shop/growthRateButton.png"),
                       buttonScale))
        ShopButton(self.window,
                   self.window.save.growthRateLevel,
                   self.buttonGrid,
                   self.sideBar,
                   self.save,
                   self.buttonList,
                   self.barImageList,
                   self.backgroundImage,
                   0,
                   2,
                   """Growth rate:
Increases the rate at which you grow, allowing you to make more money faster""",
                   self.window.root,
                   image=self.growthRateButtonImage)
        self.maxFuelButtonImage = ImageTk.PhotoImage(
            self.scale(Image.open("Images/Shop/maxFuelButton.png"),
                       buttonScale))
        ShopButton(self.window,
                   self.window.save.maxFuelLevel,
                   self.buttonGrid,
                   self.sideBar,
                   self.save,
                   self.buttonList,
                   self.barImageList,
                   self.backgroundImage,
                   1,
                   2,
                   """Max Fuel:
Increases the amount of fuel you start with, and the maximum amount you can hold""",
                   self.window.root,
                   image=self.maxFuelButtonImage)
        self.propulsionButtonImage = ImageTk.PhotoImage(
            self.scale(Image.open("Images/Shop/propulsionButton.png"),
                       buttonScale))
        ShopButton(self.window,
                   self.window.save.propulsionLevel,
                   self.buttonGrid,
                   self.sideBar,
                   self.save,
                   self.buttonList,
                   self.barImageList,
                   self.backgroundImage,
                   2,
                   2,
                   """Rocket speed:
Increases the propulsion from your rocket, allowing you to maneuver more easily and go farther""",
                   self.window.root,
                   image=self.propulsionButtonImage)

    def update(self):
        self.f.config(width=self.window.width, height=self.window.width)

        self.shopScale = self.window.width / 1280
        self.save = self.window.save
        barScale = self.shopScale / 5

        self.sideBar.config(width=self.window.width // 5,
                            heigh=self.window.height)
        self.buttonGrid.config(width=self.window.width // 5 * 3,
                               height=self.window.height)
        buttonScale = self.shopScale / 2

        self.barImageList.clear()
        self.barImageList.append(
            self.openTkImage("Images/Shop/levelBar1.png", barScale))
        self.barImageList.append(
            self.openTkImage("Images/Shop/levelBar2.png", barScale))
        self.barImageList.append(
            self.openTkImage("Images/Shop/levelBar3.png", barScale))
        self.barImageList.append(
            self.openTkImage("Images/Shop/levelBar4.png", barScale))
        self.barImageList.append(
            self.openTkImage("Images/Shop/levelBar5.png", barScale))
        self.barImageList.append(
            self.openTkImage("Images/Shop/levelBar6.png", barScale))

        try:
            self.buttonGrid.config(width=self.window.width // 5 * 3,
                                   height=self.window.height)
            self.shieldButtonImage = ImageTk.PhotoImage(
                self.scale(Image.open("Images/Shop/shieldButton.png"),
                           buttonScale))
            self.buttonList[0].config(image=self.shieldButtonImage)
            self.airResistButtonImage = ImageTk.PhotoImage(
                self.scale(Image.open("Images/Shop/airResistButton.png"),
                           buttonScale))
            self.buttonList[1].config(image=self.airResistButtonImage)
            self.antiGravButtonImage = ImageTk.PhotoImage(
                self.scale(Image.open("Images/Shop/antiGravButton.png"),
                           buttonScale))
            self.buttonList[2].config(image=self.antiGravButtonImage)
            self.frictionButtonImage = ImageTk.PhotoImage(
                self.scale(Image.open("Images/Shop/frictionButton.png"),
                           buttonScale))
            self.buttonList[3].config(image=self.frictionButtonImage)
            self.launchSpeedButtonImage = ImageTk.PhotoImage(
                self.scale(Image.open("Images/Shop/launchSpeedButton.png"),
                           buttonScale))
            self.buttonList[4].config(image=self.launchSpeedButtonImage)
            self.maxMassButtonImage = ImageTk.PhotoImage(
                self.scale(Image.open("Images/Shop/maxMassButton.png"),
                           buttonScale))
            self.buttonList[5].config(image=self.maxMassButtonImage)
            self.growthRateButtonImage = ImageTk.PhotoImage(
                self.scale(Image.open("Images/Shop/growthRateButton.png"),
                           buttonScale))
            self.buttonList[6].config(image=self.growthRateButtonImage)
            self.maxFuelButtonImage = ImageTk.PhotoImage(
                self.scale(Image.open("Images/Shop/maxFuelButton.png"),
                           buttonScale))
            self.buttonList[7].config(image=self.maxFuelButtonImage)
            self.propulsionButtonImage = ImageTk.PhotoImage(
                self.scale(Image.open("Images/Shop/propulsionButton.png"),
                           buttonScale))
            self.buttonList[8].config(image=self.propulsionButtonImage)
        except:
            pass

    def accept(self):
        self.window.rMenu = "charScreen"

    def achievement(self):
        self.window.rMenu = "starShop"

    def run(self):
        self.moneyL.config(text="Mass: " + str(int(self.save.mass)))
        self.save = self.window.save
        for button in self.buttonList:
            button.save = self.window.save
            button.run()

        self.window.save.shieldLevel = self.buttonList[0].level
        self.window.save.airResistLevel = self.buttonList[1].level
        self.window.save.antiGravLevel = self.buttonList[2].level
        self.window.save.frictionLevel = self.buttonList[3].level
        self.window.save.launchLevel = self.buttonList[4].level
        self.window.save.maxMassLevel = self.buttonList[5].level
        self.window.save.growthRateLevel = self.buttonList[6].level
        self.window.save.maxFuelLevel = self.buttonList[7].level
        self.window.save.propulsionLevel = self.buttonList[8].level

    def scale(self, image, scale):
        newWidth = image.size[0] * scale
        wPercent = (newWidth / float(image.size[0]))
        hSize = int((float(image.size[1]) * float(wPercent)))
        scaledImage = image.resize((int(newWidth), int(hSize)),
                                   PIL.Image.ANTIALIAS)
        return scaledImage

    def hide(self):
        self.backgroundLabel.place(x=10000, y=10000, relwidth=1, relheight=1)
        self.sideBar.place(x=10000, y=10000, relwidth=.15, relheight=1)
        self.f.pack_forget()

    def setUp(self):
        self.backgroundLabel.place(x=0, y=0, relwidth=1, relheight=1)
        self.sideBar.place(x=0, y=0, relwidth=.15, relheight=1)
        self.shopScale = self.window.width / 1280
        self.buttonList[0].level = self.window.save.shieldLevel
        self.buttonList[1].level = self.window.save.airResistLevel
        self.buttonList[2].level = self.window.save.antiGravLevel
        self.buttonList[3].level = self.window.save.frictionLevel
        self.buttonList[4].level = self.window.save.launchLevel
        self.buttonList[5].level = self.window.save.maxMassLevel
        self.buttonList[6].level = self.window.save.growthRateLevel
        self.buttonList[7].level = self.window.save.maxFuelLevel
        self.buttonList[8].level = self.window.save.propulsionLevel

        self.f.pack()

    def openTkImage(self, path, scale):
        return ImageTk.PhotoImage(
            self.scale(Image.open(path), scale).convert("RGB"))
Beispiel #26
0
class QuantMonitor(object):

    # 背景色
    bgColor = rgb_to_hex(245, 245, 245)
    bgColorW = "white"

    def __init__(self, frame, control, language):
        self.parentFrame = frame
        self._controller = control
        self._logger = self._controller.get_logger()
        self.language = language

        # Monitor不同标签的背景色
        self.rColor = self.bgColorW
        self.lColor = self.bgColor
        self.eColor = self.bgColor
        self.pColor = self.bgColor
        # 日志不同标签背景色
        self.yColor = self.bgColor   # 系统日志标签颜色
        self.sColor = self.bgColor
        self.uColor = self.bgColorW

        self.createButtonFrame()

        # 执行列表、监控日志、信号记录、错误
        self.executeList  = Frame(self.parentFrame)
        self.errRecord    = Frame(self.parentFrame)
        self.posMonitor   = Frame(self.parentFrame)
        self.logRecord    = Frame(self.parentFrame)

        self.sysLog       = Frame(self.logRecord)
        self.sigRecord    = Frame(self.logRecord)
        self.usrLog       = Frame(self.logRecord)

        self.executeList.pack(side=TOP, fill=BOTH, expand=YES)

        self.sysText = None
        self.sigText = None
        self.usrText = None
        self.errText = None

        self._regUpdateCallback()

        # 日志功能区
        self.createLogBtnFrame()
        self.usrLog.pack(side=TOP, fill=BOTH, expand=YES)

    def createButtonFrame(self):
        btnFrame = Frame(self.parentFrame, height=30, bg=self.bgColor)
        btnFrame.pack_propagate(0)
        btnFrame.pack(side=TOP, fill=X)

        self.runBtn = Button(btnFrame, text="策略运行", relief=FLAT, padx=14, pady=1.5, bg=self.rColor,
                             bd=0, highlightthickness=1, command=self.toMonFrame)
        self.logBtn = Button(btnFrame, text="运行日志", relief=FLAT, padx=14, pady=1.5, bg=self.lColor,
                             bd=0, highlightthickness=1, command=self.toLogFrame)
        self.errBtn = Button(btnFrame, text="错误信息", relief=FLAT, padx=14, pady=1.5, bg=self.eColor,
                             bd=0, highlightthickness=1, command=self.toErrFrame)

        self.posBtn = Button(btnFrame, text="组合监控", relief=FLAT, padx=14, pady=1.5, bg=self.pColor,
                             bd=0, highlightthickness=1, command=self.toPosFrame)
        self.runBtn.pack(side=LEFT, expand=NO)
        self.logBtn.pack(side=LEFT, expand=NO)
        self.errBtn.pack(side=LEFT, expand=NO)
        self.posBtn.pack(side=LEFT, expand=NO)

        for btn in (self.runBtn, self.logBtn, self.errBtn, self.posBtn):
            btn.bind("<Enter>", self.handlerAdaptor(self.onEnter, button=btn))
            btn.bind("<Leave>", self.handlerAdaptor(self.onLeave, button=btn))

    def createLogBtnFrame(self):
        """创建日志按钮Frame"""
        lBtnFrame = Frame(self.logRecord, height=30, bg=self.bgColor)
        lBtnFrame.pack_propagate(0)
        lBtnFrame.pack(side=BOTTOM, fill=X)

        self.usrBtn = Button(lBtnFrame, text="用户日志", relief=FLAT, padx=14, pady=1.5, bg=self.rColor,
                             bd=0, highlightthickness=1, command=self.toUsrFrame)
        self.sigBtn = Button(lBtnFrame, text="信号记录", relief=FLAT, padx=14, pady=1.5, bg=self.lColor,
                             bd=0, highlightthickness=1, command=self.toSigFrame)
        self.sysBtn = Button(lBtnFrame, text="系统日志", relief=FLAT, padx=14, pady=1.5, bg=self.sColor,
                             bd=0, highlightthickness=1, command=self.toSysFrame)

        self.usrBtn.pack(side=LEFT, expand=NO)
        self.sigBtn.pack(side=LEFT, expand=NO)
        self.sysBtn.pack(side=LEFT, expand=NO)

        # for btn in (self.usrBtn, self.sigBtn, self.sysBtn):
            # btn.bind("<Enter>", self.handlerAdaptor(self.onEnter, button=btn))
            # btn.bind("<Leave>", self.handlerAdaptor(self.onLeave, button=btn))
            # pass

    def createLog(self):
        self.createSysLog()
        self.createSignal()
        self.createUsrLog()

    def createSysLog(self):
        """系统日志"""
        self.sysText = MonitorText(self.sysLog, self, height=20, bd=0)
        self.sysText.createScrollbar()
        self.sysText.pack(fill=BOTH, expand=YES)

    def createSignal(self):
        """信号记录"""
        self.sigText = SigText(self.sigRecord, self, height=20, bd=0)
        self.sigText.createScrollbar()
        self.sigText.pack(fill=BOTH, expand=YES)

    def createUsrLog(self):
        """用户日志"""
        self.usrText = UsrLogText(self.usrLog, height=20, bd=0)
        self.usrText.createScrollbar()
        self.usrText.pack(fill=BOTH, expand=YES)

    def createPos(self):
        headList = ["账号", "合约", "账户仓", "策略仓", "仓差",
                    "策略多", "策略空","策略今多", "策略今空", "账户多", "账户空", "账户今多", "账户今空"]
        widthList = [20, 20, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]

        funcFrame = Frame(self.posMonitor, relief=RAISED, bg=rgb_to_hex(245, 245, 245), height=25)
        funcFrame.pack(side=TOP, fill=X, expand=YES, padx=1, pady=2)
        treeFrame = Frame(self.posMonitor, relief=RAISED, bg=rgb_to_hex(245, 245, 245))
        treeFrame.pack(side=TOP, fill=X, expand=YES, padx=1, pady=2)
        self.posTree = ttk.Treeview(treeFrame, show="headings", height=28, columns=headList)
        self.posTree.pack(fill=BOTH, expand=YES, padx=5)

        for key, w in zip(headList, widthList):
            self.posTree.column(key, width=w, anchor=W)
            self.posTree.heading(key, text=key, anchor=W)

        self.createPosFunc(funcFrame)

    def createPosFunc(self, frame):
        cbV    = StringVar()
        sbV    = IntVar()
        timeV  = IntVar()

        cbV.set("对盘价")
        sbV.set(0)
        timeV.set(5000)

        # buttonborder = Frame(frame, highlightbackground="lightblue", highlightthickness=2, bd=0)
        # buttonborder.pack(side=LEFT, padx=2)

        synBtn = Button(frame, text="持仓一键同步", relief=FLAT, activebackground="lightblue",
                        overrelief="groove",
                        bg=rgb_to_hex(230, 230, 230))
        synBtn.pack(side=LEFT, padx=2)

        Label(frame, text="同步设置:", bg=rgb_to_hex(245, 245, 245), justify=LEFT, anchor=W, width=8).pack(side=LEFT)

        cbValues = ["对盘价", "最新价", "市价"]

        cb = ttk.Combobox(frame, values=cbValues, width=11, textvariable=cbV, state="readonly")
        cb.pack(side=LEFT, padx=2)

        Label(frame, text="+", bg=rgb_to_hex(245, 245, 245), justify=LEFT, anchor=W, width=1).pack(side=LEFT)

        sb = ttk.Spinbox(frame, values=list(range(0, 101, 1)), width=4, textvariable=sbV)
        sb.pack(side=LEFT, padx=2)

        Label(frame, text="跳", bg=rgb_to_hex(245, 245, 245), justify=LEFT, anchor=W, width=2).pack(side=LEFT)

        disCheck = Checkbutton(frame, text="间隔", bg=rgb_to_hex(245, 245, 245), width=10, bd=1, anchor=E)
        disCheck.pack(side=LEFT, padx=2)

        timeEntry = Entry(frame, relief=GROOVE, bd=2, width=5, textvariable=timeV)
        timeEntry.pack(side=LEFT)

        Label(frame, text="毫秒自动同步", bg=rgb_to_hex(245, 245, 245), justify=LEFT, anchor=W, width=12)\
            .pack(side=LEFT, padx=2)

        subCheck = Checkbutton(frame, text="仅自动减仓", bg=rgb_to_hex(245, 245, 245), bd=1, anchor=W)
        subCheck.pack(side=LEFT, padx=5)

    def createExecute(self):
        headList  = ["编号", "账号", "策略名称", "基准合约", "频率", "运行阶段", "运行模式",
                    "初始资金", "可用资金", "最大回撤", "累计收益", "胜率"]
        widthList = [5, 50, 50, 50, 5, 10, 5, 20, 10, 20, 20, 5]

        self.executeBar = ttk.Scrollbar(self.executeList, orient="vertical")
        self.executeBar.pack(side=RIGHT, fill=Y)

        self.executeListTree = ttk.Treeview(self.executeList, show="headings", height=28, columns=tuple(headList),
                                            yscrollcommand=self.executeBar.set, style="Filter.Treeview")
        self.executeBar.config(command=self.executeListTree.yview)
        self.executeListTree.pack(fill=BOTH, expand=YES)

        self.executeListTree.bind("<Button-3>", self.createMenu)

        for key, w in zip(headList, widthList):
            self.executeListTree.column(key, width=w, anchor=CENTER)
            self.executeListTree.heading(key, text=key)

    def createMenu(self, event):
        """创建运行策略右键菜单"""
        RunMenu(self._controller, self.executeListTree).popupmenu(event)

    def _formatMonitorInfo(self, dataDict):
        """
        格式化监控需要的信息
        :param dataDict: 策略的所有信息
        :return: 需要展示的信息
        """

        try:
            Id          = dataDict['StrategyId']
            UserNo      = dataDict["Config"]["Money"]["UserNo"]
            StName      = dataDict['StrategyName']
            BenchCon    = dataDict['ContractNo']
            kLineType   = dataDict['KLineType']
            kLineSlice  = dataDict['KLinceSlice']

            Frequency   = str(kLineSlice) + kLineType

            # RunType     = "是" if dataDict['IsActualRun'] else "否"
            RunType     = RunMode[dataDict["IsActualRun"]]
            Status      = StrategyStatus[dataDict["StrategyState"]]
            InitFund    = dataDict['InitialFund']

            Available   = "{:.2f}".format(InitFund)
            MaxRetrace  = 0.0
            TotalProfit = 0.0
            WinRate     = 0.0

            return [
                Id,
                UserNo,
                StName,
                BenchCon,
                Frequency,
                Status,
                RunType,
                InitFund,
                Available,
                MaxRetrace,
                TotalProfit,
                WinRate
            ]

        except KeyError:
            traceback.print_exc()
            return []

    def addExecute(self, dataDict):
        values = self._formatMonitorInfo(dataDict)

        if not values:
            return

        strategyId = dataDict["StrategyId"]
        try:
            if self.executeListTree.exists(strategyId):
                self.updateRunStage(strategyId, dataDict[5])
                return
        except Exception as e:
            self._logger.warn("addExecute exception")
        else:
            self.executeListTree.insert("", END, iid=strategyId, values=tuple(values), tag=0)

    def createErr(self):
        # 错误信息展示
        self.errText = ErrorText(self.errRecord, height=20, bd=0)
        self.errText.createScrollbar()
        self.errText.pack(fill=BOTH, expand=YES)

    def _regUpdateCallback(self):
        self._logUpdateDict = {
            "U": self._updateUsrText,
            "E": self._updateErrText,
            "s": self._updateSysText,
        }

    def _updateSigText(self, text):
        """更新下单信号日志"""
        # 先清空信号记录
        self.sigText.delText()
        self.sigText.setText(text)

    def _updateErrText(self, text):
        """更新调试信息日志"""
        self.errText.setText(text)
        self.toErrFrame()

    def _updateUsrText(self, text):
        """更新用户日志"""
        self.usrText.setText(text)

    def _updateSysText(self, text):
        """更新系统日志"""
        self.sysText.delText()
        self.sysText.setText(text)

    def loadSysLogFile(self):
        """读取本地系统日志"""
        sysLogPath = r"./log/equant.log"
        # with open(sysLogPath, "r", encoding="utf-8") as f:
        with open(sysLogPath, "r") as f:
            data = f.read()
            self._updateSysText(data)

    def loadSigLogFile(self):
        """读取本地信号日志并写入界面"""
        sigLogPath = r"./log/trade.dat"
        with open(sigLogPath, "r", encoding="utf-8") as f:
            data = f.read()
            self._updateSigText(data)

    # TODO: 函数名改为updateLogText
    def updateLogText(self):
        guiQueue = self._controller.get_logger().getGuiQ()
        errData, usrData = "", ""
        flag = True
        try:
            while flag:
                logData = guiQueue.get_nowait()
                if logData[0] == "U":
                    usrData += logData[1] + "\n"
                elif logData[0] == "E":
                    errData += logData[1] + "\n"

                if guiQueue.empty():
                    flag = False
        except:
            return
        else:
            if usrData:
                self._updateUsrText(usrData)
            if errData:
                self._updateErrText(errData)

    def clearErrorText(self):
        self.errText.setText("")

    def toMonFrame(self):
        self.runBtn.config(bg="white")
        self.rColor = self.runBtn['bg']
        self.lColor = self.bgColor
        self.eColor = self.bgColor
        self.pColor = self.bgColor
        self.errBtn.config(bg=self.rColor)
        self.logBtn.config(bg=self.lColor)
        self.posBtn.config(bg=self.pColor)
        self.logRecord.pack_forget()
        self.errRecord.pack_forget()
        self.posMonitor.pack_forget()
        self.executeList.pack(side=TOP, fill=BOTH, expand=YES)

    # def toLogFrame(self, event, button):
    #     buttons = [self.runBtn, self.logBtn, self.errBtn, self.posBtn]
    #     colors = [self.rColor, self.lColor, self.eColor, self.pColor]
    #     frames = [self.executeList, self.logRecord, self.errRecord, self.posMonitor]
    #
    #     button.config(bg="white")
    #     index = buttons.index(button)
    #     colors[index] = button['bg']
    #     frames[index].pack(side=TOP, fill=BOTH, expand=YES)
    #     buttons.remove(button)
    #     colors.remove(colors[index])
    #     frames.remove(frames[index])
    #     #TODO:怎么pop呢?
    #
    #     for btn in buttons:
    #         i = buttons.index(btn)
    #         colors[i] = self.bgColor
    #         btn.config(bg=self.bgColor)
    #         frames[i].pack_forget()

    def toLogFrame(self):
        self.logBtn.config(bg="white")
        self.lColor = self.logBtn['bg']
        self.rColor = self.bgColor
        self.eColor = self.bgColor
        self.pColor = self.bgColor
        self.runBtn.config(bg=self.rColor)
        self.errBtn.config(bg=self.eColor)
        self.posBtn.config(bg=self.pColor)
        self.executeList.pack_forget()
        self.errRecord.pack_forget()
        self.posMonitor.pack_forget()
        self.logRecord.pack(side=TOP, fill=BOTH, expand=YES)

    def toSysFrame(self):
        self.sysBtn.config(bg="white")
        self.yColor = self.sysBtn['bg']
        self.sColor = self.bgColor
        self.uColor = self.bgColor

        self.sigBtn.config(bg=self.sColor)
        self.usrBtn.config(bg=self.uColor)

        self.sigRecord.pack_forget()
        self.usrLog.pack_forget()

        self.sysLog.pack(side=TOP, fill=BOTH, expand=YES)

        # 写入系统日志
        self.loadSysLogFile()

    def toSigFrame(self):
        self.sigBtn.config(bg="white")
        self.sColor = self.sigBtn['bg']
        self.uColor = self.bgColor
        self.yColor = self.bgColor

        self.sysBtn.config(bg=self.yColor)
        self.usrBtn.config(bg=self.uColor)

        self.sysLog.pack_forget()
        self.usrLog.pack_forget()

        self.sigRecord.pack(side=TOP, fill=BOTH, expand=YES)

        # 写入信号记录
        self.loadSigLogFile()

    def toUsrFrame(self):
        self.usrBtn.config(bg="white")
        self.uColor = self.sysBtn['bg']
        self.sColor = self.bgColor
        self.yColor = self.bgColor

        self.sigBtn.config(bg=self.sColor)
        self.sysBtn.config(bg=self.yColor)

        self.sigRecord.pack_forget()
        self.sysLog.pack_forget()

        self.usrLog.pack(side=TOP, fill=BOTH, expand=YES)

    def toErrFrame(self):
        self.errBtn.config(bg="white")
        self.eColor = self.errBtn['bg']
        self.lColor = self.bgColor
        self.rColor = self.bgColor
        self.pColor = self.bgColor
        self.runBtn.config(bg=self.rColor)
        self.logBtn.config(bg=self.lColor)
        self.posBtn.config(bg=self.pColor)
        self.parentFrame.update()
        self.logRecord.pack_forget()
        self.executeList.pack_forget()
        self.posMonitor.pack_forget()
        self.errRecord.pack(side=TOP, fill=BOTH, expand=YES)

    def toPosFrame(self):
        self.posBtn.config(bg="white")
        self.pColor = self.posBtn['bg']
        self.lColor = self.bgColor
        self.rColor = self.bgColor
        self.eColor = self.bgColor
        self.runBtn.config(bg=self.rColor)
        self.logBtn.config(bg=self.lColor)
        self.errBtn.config(bg=self.eColor)
        self.parentFrame.update()
        self.logRecord.pack_forget()
        self.executeList.pack_forget()
        self.errRecord.pack_forget()
        self.posMonitor.pack(side=TOP, fill=BOTH, expand=YES)

    def handlerAdaptor(self, fun, **kwargs):
        return lambda event, fun=fun, kwargs=kwargs: fun(event, **kwargs)

    def onEnter(self, event, button):
        """鼠标进入事件"""
        buttons = [self.runBtn, self.logBtn, self.errBtn, self.posBtn]
        button.config(bg='white')
        buttons.remove(button)
        for btn in buttons:
            btn.config(bg=self.bgColor)

    def onLeave(self, event, button):
        """鼠标离开事件"""
        buttons = [self.runBtn, self.logBtn, self.errBtn, self.posBtn]
        #TODO: 类实例作为字典键值有问题!
        btnColorDict = {
            self.runBtn: self.rColor,
            self.logBtn: self.lColor,
            self.errBtn: self.eColor,
            self.posBtn: self.pColor
        }
        button.config(bg=rgb_to_hex(227, 230, 233))
        button['bg'] = btnColorDict[button]

        buttons.remove(button)
        for btn in buttons:
            btn['bg'] = btnColorDict[btn]

    def deleteStrategy(self, strategyId):
        """删除策略"""
        if str(strategyId) in self.executeListTree.get_children():
            self.executeListTree.delete(strategyId)
            self._logger.info(f"[UI][{strategyId}]: Delete strategy {strategyId} successfully!")

    def updateValue(self, strategyId, dataDict):
        """更新策略ID对应的运行数据"""

        colValues = {
                       "#9": "{:.2f}".format(dataDict["Available"]),
                       "#10": "{:.2f}".format(dataDict["MaxRetrace"]),
                       "#11": "{:.2f}".format(dataDict["NetProfit"]),
                       "#12": "{:.2f}".format(dataDict["WinRate"])
                   }

        if str(strategyId) in self.executeListTree.get_children():
            for k, v in colValues.items():
                try:
                    self.executeListTree.set(strategyId, column=k, value=v)
                except TclError as e:
                    self._logger.error(f"[UI][{strategyId}]: 更新策略执行数据时出错,执行列表中该策略已删除!")

    def updateRunStage(self, strategyId, status):
        """更新策略运行阶段"""
        if str(strategyId) in self.executeListTree.get_children():
            self.executeListTree.set(strategyId, column="#6", value=StrategyStatus[status])

    def updateRunMode(self, strategyId, status):
        """更新策略运行模式"""
        if str(strategyId) in self.executeListTree.get_children():
            self.executeListTree.set(strategyId, column="#7", value=RunMode[status])

    def updatePos(self, positions):
        for itemId in self.posTree.get_children():
            self.posTree.delete(itemId)
       
        for v in positions:
            self.posTree.insert("", 'end', values=v)
Beispiel #27
0
class MyRoot(Tk):
    def __init__(self, master=None):
        Tk.__init__(self, master)
        self.last_time_count = DEFAULT_TIME_COUNT

        self.hour_str = StringVar()
        self.minute_str = StringVar()
        self.second_str = StringVar()
        self.time_str = StringVar()
        self.status_str = StringVar()
        self.edit_str = StringVar()
        self.time_str.set('60:00')
        self.status_str.set('开始')
        self.edit_str.set('保存')

        self.timer_frame = Frame(self)
        self.timer_frame.pack(side='top', fill='both')

        self.input_hour = Entry(self.timer_frame,
                                width=3,
                                textvariable=self.hour_str)
        self.input_hour.pack(side='left', fill='both')
        self.input_hour.insert(INSERT, "1")

        self.sign_one = Label(self.timer_frame, text=':', width=1)
        self.sign_one.pack(side='left', fill='both')

        self.input_minute = Entry(self.timer_frame,
                                  width=3,
                                  textvariable=self.minute_str)
        self.input_minute.pack(side='left', fill='both')
        self.input_minute.insert(INSERT, "00")

        self.sign_two = Label(self.timer_frame, text=':', width=1)
        self.sign_two.pack(side='left', fill='both')

        self.input_second = Entry(self.timer_frame,
                                  width=3,
                                  textvariable=self.second_str)
        self.input_second.pack(side='left', fill='both')
        self.input_second.insert(INSERT, "00")

        self.label = Label(self, textvariable=self.time_str, width=10)
        self.label.pack(side='top', fill='both')

        self.start_button = Button(self,
                                   textvariable=self.status_str,
                                   command=self.toggle,
                                   state='disabled')
        self.start_button.pack(side='top', fill='both')

        self.edit_button = Button(self,
                                  textvariable=self.edit_str,
                                  command=self.edit)
        self.edit_button.pack(side='top', fill='both')

        self.time_count = DEFAULT_TIME_COUNT
        self.current_status = False  # False 代表 暂停  True 代表 播放
        self.edit_status = False
        self.is_first = False

        self.show_edit()

    def toggle(self):
        self.current_status = not self.current_status
        if self.current_status:
            self.play()
        else:
            self.pause()

    def play(self):
        if self.time_count == 0:
            showwarning('请注意!', '起来喝水了!! 回来以后!')
            self.reset()
            return

        self.status_str.set('暂停')
        self.run_time()
        self.timer = self.after(1000, self.play)

    def pause(self):
        self.status_str.set('运行')
        self.after_cancel(self.timer)

    def reset(self):
        self.time_count = self.last_time_count
        self.current_status = False
        self.run_time()
        self.pause()

    def set_label_time(self):
        time_format_dict = self.format_time()
        hour = time_format_dict['hour']
        minute = time_format_dict['minute']
        second = time_format_dict['second']
        self.time_str.set('%d:%02d:%02d' % (hour, minute, second))

    def run_time(self):
        self.set_label_time()
        self.time_count -= 1

    def format_time(self):
        hour = self.time_count // 3600
        hour_mod = self.time_count % 3600
        minute = hour_mod // 60
        minute_mod = hour_mod % 60
        second = minute_mod % 60
        return {'hour': hour, 'minute': minute, 'second': second}

    def set_time(self, time_dict):
        self.time_count = time_dict['hour'] * 3600 + time_dict[
            'minute'] * 60 + time_dict['second']
        self.last_time_count = self.time_count

    def get_time(self):
        hour_text = self.input_hour.get()
        minute_text = self.input_minute.get()
        second_text = self.input_second.get()

        time_dict = {}
        time_dict['hour'] = int(hour_text)
        time_dict['minute'] = int(minute_text)
        time_dict['second'] = int(second_text)

        return time_dict

    def validate_time(self):
        result_dict = self.validate_hour()
        if not result_dict['accept']:
            showwarning('warning', result_dict['msg'])
            return False

        result_dict = self.validate_minute()
        if not result_dict['accept']:
            showwarning('warning', result_dict['msg'])
            return False

        result_dict = self.validate_second()
        if not result_dict['accept']:
            showwarning('warning', result_dict['msg'])
            return False

        return True

    def validate_hour(self):
        hour_str = self.input_hour.get()
        result_dict = {'accept': True, 'msg': None}
        if not hour_str.isdigit():
            result_dict['accept'] = False
            result_dict['msg'] = '小时数不为整数'
            return result_dict

        return result_dict

    def validate_minute(self):
        minute_str = self.input_minute.get()
        result_dict = {'accept': True, 'msg': None}
        if not minute_str.isdigit():
            result_dict['accept'] = False
            result_dict['msg'] = '分钟数不为整数'
            return result_dict

        minute_num = int(minute_str)
        if minute_num >= 60:
            result_dict['accept'] = False
            result_dict['msg'] = '分钟数不能大于等于60'
            return result_dict

        return result_dict

    def validate_second(self):
        second_str = self.input_second.get()
        result_dict = {'accept': True, 'msg': None}
        if not second_str.isdigit():
            result_dict['accept'] = False
            result_dict['msg'] = '秒数不为整数'
            return result_dict

        second_num = int(second_str)
        if second_num >= 60:
            result_dict['accept'] = False
            result_dict['msg'] = '秒数不能大于60'
            return result_dict

        return result_dict

    def edit(self):
        self.toggle_edit()

    def toggle_edit(self):
        if self.edit_status:
            self.switch_to_edit()
        else:
            self.completed_edit()

        self.edit_status = not self.edit_status

    def switch_to_edit(self):
        self.show_edit()
        self.start_button.config({'state': 'disabled'})
        self.force_pause()
        self.edit_str.set('保存')
        self.set_current_time_to_input()

    def force_pause(self):
        if self.current_status:
            self.toggle()

    def set_current_time_to_input(self):
        time_format_dict = self.format_time()
        hour = time_format_dict['hour']
        minute = time_format_dict['minute']
        second = time_format_dict['second']
        self.hour_str.set(hour)
        self.minute_str.set(minute)
        self.second_str.set(second)

    def completed_edit(self):
        if self.validate_time():
            self.set_time(self.get_time())
            self.edit_str.set('编辑')
            self.set_label_time()
            self.hide_edit()
            self.start_button.config({'state': 'normal'})
        else:
            self.edit_status = not self.edit_status

    def hide_edit(self):
        self.timer_frame.pack_forget()
        self.label.pack(side='top', fill='both', before=self.start_button)

    def show_edit(self):
        self.timer_frame.pack(side='top',
                              fill='both',
                              before=self.start_button)
        self.label.pack_forget()
Beispiel #28
0
class Interface(Tk):
  def __init__(self,parent):
    Tk.__init__(self,parent)
    self.parent = parent
    
    self.attributes('-fullscreen',True)
    self.currentScreem = ""
    self.titulos_treeview = ["Id", "Descricao", "Data"]

    self.menu()
    self.Home()

  def menu(self):
    topo = self.winfo_toplevel()
    self.menuBar = Menu(topo)

    mnuOpcoes = Menu(self.menuBar, tearoff=0)
    mnuOpcoes.add_command(label="Sair", command=self.processaSair)
    self.menuBar.add_cascade(label="Opções", menu=mnuOpcoes)

    topo.config(menu=self.menuBar)																							# Posiciona o menu no topo da janela
    
  def toobar(self,screem):
    self.toobarFrame = Frame(self)
    self.toobarFrame.pack(side="top",pady=5,fill="x")
    
    # Button de home
    self.homeB=Button(self.toobarFrame,justify = "left", command=self.Home)
    self.photoHome=PhotoImage(file="img/home.png")
    self.homeB.config(image=self.photoHome,width="20",height="20")
    self.homeB.pack(side="left", padx=5)
    if screem == "home":
      self.homeB.config(state="disabled")
    
    # Button de recarregar
    self.refreshB=Button(self.toobarFrame,justify = "left",command=self.atualizaTabela)
    self.photoRefresh=PhotoImage(file="img/refresh.png")
    self.refreshB.config(image=self.photoRefresh,width="20",height="20")
    self.refreshB.pack(side="left")
    if screem != "home":
      self.refreshB.config(state="disabled")

    # Entry de busca
    self.searchE = Entry(self.toobarFrame)
    self.searchE.pack(side="left",padx=5)
    self.searchE.bind("<Return>",lambda x: self.buscaComFiltro())
    if screem != "home":
      self.searchE.config(state="disabled")

    # Button de busca
    self.searchB=Button(self.toobarFrame,justify = "left",command=self.buscaComFiltro)
    self.photoSearch=PhotoImage(file="img/search.png")
    self.searchB.config(image=self.photoSearch,width="20",height="20")
    self.searchB.pack(side="left")
    if screem != "home":
      self.searchB.config(state="disabled")

    self.addB=Button(self.toobarFrame,justify = "left",command=self.Formulario)
    self.photoAdd=PhotoImage(file="img/add.png")
    self.addB.config(image=self.photoAdd,width="20",height="20")
    self.addB.pack(side="left", padx=5)
    if screem == "formulario":
      self.addB.config(state="disabled")
    
  def Home(self):
    if self.currentScreem == "formulario":
      self.toobarFrame.pack_forget()
      self.telaFormulario.pack_forget()
    
    self.toobar("home")
    
    self.telaHome = Frame(None)
    self.telaHome.pack(fill="both")

    self.tabela = ttk.Treeview(	self.telaHome,columns=self.titulos_treeview,show="headings")
    self.scbar = Scrollbar(self.telaHome,orient="vertical",command=self.tabela.yview)
    self.tabela.configure(yscrollcommand=self.scbar.set)
    
    self.scbar.pack(side="right", fill="y")
    self.tabela.pack(side="top", fill='both')

    self.atualizaTabela()

    self.currentScreem = "home"

  def Formulario(self,tarefa=[]):
    self.toobarFrame.pack_forget()
    self.telaHome.pack_forget()
    self.toobar("formulario")

    self.telaFormulario = Frame(None)
    self.telaFormulario.pack()

    self.btnAcao = Button(	self.telaFormulario,text="Cadastrar",command=self.cadastroTarefa)
    descricao = ""
    data = ""
    if tarefa != []:
      self.btnAcao = Button(	self.telaFormulario,text="Atualizar",command=self.cadastroTarefa)
      descricao = tarefa[1]
      data = tarefa[2]

    self.lblDescricao = Label(self.telaFormulario, text="Descrição")
    self.lblDescricao.pack()
    self.entryDescricao = Entry(self.telaFormulario)
    self.entryDescricao.insert(0,descricao)
    self.entryDescricao.pack()

    self.lblData= Label(self.telaFormulario,text="Data")
    self.lblData.pack()
    self.entryData = Entry(self.telaFormulario)
    self.entryData.insert(0,data)
    self.entryData.pack()
    
    if tarefa != []:
      self.tarefa_id = tarefa[0]
      self.btnAcao = Button(	self.telaFormulario,text="Atualizar",command=self.atualizarTarefa)
      self.btnExcluir = Button(	self.telaFormulario,text="Excluir",command=self.excluirTarefa)
      self.btnExcluir.pack(pady=10,side="bottom")
    self.btnAcao.pack(pady=10,side="bottom")


    self.lblres= Label(self.telaFormulario, text="")
    self.lblres.pack()

    self.currentScreem = "formulario"
    
  def clicarLinha(self, event):
    item = self.tabela.selection()
    for i in item:
      self.Formulario(self.tabela.item(i, "values"))

  def buscaSemFiltro(self):
    banco = Banco()
    try:
      c = banco.conexao.cursor()
      c.execute("select * from tarefas;")
      self.tarefas = []
      for linha in c:
        obj = {}
        obj["id"] = linha[0]
        obj["descricao"] = linha[1]
        obj["data"] = linha[2]
        self.tarefas.append(obj)
      c.close()
      print("Busca sem filtro feita com sucesso!")
    except:
      print("Ocorreu um erro na busca do usuário")
    
  def atualizaTabela(self):
    self.buscaSemFiltro()
    self.mostrarTarefas(self.tarefas)

  def buscaComFiltro(self):
    busca = self.searchE.get()
    self.searchE.delete("0", "end")
    filmes_busca = []
    banco = Banco()
    try:
      c = banco.conexao.cursor()
      query = "select * from tarefas where id like '%{0}%' or descricao like '%{0}%' or data like '%{0}%';".format(busca)
      c.execute(query)
      for linha in c:
        obj = {}
        obj["id"] = linha[0]
        obj["descricao"] = linha[1]
        obj["data"] = linha[2]
        filmes_busca.append(obj)
      c.close()
      print("Busca com filtro feita com sucesso!")
    except:
      print("Ocorreu um erro na busca do usuário")

    self.mostrarTarefas(filmes_busca)

  def mostrarTarefas(self, tarefas):
    for i in self.tabela.get_children():
      self.tabela.delete(i)
    
    for col in self.titulos_treeview:
      self.tabela.heading(col, text=col.title())

    for tarefa in tarefas:
      item = (tarefa['id'], tarefa['descricao'], tarefa['data'])
      self.tabela.insert('', 'end', values=item)
    
    self.tabela.pack(side="top", fill='both')
    self.tabela.bind("<Double-1>", self.clicarLinha)
    
  def cadastroTarefa(self):
    descricao = self.entryDescricao.get()
    data = self.entryData.get()

    if len(descricao)<1 or len(data)<1:
      self.changeMSG("Todos os campos devem ser preenchidos",'red')
    else:
      banco = Banco()
      try:
        c = banco.conexao.cursor()
        query = "insert into tarefas (descricao,data) values ('{0}','{1}');".format(descricao,data)
        c.execute(query)
        banco.conexao.commit()
        if c.lastrowid > 0:
          self.changeMSG("Tarefa cadastrado com sucesso","green")
          self.entryDescricao.delete("0","end")
          self.entryData.delete("0","end")
          print("sucesso")
        else:
          print("erro")
          self.changeMSG("Ocorreu um erro no cadastro da tarefa","red")
        c.close()
      except:
        print("exceção")
        self.changeMSG("Ocorreu um erro no cadastro da tarefa","red")
  
  def atualizarTarefa(self):
    descricao = self.entryDescricao.get()
    data = self.entryData.get()

    if len(descricao)<1 or len(data)<1:
      self.changeMSG("Todos os campos devem ser preenchidos",'red')
    else:
      banco = Banco()
      try:
        c = banco.conexao.cursor()
        query = "update tarefas set descricao = '{0}',data = '{1}' where id = {2};".format(descricao,data,self.tarefa_id)
        c.execute(query)
        banco.conexao.commit()
        self.changeMSG("Tarefa atualizada com sucesso","green")
        self.entryDescricao.delete("0","end")
        self.entryData.delete("0","end")
        print("sucesso")
        c.close()
      except:
        print("exceção")
        self.changeMSG("Ocorreu um erro no cadastro da tarefa","red")
    self.tarefa_id = 0

  def excluirTarefa(self):
    banco = Banco()
    try:
      c = banco.conexao.cursor()
      query = "delete from tarefas where id ={0};".format(self.tarefa_id)
      c.execute(query)
      banco.conexao.commit()
      self.changeMSG("Tarefa excluida com sucesso","green")
      self.entryDescricao.delete("0","end")
      self.entryData.delete("0","end")
      print("sucesso")
      c.close()
    except:
      print("exceção")
      self.changeMSG("Ocorreu um erro no cadastro da tarefa","red")
    self.tarefa_id = 0

  def changeMSG(self,texto,color):
    self.lblres.destroy()

    self.lblres= Label(self.telaFormulario, text=texto,bg='{}'.format(color))

    self.lblres.pack(pady=5, side="bottom")

  def processaSair(self):
    self.destroy()
Beispiel #29
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()
Beispiel #30
0
class QuantMonitor(object):

    # 背景色
    bgColor = rgb_to_hex(245, 245, 245)
    bgColorW = "white"

    def __init__(self, frame, control, language):
        self.parentFrame = frame
        self._controller = control
        self.language = language

        # 初始化策略状态字典
        self._initStrategyStatus()
        # 策略编号初始值
        self._strategyNum = 1

        # Monitor不同标签的背景色
        self.rColor = self.bgColorW
        self.lColor = self.bgColor
        self.sColor = self.bgColor
        self.eColor = self.bgColor

        self.createButtonFrame()

        # 执行列表、监控日志、信号记录、错误
        self.executeList = Frame(self.parentFrame)
        self.monitorLog = Frame(self.parentFrame)
        self.sigRecord = Frame(self.parentFrame)
        self.errRecord = Frame(self.parentFrame)

        self.executeList.pack(side=TOP, fill=BOTH, expand=YES)

        self.monText = None
        self.sigText = None
        self.errText = None

    def createButtonFrame(self):
        btnFrame = Frame(self.parentFrame, height=30, bg=self.bgColor)
        btnFrame.pack_propagate(0)
        btnFrame.pack(side=TOP, fill=X)
        # 利用frame做出button的黑色边框
        # f1 = Frame(btnFrame, highlightbackground="black", highlightthickness=1, bd=0)
        # f1.pack(side=LEFT)

        self.runBtn = Button(btnFrame, text="策略运行", relief=FLAT, padx=14, pady=1.5, bg=self.rColor,
                             bd=0, highlightthickness=1, command=self.toMonFrame)
        self.logBtn = Button(btnFrame, text="运行日志", relief=FLAT, padx=14, pady=1.5, bg=self.lColor,
                             bd=0, highlightthickness=1,
                             command=self.toLogFrame)
        self.sigBtn = Button(btnFrame, text="信号记录", relief=FLAT, padx=14, pady=1.5, bg=self.sColor,
                             bd=0, highlightthickness=1,  command=self.toSigFrame)
        self.errBtn = Button(btnFrame, text="错误信息", relief=FLAT, padx=14, pady=1.5, bg=self.eColor,
                             bd=0, highlightthickness=1, command=self.toErrFrame)
        self.runBtn.pack(side=LEFT, expand=NO)
        self.logBtn.pack(side=LEFT, expand=NO)
        self.sigBtn.pack(side=LEFT, expand=NO)
        self.errBtn.pack(side=LEFT, expand=NO)

        for btn in (self.runBtn, self.logBtn, self.sigBtn, self.errBtn):
            btn.bind("<Enter>", self.handlerAdaptor(self.onEnter, button=btn))
            btn.bind("<Leave>", self.handlerAdaptor(self.onLeave, button=btn))

    def createMonitor(self):
        # monitorRightBar = Scrollbar(self.monitorLog)
        # monitorRightBar.pack(side=RIGHT, fill=Y), yscrollcommand=monitorRightBar.set

        self.monText = MonitorText(self.monitorLog, height=20, bd=0)
        self.monText.createScrollbar()
        self.monText.pack(fill=BOTH, expand=YES)

    def createSignal(self):
        self.sigText = SignalText(self.sigRecord, height=20, bd=0)
        self.sigText.createScrollbar()
        self.sigText.pack(fill=BOTH, expand=YES)

    def createExecute(self):
        # headList = ["编号", "策略名称", "策略状态", "最终权益", "胜率", "净利润", "总盈利", "总亏损", "可用资金",
        #              "夏普比率", "风险率", "手续费", "最大资产回撤", "最大资产回撤时间", "资产最大值", "资产最小值",
        #              "最大连续盈利次数", "最大连续亏损次数"]
        # headList = ["编号", "策略名称", "策略状态", "频率","保证金比例", "手续费",
        #             "初始资金", "总盈利", "总亏损", "可用资金"]
        # headList = ["编号", "策略名称", "策略状态", "运行类型", "初始资金", "合约", "开始时间", "结束时间", "权益"]
        headList = ["编号", "策略名称", "合约", "运行状态", "实盘运行"]

        self.executeBar = ttk.Scrollbar(self.executeList, orient="vertical")
        self.executeBar.pack(side=RIGHT, fill=Y)

        self.executeListTree = ttk.Treeview(self.executeList, show="headings", height=28, columns=tuple(headList),
                                            yscrollcommand=self.executeBar.set, style="Filter.Treeview")
        self.executeBar.config(command=self.executeListTree.yview)
        self.executeListTree.pack(fill=BOTH, expand=YES)

        self.executeListTree.bind("<Button-3>", self.createMenu)

        for key in tuple(headList):
            self.executeListTree.column(key, minwidth=20, width=55, anchor=CENTER)
            self.executeListTree.heading(key, text=key)

    def createMenu(self, event):
        """创建运行策略右键菜单"""
        RunMenu(self._controller, self.executeListTree).popupmenu(event)

    def _initStrategyStatus(self):
        self.statusDict = {
            ST_STATUS_NONE:         "初始状态",
            ST_STATUS_HISTORY:      "历史回测",
            ST_STATUS_CONTINUES:    "实时触发",
            ST_STATUS_PAUSE:        "暂停",
            ST_STATUS_QUIT:         "停止"
        }

    def _getStrategyStatus(self, key):
        return self.statusDict[key]

    def _formatMonitorInfo(self, dataDict):
        """
        格式化监控需要的信息
        :param dataDict: 策略的所有信息
        :return: 需要展示的信息
        """
        status = self._getStrategyStatus(dataDict["StrategyState"])
        runType = "是" if dataDict['Config']['RunMode']['Actual']['SendOrder2Actual'] else "否"

        values = [
            dataDict['StrategyId'],
            dataDict['StrategyName'],
            dataDict['Config']['Contract'],
            status,
            runType,
        ]

        return values

    def updateSingleExecute(self, dataDict):
        values = self._formatMonitorInfo(dataDict)
        self.executeListTree.insert("", END, iid=dataDict['StrategyId'], values=tuple(values), tag=0)

    def createErr(self):
        # 错误信息展示
        self.errText = ErrorText(self.errRecord, height=20, bd=0)
        self.errText.createScrollbar()
        self.errText.pack(fill=BOTH, expand=YES)

    def updateRun(self):
        pass

    def updateLogText(self):
        guiQueue = self._controller.get_logger().getGuiQ()

        try:
            data = guiQueue.get_nowait()
        except:
            return
        else:
            self.monText.setText(data)

    def updateSigText(self):
        sigQueue = self._controller.get_logger().getSigQ()
        try:
            sigData = sigQueue.get_nowait()
        except:
            return
        else:
            # self.toSigFrame()
            self.sigText.setText(sigData)

    def updateErrText(self):
        errQueue = self._controller.get_logger().getErrQ()
        try:
            errData = errQueue.get_nowait()
        except:
            return
        else:
            self.toErrFrame()
            self.errText.setText(errData)

    def toMonFrame(self):
        self.runBtn.config(bg="white")
        self.rColor = self.runBtn['bg']
        self.lColor = self.bgColor
        self.sColor = self.bgColor
        self.eColor = self.bgColor
        self.errBtn.config(bg=self.rColor)
        self.sigBtn.config(bg=self.sColor)
        self.logBtn.config(bg=self.lColor)
        self.monitorLog.pack_forget()
        self.sigRecord.pack_forget()
        self.errRecord.pack_forget()
        self.executeList.pack(side=TOP, fill=BOTH, expand=YES)

    def toLogFrame(self):
        self.logBtn.config(bg="white")
        self.lColor = self.logBtn['bg']
        self.rColor = self.bgColor
        self.sColor = self.bgColor
        self.eColor = self.bgColor
        self.runBtn.config(bg=self.rColor)
        self.sigBtn.config(bg=self.sColor)
        self.errBtn.config(bg=self.eColor)
        self.sigRecord.pack_forget()
        self.executeList.pack_forget()
        self.errRecord.pack_forget()
        self.monitorLog.pack(side=TOP, fill=BOTH, expand=YES)

    def toSigFrame(self):
        self.sigBtn.config(bg="white")
        self.sColor = self.sigBtn['bg']
        self.lColor = self.bgColor
        self.rColor = self.bgColor
        self.eColor = self.bgColor
        self.runBtn.config(bg=self.rColor)
        self.logBtn.config(bg=self.lColor)
        self.errBtn.config(bg=self.eColor)
        self.monitorLog.pack_forget()
        self.executeList.pack_forget()
        self.errRecord.pack_forget()
        self.sigRecord.pack(side=TOP, fill=BOTH, expand=YES)

    def toErrFrame(self):
        self.errBtn.config(bg="white")
        self.eColor = self.errBtn['bg']
        self.lColor = self.bgColor
        self.rColor = self.bgColor
        self.sColor = self.bgColor
        self.runBtn.config(bg=self.rColor)
        self.sigBtn.config(bg=self.sColor)
        self.logBtn.config(bg=self.lColor)
        self.parentFrame.update()
        self.monitorLog.pack_forget()
        self.executeList.pack_forget()
        self.sigRecord.pack_forget()
        self.errRecord.pack(side=TOP, fill=BOTH, expand=YES)

    def handlerAdaptor(self, fun, **kwargs):
        return lambda event, fun=fun, kwargs=kwargs: fun(event, **kwargs)

    def onEnter(self, event, button):
        if button == self.runBtn:
            button.config(bg='white')
            self.logBtn.config(bg=self.bgColor)
            self.sigBtn.config(bg=self.bgColor)
            self.errBtn.config(bg=self.bgColor)
        elif button == self.logBtn:
            button.config(bg='white')
            self.runBtn.config(bg=self.bgColor)
            self.sigBtn.config(bg=self.bgColor)
            self.errBtn.config(bg=self.bgColor)
        elif button == self.sigBtn:
            button.config(bg='white')
            self.runBtn.config(bg=self.bgColor)
            self.logBtn.config(bg=self.bgColor)
            self.errBtn.config(bg=self.bgColor)
        else:
            button.config(bg='white')
            self.runBtn.config(bg=self.bgColor)
            self.logBtn.config(bg=self.bgColor)
            self.sigBtn.config(bg=self.bgColor)

    def onLeave(self, event, button):
        button.config(bg=rgb_to_hex(227, 230, 233))
        if button == self.runBtn:
            button['bg'] = self.rColor
            self.logBtn['bg'] = self.lColor
            self.sigBtn['bg'] = self.sColor
            self.errBtn['bg'] = self.eColor
        elif button == self.logBtn:
            button['bg'] = self.lColor
            self.runBtn['bg'] = self.rColor
            self.sigBtn['bg'] = self.sColor
            self.errBtn['bg'] = self.eColor
        elif button == self.sigBtn:
            button['bg'] = self.sColor
            self.runBtn['bg'] = self.rColor
            self.logBtn['bg'] = self.lColor
            self.errBtn['bg'] = self.eColor
        else:
            button['bg'] = self.eColor
            self.runBtn['bg'] = self.rColor
            self.logBtn['bg'] = self.lColor
            self.sigBtn['bg'] = self.sColor

    def deleteStrategy(self, strategyId):
        """删除策略"""
        self.executeListTree.delete(strategyId)

    def updateStatus(self, strategyId, dataDict):
        """更新策略ID对应的策略状态"""
        values = self._formatMonitorInfo(dataDict)
        self.executeListTree.item(strategyId, values=values)
        # self.executeListTree.update()
Beispiel #31
0
class Application(Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.pack()

        # First row
        f1 = LabelFrame(self,
                        text='NAND file with No$GBA footer',
                        padx=10,
                        pady=10)

        # NAND Button
        self.nand_mode = False

        nand_icon = PhotoImage(
            data=('R0lGODlhEAAQAIMAAAAAADMzM2ZmZpmZmczMzP///wAAAAAAAAA'
                  'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAMAAAYALAAAAAAQAB'
                  'AAAARG0MhJaxU4Y2sECAEgikE1CAFRhGMwSMJwBsU6frIgnR/bv'
                  'hTPrWUSDnGw3JGU2xmHrsvyU5xGO8ql6+S0AifPW8kCKpcpEQA7'))

        self.nand_button = Button(f1,
                                  image=nand_icon,
                                  command=self.change_mode,
                                  state=DISABLED)
        self.nand_button.image = nand_icon

        self.nand_button.pack(side='left')

        self.nand_file = StringVar()
        Entry(f1, textvariable=self.nand_file, state='readonly',
              width=40).pack(side='left')

        Button(f1, text='...', command=self.choose_nand).pack(side='left')

        f1.pack(padx=10, pady=10, fill=X)

        # Second row
        f2 = Frame(self)

        # Check boxes
        self.checks_frame = Frame(f2)

        # Install TWiLight check
        self.twilight = IntVar()
        self.twilight.set(1)

        twl_chk = Checkbutton(
            self.checks_frame,
            text='Install latest TWiLight Menu++ on custom firmware',
            variable=self.twilight)

        twl_chk.pack(padx=10, anchor=W)

        # Clean files check
        self.clean_downloaded = IntVar()
        self.clean_downloaded.set(1)

        clean_chk = Checkbutton(self.checks_frame,
                                text='Clean downloaded files after completion',
                                variable=self.clean_downloaded)

        clean_chk.pack(padx=10, anchor=W)

        self.checks_frame.pack(fill=X)

        # NAND operation frame
        self.nand_frame = LabelFrame(f2,
                                     text='NAND operation',
                                     padx=10,
                                     pady=10)

        self.nand_operation = IntVar()
        self.nand_operation.set(0)

        Radiobutton(self.nand_frame,
                    text='Remove No$GBA footer',
                    variable=self.nand_operation,
                    value=0,
                    command=lambda: self.enable_entries(False)).pack(anchor=W)

        Radiobutton(self.nand_frame,
                    text='Add No$GBA footer',
                    variable=self.nand_operation,
                    value=1,
                    command=lambda: self.enable_entries(True)).pack(anchor=W)

        fl = Frame(self.nand_frame)

        self.cid_label = Label(fl, text='eMMC CID', state=DISABLED)
        self.cid_label.pack(anchor=W, padx=(24, 0))

        self.cid = StringVar()
        self.cid_entry = Entry(fl,
                               textvariable=self.cid,
                               width=20,
                               state=DISABLED)
        self.cid_entry.pack(anchor=W, padx=(24, 0))

        fl.pack(side='left')

        fr = Frame(self.nand_frame)

        self.console_id_label = Label(fr, text='Console ID', state=DISABLED)
        self.console_id_label.pack(anchor=W)

        self.console_id = StringVar()
        self.console_id_entry = Entry(fr,
                                      textvariable=self.console_id,
                                      width=20,
                                      state=DISABLED)
        self.console_id_entry.pack(anchor=W)

        fr.pack(side='right')

        f2.pack(fill=X)

        # Third row
        f3 = Frame(self)

        self.start_button = Button(f3,
                                   text='Start',
                                   width=16,
                                   command=self.hiya,
                                   state=DISABLED)
        self.start_button.pack(side='left', padx=(0, 5))

        Button(f3, text='Quit', command=root.destroy,
               width=16).pack(side='left', padx=(5, 0))

        f3.pack(pady=(10, 20))

        self.folders = []
        self.files = []

    ################################################################################################
    def change_mode(self):
        if (self.nand_mode):
            self.nand_frame.pack_forget()
            self.checks_frame.pack(padx=10, anchor=W)
            self.nand_mode = False

        else:
            if askokcancel(
                    'Warning',
                ('You are about to enter NAND mode. Do it only if you know '
                 'what you are doing. Proceed?'),
                    icon=WARNING):
                self.checks_frame.pack_forget()
                self.nand_frame.pack(padx=10, pady=(0, 10), fill=X)
                self.nand_mode = True

    ################################################################################################
    def enable_entries(self, status):
        self.cid_label['state'] = (NORMAL if status else DISABLED)
        self.cid_entry['state'] = (NORMAL if status else DISABLED)
        self.console_id_label['state'] = (NORMAL if status else DISABLED)
        self.console_id_entry['state'] = (NORMAL if status else DISABLED)

    ################################################################################################
    def choose_nand(self):
        name = askopenfilename(filetypes=(('nand.bin', '*.bin'), ('DSi-1.mmc',
                                                                  '*.mmc')))
        self.nand_file.set(name)

        self.nand_button['state'] = (NORMAL if name != '' else DISABLED)
        self.start_button['state'] = (NORMAL if name != '' else DISABLED)

    ################################################################################################
    def hiya(self):
        if not self.nand_mode:
            showinfo(
                'Info',
                'Now you will be asked to choose the SD card path that will be used '
                'for installing the custom firmware (or an output folder).\n\nIn order to avoid '
                'boot errors please assure it is empty before continuing.')
            self.sd_path = askdirectory()

            # Exit if no path was selected
            if self.sd_path == '':
                return

        # If adding a No$GBA footer, check if CID and ConsoleID values are OK
        elif self.nand_operation.get() == 1:
            cid = self.cid.get()
            console_id = self.console_id.get()

            # Check lengths
            if len(cid) != 32:
                showerror('Error', 'Bad eMMC CID')
                return

            elif len(console_id) != 16:
                showerror('Error', 'Bad Console ID')
                return

            # Parse strings to hex
            try:
                cid = bytearray.fromhex(cid)

            except ValueError:
                showerror('Error', 'Bad eMMC CID')
                return

            try:
                console_id = bytearray(reversed(bytearray.fromhex(console_id)))

            except ValueError:
                showerror('Error', 'Bad Console ID')
                return

        dialog = Toplevel(self)
        # Open as dialog (parent disabled)
        dialog.grab_set()
        dialog.title('Status')
        # Disable maximizing
        dialog.resizable(0, 0)

        frame = Frame(dialog, bd=2, relief=SUNKEN)

        scrollbar = Scrollbar(frame)
        scrollbar.pack(side=RIGHT, fill=Y)

        self.log = ThreadSafeText(frame,
                                  bd=0,
                                  width=52,
                                  height=20,
                                  yscrollcommand=scrollbar.set)
        self.log.pack()

        scrollbar.config(command=self.log.yview)

        frame.pack()

        Button(dialog, text='Close', command=dialog.destroy,
               width=16).pack(pady=10)

        # Center in window
        dialog.update_idletasks()
        width = dialog.winfo_width()
        height = dialog.winfo_height()
        dialog.geometry(
            '%dx%d+%d+%d' %
            (width, height, root.winfo_x() + (root.winfo_width() / 2) -
             (width / 2), root.winfo_y() + (root.winfo_height() / 2) -
             (height / 2)))

        # Check if we'll be adding a No$GBA footer
        if self.nand_mode and self.nand_operation.get() == 1:
            Thread(target=self.add_footer, args=(cid, console_id)).start()

        else:
            Thread(target=self.check_nand).start()

    ################################################################################################
    def check_nand(self):
        self.log.write('Checking NAND file...')

        # Read the NAND file
        try:
            with open(self.nand_file.get(), 'rb') as f:
                # Go to the No$GBA footer offset
                f.seek(-64, 2)
                # Read the footer's header :-)
                bstr = f.read(0x10)

                if bstr == b'DSi eMMC CID/CPU':
                    # Read the CID
                    bstr = f.read(0x10)
                    self.cid.set(bstr.hex().upper())
                    self.log.write('- eMMC CID: ' + self.cid.get())

                    # Read the console ID
                    bstr = f.read(8)
                    self.console_id.set(
                        bytearray(reversed(bstr)).hex().upper())
                    self.log.write('- Console ID: ' + self.console_id.get())

                    # Check we are removing the No$GBA footer
                    if self.nand_mode:
                        Thread(target=self.remove_footer).start()

                    else:
                        Thread(target=self.get_latest_hiyacfw).start()

                else:
                    self.log.write('ERROR: No$GBA footer not found')

        except IOError as e:
            print(e)
            self.log.write('ERROR: Could not open the file ' +
                           path.basename(self.nand_file.get()))

    ################################################################################################
    def get_latest_hiyacfw(self):
        # Try to use already downloaded hiyaCFW archive
        filename = 'hiyaCFW.7z'

        try:
            if path.isfile(filename):
                self.log.write('\nPreparing hiyaCFW...')

            else:
                self.log.write('\nDownloading latest hiyaCFW release...')

                with urlopen(
                        'https://github.com/RocketRobz/hiyaCFW/releases/latest/download/'
                        + filename) as src, open(filename, 'wb') as dst:
                    copyfileobj(src, dst)

            self.log.write('- Extracting hiyaCFW archive...')

            proc = Popen([
                _7za, 'x', '-bso0', '-y', filename, 'for PC',
                'for SDNAND SD card'
            ])

            ret_val = proc.wait()

            if ret_val == 0:
                if self.clean_downloaded.get() == 1:
                    self.files.append(filename)
                self.folders.append('for PC')
                self.folders.append('for SDNAND SD card')
                # Got to decrypt NAND if bootloader.nds is present
                Thread(target=self.decrypt_nand if path.isfile(
                    'bootloader.nds') else self.extract_bios).start()

            else:
                self.log.write('ERROR: Extractor failed')

        except (URLError, IOError) as e:
            print(e)
            self.log.write('ERROR: Could not get hiyaCFW')

        except OSError as e:
            print(e)
            self.log.write('ERROR: Could not execute ' + exe)

    ################################################################################################
    def extract_bios(self):
        self.log.write('\nExtracting ARM7/ARM9 BIOS from NAND...')

        try:
            proc = Popen([twltool, 'boot2', '--in', self.nand_file.get()])

            ret_val = proc.wait()

            if ret_val == 0:
                # Hash arm7.bin
                sha1_hash = sha1()

                with open('arm7.bin', 'rb') as f:
                    sha1_hash.update(f.read())

                self.log.write('- arm7.bin SHA1:\n  ' +
                               sha1_hash.digest().hex().upper())

                # Hash arm9.bin
                sha1_hash = sha1()

                with open('arm9.bin', 'rb') as f:
                    sha1_hash.update(f.read())

                self.log.write('- arm9.bin SHA1:\n  ' +
                               sha1_hash.digest().hex().upper())

                self.files.append('arm7.bin')
                self.files.append('arm9.bin')

                Thread(target=self.patch_bios).start()

            else:
                self.log.write('ERROR: Extractor failed')
                Thread(target=self.clean, args=(True, )).start()

        except OSError as e:
            print(e)
            self.log.write('ERROR: Could not execute ' + exe)
            Thread(target=self.clean, args=(True, )).start()

    ################################################################################################
    def patch_bios(self):
        self.log.write('\nPatching ARM7/ARM9 BIOS...')

        try:
            self.patcher(
                path.join('for PC', 'bootloader files',
                          'bootloader arm7 patch.ips'), 'arm7.bin')

            self.patcher(
                path.join('for PC', 'bootloader files',
                          'bootloader arm9 patch.ips'), 'arm9.bin')

            # Hash arm7.bin
            sha1_hash = sha1()

            with open('arm7.bin', 'rb') as f:
                sha1_hash.update(f.read())

            self.log.write('- Patched arm7.bin SHA1:\n  ' +
                           sha1_hash.digest().hex().upper())

            # Hash arm9.bin
            sha1_hash = sha1()

            with open('arm9.bin', 'rb') as f:
                sha1_hash.update(f.read())

            self.log.write('- Patched arm9.bin SHA1:\n  ' +
                           sha1_hash.digest().hex().upper())

            Thread(target=self.arm9_prepend).start()

        except IOError as e:
            print(e)
            self.log.write('ERROR: Could not patch BIOS')
            Thread(target=self.clean, args=(True, )).start()

        except Exception as e:
            print(e)
            self.log.write('ERROR: Invalid patch header')
            Thread(target=self.clean, args=(True, )).start()

    ################################################################################################
    def arm9_prepend(self):
        self.log.write('\nPrepending data to ARM9 BIOS...')

        try:
            with open('arm9.bin', 'rb') as f:
                data = f.read()

            with open('arm9.bin', 'wb') as f:
                with open(
                        path.join('for PC', 'bootloader files',
                                  'bootloader arm9 append to start.bin'),
                        'rb') as pre:
                    f.write(pre.read())

                f.write(data)

            # Hash arm9.bin
            sha1_hash = sha1()

            with open('arm9.bin', 'rb') as f:
                sha1_hash.update(f.read())

            self.log.write('- Prepended arm9.bin SHA1:\n  ' +
                           sha1_hash.digest().hex().upper())

            Thread(target=self.make_bootloader).start()

        except IOError as e:
            print(e)
            self.log.write('ERROR: Could not prepend data to ARM9 BIOS')
            Thread(target=self.clean, args=(True, )).start()

    ################################################################################################
    def make_bootloader(self):
        self.log.write('\nGenerating new bootloader...')

        exe = (path.join('for PC', 'bootloader files', 'ndstool.exe')
               if sysname == 'Windows' else path.join(sysname, 'ndsblc'))

        try:
            proc = Popen([
                exe, '-c', 'bootloader.nds', '-9', 'arm9.bin', '-7',
                'arm7.bin', '-t',
                path.join('for PC', 'bootloader files', 'banner.bin'), '-h',
                path.join('for PC', 'bootloader files', 'header.bin')
            ])

            ret_val = proc.wait()

            if ret_val == 0:
                self.files.append('bootloader.nds')

                # Hash bootloader.nds
                sha1_hash = sha1()

                with open('bootloader.nds', 'rb') as f:
                    sha1_hash.update(f.read())

                self.log.write('- bootloader.nds SHA1:\n  ' +
                               sha1_hash.digest().hex().upper())

                Thread(target=self.decrypt_nand).start()

            else:
                self.log.write('ERROR: Generator failed')
                Thread(target=self.clean, args=(True, )).start()

        except OSError as e:
            print(e)
            self.log.write('ERROR: Could not execute ' + exe)
            Thread(target=self.clean, args=(True, )).start()

    ################################################################################################
    def decrypt_nand(self):
        self.log.write('\nDecrypting NAND...')

        try:
            proc = Popen([
                twltool, 'nandcrypt', '--in',
                self.nand_file.get(), '--out',
                self.console_id.get() + '.img'
            ])

            ret_val = proc.wait()
            print("\n")

            if ret_val == 0:
                self.files.append(self.console_id.get() + '.img')

                Thread(target=self.win_extract_nand if (
                    sysname == 'Windows' and _7z is not None
                ) else self.extract_nand).start()

            else:
                self.log.write('ERROR: Decryptor failed')
                Thread(target=self.clean, args=(True, )).start()

        except OSError as e:
            print(e)
            self.log.write('ERROR: Could not execute ' + exe)
            Thread(target=self.clean, args=(True, )).start()

    ################################################################################################
    def win_extract_nand(self):
        self.log.write('\nExtracting files from NAND...')

        try:
            proc = Popen([
                _7z, 'x', '-bso0', '-y',
                self.console_id.get() + '.img', '0.fat'
            ])

            ret_val = proc.wait()

            if ret_val == 0:
                self.files.append('0.fat')

                proc = Popen(
                    [_7z, 'x', '-bso0', '-y', '-o' + self.sd_path, '0.fat'])

                ret_val = proc.wait()

                if ret_val == 0:
                    Thread(target=self.get_launcher).start()

                else:
                    self.log.write(
                        'ERROR: Extractor failed, please update 7-Zip')

                    if path.exists(fatcat):
                        self.log.write('\nTrying with fatcat...')
                        Thread(target=self.extract_nand).start()

                    else:
                        Thread(target=self.clean, args=(True, )).start()

            else:
                self.log.write('ERROR: Extractor failed')

                if path.exists(fatcat):
                    self.log.write('\nTrying with fatcat...')
                    Thread(target=self.extract_nand).start()

                else:
                    Thread(target=self.clean, args=(True, )).start()

        except OSError as e:
            print(e)
            self.log.write('ERROR: Could not execute ' + exe)

            if path.exists(fatcat):
                self.log.write('\nTrying with fatcat...')
                Thread(target=self.extract_nand).start()

            else:
                Thread(target=self.clean, args=(True, )).start()

    ################################################################################################
    def extract_nand(self):
        self.log.write('\nExtracting files from NAND...')

        try:
            # DSi first partition offset: 0010EE00h
            proc = Popen([
                fatcat, '-O', '1109504', '-x', self.sd_path,
                self.console_id.get() + '.img'
            ])

            ret_val = proc.wait()

            if ret_val == 0:
                Thread(target=self.get_launcher).start()

            else:
                self.log.write('ERROR: Extractor failed')
                Thread(target=self.clean, args=(True, )).start()

        except OSError as e:
            print(e)
            self.log.write('ERROR: Could not execute ' + exe)
            Thread(target=self.clean, args=(True, )).start()

    ################################################################################################
    def get_launcher(self):
        app = self.detect_region()

        # Stop if no supported region was found
        if not app:
            Thread(target=self.clean, args=(True, )).start()
            return

        # Delete contents of the launcher folder as it will be replaced by the one from hiyaCFW
        launcher_folder = path.join(self.sd_path, 'title', '00030017', app,
                                    'content')

        # Walk through all files in the launcher content folder
        for file in listdir(launcher_folder):
            file = path.join(launcher_folder, file)

            # Set current file as read/write in case we extracted with 7-Zip and unlaunch was
            # installed in the NAND. Fatcat doesn't keep file attributes
            if _7z is not None:
                chmod(file, 438)

            # Delete current file
            remove(file)

        # Try to use already downloaded launcher
        try:
            if path.isfile(self.launcher_region):
                self.log.write('\nPreparing ' + self.launcher_region +
                               ' launcher...')

            else:
                self.log.write('\nDownloading ' + self.launcher_region +
                               ' launcher...')

                with urlopen('https://raw.githubusercontent.com'
                             '/mondul/HiyaCFW-Helper/master/launchers/' +
                             self.launcher_region) as src, open(
                                 self.launcher_region, 'wb') as dst:
                    copyfileobj(src, dst)

            self.log.write('- Decrypting launcher...')

            # Set launcher filename according to the region
            launcher_app = ('00000000.app' if self.launcher_region
                            in ('CHN', 'KOR') else '00000002.app')

            # Prepare decryption params
            params = [
                _7za, 'x', '-bso0', '-y', '-p' + app.lower(),
                self.launcher_region, launcher_app
            ]

            if launcher_app == '00000000.app':
                params.append('title.tmd')

            proc = Popen(params)

            ret_val = proc.wait()

            if ret_val == 0:
                if self.clean_downloaded.get() == 1:
                    self.files.append(self.launcher_region)
                self.files.append(launcher_app)

                if launcher_app == '00000000.app':
                    self.files.append('title.tmd')

                # Hash launcher app
                sha1_hash = sha1()

                with open(launcher_app, 'rb') as f:
                    sha1_hash.update(f.read())

                self.log.write('- Patched launcher SHA1:\n  ' +
                               sha1_hash.digest().hex().upper())

                Thread(target=self.install_hiyacfw,
                       args=(launcher_app, launcher_folder)).start()

            else:
                self.log.write('ERROR: Extractor failed')
                Thread(target=self.clean, args=(True, )).start()

        except IOError as e:
            print(e)
            self.log.write('ERROR: Could not download ' +
                           self.launcher_region + ' launcher')
            Thread(target=self.clean, args=(True, )).start()

        except OSError as e:
            print(e)
            self.log.write('ERROR: Could not execute ' + exe)
            Thread(target=self.clean, args=(True, )).start()

    ################################################################################################
    def install_hiyacfw(self, launcher_app, launcher_folder):
        self.log.write('\nCopying HiyaCFW files...')

        # Reset copied files cache
        _path_created.clear()

        copy_tree('for SDNAND SD card', self.sd_path, update=1)
        copyfile('bootloader.nds',
                 path.join(self.sd_path, 'hiya', 'bootloader.nds'))
        copyfile(launcher_app, path.join(launcher_folder, launcher_app))

        if launcher_app == '00000000.app':
            copyfile('title.tmd', path.join(launcher_folder, 'title.tmd'))

        Thread(target=self.get_latest_twilight if self.twilight.get() ==
               1 else self.clean).start()

    ################################################################################################
    def get_latest_twilight(self):
        # Try to use already downloaded TWiLight Menu++ archive
        filename = 'TWiLightMenu.7z'

        try:
            if path.isfile(filename):
                self.log.write('\nPreparing TWiLight Menu++...')

            else:
                self.log.write(
                    '\nDownloading latest TWiLight Menu++ release...')

                with urlopen(
                        'https://github.com/DS-Homebrew/TWiLightMenu/releases/latest/download/'
                        + filename) as src, open(filename, 'wb') as dst:
                    copyfileobj(src, dst)

            self.log.write('- Extracting ' + filename[:-3] + ' archive...')

            proc = Popen([
                _7za, 'x', '-bso0', '-y', filename, '_nds', 'DSi - CFW users',
                'DSi&3DS - SD card users', 'roms'
            ])

            ret_val = proc.wait()

            if ret_val == 0:
                if self.clean_downloaded.get() == 1:
                    self.files.append(filename)
                self.folders.append('DSi - CFW users')
                self.folders.append('_nds')
                self.folders.append('DSi&3DS - SD card users')
                self.folders.append('roms')
                Thread(target=self.install_twilight,
                       args=(filename[:-3], )).start()

            else:
                self.log.write('ERROR: Extractor failed')
                Thread(target=self.clean, args=(True, )).start()

        except (URLError, IOError) as e:
            print(e)
            self.log.write('ERROR: Could not get TWiLight Menu++')
            Thread(target=self.clean, args=(True, )).start()

        except OSError as e:
            print(e)
            self.log.write('ERROR: Could not execute ' + exe)
            Thread(target=self.clean, args=(True, )).start()

    ################################################################################################
    def install_twilight(self, name):
        self.log.write('\nCopying ' + name + ' files...')

        copy_tree(path.join('DSi - CFW users', 'SDNAND root'),
                  self.sd_path,
                  update=1)
        copy_tree('_nds', path.join(self.sd_path, '_nds'))
        copy_tree('DSi&3DS - SD card users', self.sd_path, update=1)
        copy_tree('roms', path.join(self.sd_path, 'roms'))

        Thread(target=self.clean).start()

    ################################################################################################
    def clean(self, err=False):
        self.log.write('\nCleaning...')

        while len(self.folders) > 0:
            rmtree(self.folders.pop(), ignore_errors=True)

        while len(self.files) > 0:
            try:
                remove(self.files.pop())

            except:
                pass

        if err:
            self.log.write('Done')
            return

        self.log.write('Done!\nEject your SD card and insert it into your DSi')

    ################################################################################################
    def patcher(self, patchpath, filepath):
        patch_size = path.getsize(patchpath)

        patchfile = open(patchpath, 'rb')

        if patchfile.read(5) != b'PATCH':
            patchfile.close()
            raise Exception()

        target = open(filepath, 'r+b')

        # Read First Record
        r = patchfile.read(3)

        while patchfile.tell() not in [patch_size, patch_size - 3]:
            # Unpack 3-byte pointers.
            offset = self.unpack_int(r)
            # Read size of data chunk
            r = patchfile.read(2)
            size = self.unpack_int(r)

            if size == 0:  # RLE Record
                r = patchfile.read(2)
                rle_size = self.unpack_int(r)
                data = patchfile.read(1) * rle_size

            else:
                data = patchfile.read(size)

            # Write to file
            target.seek(offset)
            target.write(data)
            # Read Next Record
            r = patchfile.read(3)

        if patch_size - 3 == patchfile.tell():
            trim_size = self.unpack_int(patchfile.read(3))
            target.truncate(trim_size)

        # Cleanup
        target.close()
        patchfile.close()

    ################################################################################################
    def unpack_int(self, bstr):
        # Read an n-byte big-endian integer from a byte string
        (ret_val, ) = unpack_from('>I', b'\x00' * (4 - len(bstr)) + bstr)
        return ret_val

    ################################################################################################
    def detect_region(self):
        REGION_CODES = {
            '484e4143': 'CHN',
            '484e4145': 'USA',
            '484e414a': 'JAP',
            #'484e414b': 'KOR',
            '484e4150': 'EUR',
            '484e4155': 'AUS'
        }

        # Autodetect console region
        try:
            for app in listdir(path.join(self.sd_path, 'title', '00030017')):
                for file in listdir(
                        path.join(self.sd_path, 'title', '00030017', app,
                                  'content')):
                    if file.endswith('.app'):
                        try:
                            self.log.write('- Detected ' +
                                           REGION_CODES[app.lower()] +
                                           ' console NAND dump')
                            self.launcher_region = REGION_CODES[app.lower()]
                            return app

                        except KeyError:
                            self.log.write('ERROR: Unsupported console region')
                            return False

            self.log.write('ERROR: Could not detect console region')

        except OSError as e:
            self.log.write('ERROR: ' + e.strerror + ': ' + e.filename)

        return False

    ################################################################################################
    def remove_footer(self):
        self.log.write('\nRemoving No$GBA footer...')

        file = self.console_id.get() + '-no-footer.bin'

        try:
            copyfile(self.nand_file.get(), file)

            # Back-up footer info
            with open(self.console_id.get() + '-info.txt', 'w') as f:
                f.write('eMMC CID: ' + self.cid.get() + '\r\n')
                f.write('Console ID: ' + self.console_id.get() + '\r\n')

            with open(file, 'r+b') as f:
                # Go to the No$GBA footer offset
                f.seek(-64, 2)
                # Remove footer
                f.truncate()

            self.log.write('\nDone!\nModified NAND stored as\n' + file +
                           '\nStored footer info in ' + self.console_id.get() +
                           '-info.txt')

        except IOError as e:
            print(e)
            self.log.write('ERROR: Could not open the file ' +
                           path.basename(self.nand_file.get()))

    ################################################################################################
    def add_footer(self, cid, console_id):
        self.log.write('Adding No$GBA footer...')

        file = self.console_id.get() + '-footer.bin'

        try:
            copyfile(self.nand_file.get(), file)

            with open(file, 'r+b') as f:
                # Go to the No$GBA footer offset
                f.seek(-64, 2)
                # Read the footer's header :-)
                bstr = f.read(0x10)

                # Check if it already has a footer
                if bstr == b'DSi eMMC CID/CPU':
                    self.log.write('ERROR: File already has a No$GBA footer')
                    f.close()
                    remove(file)
                    return

                # Go to the end of file
                f.seek(0, 2)
                # Write footer
                f.write(b'DSi eMMC CID/CPU')
                f.write(cid)
                f.write(console_id)
                f.write(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
                        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')

            self.log.write('\nDone!\nModified NAND stored as\n' + file)

        except IOError as e:
            print(e)
            self.log.write('ERROR: Could not open the file ' +
                           path.basename(self.nand_file.get()))