示例#1
0
    def init_details(self, window):
        # Create details button
        def details():
            if helper_frame.hidden:
                helper_frame.grid()
                helper_frame.hidden = False
                self.run_button.grid(row=17)
            else:
                helper_frame.grid_remove()
                helper_frame.hidden = True
                self.run_button.grid(row=16)

        details_button = Button(window, text="Details", command=details)
        details_button.grid(row=15, column=0, sticky="W", padx=PAD_X)

        # Details Menu
        helper_frame = Frame(window, width=window.winfo_width() - PAD_X * 2, height=100)
        helper_frame.pack_propagate(False)
        self.details_text = Text(helper_frame, width=0, height=0)
        details_scroll = Scrollbar(helper_frame, command=self.details_text.yview)
        details_scroll.pack(side=RIGHT, fill="y")
        self.details_text.configure(yscrollcommand=details_scroll.set)
        self.details_text.pack(fill="both", expand=True)
        helper_frame.grid(row=16, column=0, padx=PAD_X, pady=10)
        helper_frame.grid_remove()
        helper_frame.hidden = True
示例#2
0
    class WaitingBar:
        def __init__(self, frame, field_width, field_height):
            self.val = True
            self.waiting_frame = Frame(frame, width=70, height=30)
            self.waiting_frame.grid(row=field_height + 1, column=4, columnspan=3)
            self.waiting_frame.grid_remove()
            self.waiting_frame.pack_propagate(True)
            self.waiting_message = Label(self.waiting_frame, text='Подождите...', font=8)
            self.waiting_message.pack()

        def show(self, flag):
            if flag:
                self.waiting_frame.grid()
            else:
                self.waiting_frame.grid_remove()
示例#3
0
class PantallaEsperaView(View):
    def __init__(self, controller):

        super().__init__(Toplevel(), controller)

        self.construir_main_frame()

        self.construir_progressbar_frame()

        self.ocultar_vista()

    def configurar_root(self):
        super(PantallaEsperaView, self).configurar_root()
        self.root.geometry("250x150")

    def construir_main_frame(self):
        self.main_frame = Frame(self.root)
        self.main_frame.pack()

    def construir_progressbar_frame(self):
        self.label = Label(self.main_frame)
        self.label.config(pady=20, padx=20, font=("Helvetica", 10))
        self.label.grid(row=0, column=0)

        self.pb_frame = Frame(self.main_frame)
        self.pb_frame.config(padx=20, pady=20)
        # self.pb_frame.grid(row=1, column=0)
        self.progressbar = Progressbar(self.pb_frame)
        self.progressbar.config(mode="indeterminate", length=150)
        self.progressbar.pack()

    def ocultar_vista(self):
        self.progressbar.stop()
        super(PantallaEsperaView, self).ocultar_vista()
        self.pb_frame.grid_remove()

    def mostrar_vista(self):
        self.pb_frame.grid(row=1, column=0)
        super(PantallaEsperaView, self).mostrar_vista()
        self.progressbar.start(10)
示例#4
0
文件: ranks.py 项目: fpapouin/tntpro
    def load(self):
        self.accounts = []
        for pdata in read_data():
            self.accounts.append(Pohhop(pdata))
        self.accounts.sort(key=lambda x: (x.compet, x.wingman), reverse=True)
        x = 0
        y = 0
        position = 0
        delta = 0
        last_account = self.accounts[-1]
        for player in self.accounts:
            player.download_avatar()
            if not player.visible:
                continue
            if player.compet != last_account.compet:
                position += 1
                position += delta
                delta = 0
            elif player.wingman != last_account.wingman:
                position += 1
                position += delta
                delta = 0
            else:
                delta += 1
            last_account = player

            frame = Frame(self.root, background='Black')
            self.add_position(frame, position)
            self.add_avatar(frame, player)
            self.add_rank(frame, player)
            frame.grid(column=x, row=y, padx=20, pady=5)
            if y >= 7 * 2:
                pass
                frame.grid_remove()
            x += 1
            if x == 5:
                x = 0
                y += 2
示例#5
0
文件: view.py 项目: joyfish/Programas
class PianoTutor:
    def __init__(self, root):
        self.root = root
        self.root.resizable(False, False)
        self.root.title('Piano Tutor')
        self.keys = []
        self.build_mode_selector_frame()
        self.build_score_sheet_frame()
        self.build_controls_frame()
        self.build_keyboard_frame()
        self.build_chords_frame()
        self.build_progressions_frame()
        self.build_scales_frame()

    def build_mode_selector_frame(self):
        self.mode_selector_frame = Frame(self.root,
                                         width=WINDOW_WIDTH,
                                         height=MODE_SELECTOR_HEIGHT,
                                         background='mint cream')
        self.mode_selector_frame.grid_propagate(False)
        self.mode_selector = ttk.Combobox(self.mode_selector_frame,
                                          values=CHOICES)
        self.mode_selector.bind('<<ComboboxSelected>>', self.on_mode_changed)
        self.mode_selector.current(0)
        self.mode_selector.grid(
            row=0,
            column=1,
            columnspan=3,
            padx=10,
            pady=10,
            sticky='nsew',
        )
        self.mode_selector_frame.grid(row=0, column=0)

    def build_score_sheet_frame(self):
        self.score_sheet_frame = Frame(self.root,
                                       width=WINDOW_WIDTH,
                                       height=SCORE_DISPLAY_HEIGHT,
                                       background='SteelBlue1')
        self.score_sheet_frame.grid_propagate(False)
        Label(self.score_sheet_frame,
              text='placeholder for score sheet',
              background='SteelBlue1').grid(row=1, column=1)
        self.score_sheet_frame.grid(row=1, column=0)

    def build_controls_frame(self):
        self.controls_frame = Frame(self.root,
                                    width=WINDOW_WIDTH,
                                    height=CONTROLS_FRAME_HEIGHT,
                                    background='cornsilk3')
        self.controls_frame.grid_propagate(False)
        self.controls_frame.grid(row=2, column=0)

    def build_keyboard_frame(self):
        self.keyboard_frame = Frame(self.root,
                                    width=WINDOW_WIDTH,
                                    height=KEYBOARD_HEIGHT,
                                    background='LavenderBlush2')
        self.keyboard_frame.grid_propagate(False)
        self.keyboard_frame.grid(row=4, column=0, sticky='nsew')
        for (index, key) in enumerate(WHITE_KEY_NAMES):
            x = WHITE_KEY_X_COORDINATES[index]
            self.create_key(WHITE_KEY_IMAGE, key, x)
        for (index, key) in enumerate(BLACK_KEY_NAMES):
            x = BLACK_KEY_X_COORDINATES[index]
            self.create_key(BLACK_KEY_IMAGE, key, x)

    def build_scales_frame(self):
        self.scales_frame = Frame(self.controls_frame,
                                  width=WINDOW_WIDTH,
                                  height=CONTROLS_FRAME_HEIGHT,
                                  bg='SlateBlue3')
        Label(self.scales_frame,
              text='placeholder for scales frame').grid(row=1, column=1)
        self.scales_frame.grid(row=1, column=0, sticky='nsew')

    def build_chords_frame(self):
        self.chords_frame = Frame(self.controls_frame,
                                  width=WINDOW_WIDTH,
                                  height=CONTROLS_FRAME_HEIGHT,
                                  bg='cornsilk4')
        self.chords_frame.grid_propagate(False)
        Label(self.chords_frame,
              text='placeholder for chords frame').grid(row=1, column=1)
        self.chords_frame.grid(row=1, column=0, sticky='nsew')

    def build_progressions_frame(self):
        self.progressions_frame = Frame(self.controls_frame,
                                        width=WINDOW_WIDTH,
                                        height=CONTROLS_FRAME_HEIGHT,
                                        bg='plum2')
        self.progressions_frame.grid_propagate(False)
        Label(self.progressions_frame,
              text='placeholder for progression frame').grid(row=1, column=1)
        self.progressions_frame.grid(row=1, column=0, sticky='nsew')

    def on_mode_changed(self, event):
        selected_mode = self.mode_selector.get()
        if selected_mode == 'Scales':
            self.show_scales_frame()
        elif selected_mode == 'Chords':
            self.show_chords_frame()
        elif selected_mode == 'Chord Progressions':
            self.show_progressions_frame()

    def show_scales_frame(self):
        self.chords_frame.grid_remove()
        self.progressions_frame.grid_remove()
        self.scales_frame.grid()

    def show_chords_frame(self):
        self.chords_frame.grid()
        self.progressions_frame.grid_remove()
        self.scales_frame.grid_remove()

    def show_progressions_frame(self):
        self.chords_frame.grid_remove()
        self.progressions_frame.grid()
        self.scales_frame.grid_remove()

    def create_key(self, img, key_name, x_coordinate):
        key_image = PhotoImage(file=img)
        label = Label(self.keyboard_frame, image=key_image, border=0)
        label.image = key_image
        label.place(x=x_coordinate, y=0)
        label.name = key_name
        label.bind('<Button-1>', self.on_key_pressed)
        label.bind('<ButtonRelease-1>', self.on_key_released)
        self.keys.append(label)
        return label

    def change_image_to_pressed(self, event):
        if len(event.widget.name) == 2:
            img = WHITE_KEY_PRESSED_IMAGE
        elif len(event.widget.name) == 3:
            img = BLACK_KEY_PRESSED_IMAGE
        key_img = PhotoImage(file=img)
        event.widget.configure(image=key_img)
        event.widget.image = key_img

    def change_image_to_unpressed(self, event):
        if len(event.widget.name) == 2:
            img = WHITE_KEY_IMAGE
        elif len(event.widget.name) == 3:
            img = BLACK_KEY_IMAGE
        key_img = PhotoImage(file=img)
        event.widget.configure(image=key_img)
        event.widget.image = key_img

    def on_key_pressed(self, event):
        play_note(event.widget.name)
        self.change_image_to_pressed(event)

    def on_key_released(self, event):
        print(event.widget.name + ' released')
        self.change_image_to_unpressed(event)
class MessageComponentFrame:
    def __init__(self, parent):
        self.parent = parent
        self.frame = Frame(parent.master, bd=2, relief=GROOVE)

        self.textValue = StringVar()
        self.imageValue = StringVar()
        self.imagePath = StringVar()
        self.fileValue = StringVar()
        self.filePath = StringVar()
        self.gapValue = StringVar()
        self.componentType = StringVar()
        self.componentTypes = ["Text", "Image", "Text From File", "Pixel Gap"]

        labelMessageSettings = Label(self.frame, text="Component Settings")
        labelMessageSettings.grid(row=0,
                                  column=0,
                                  sticky=W,
                                  columnspan=3,
                                  padx=1,
                                  pady=1)

        labelComponentType = Label(self.frame, text="Component Type:")
        labelComponentType.grid(row=1, column=0, sticky=E, padx=4, pady=4)
        self.comboboxComponentType = Combobox(self.frame,
                                              values=self.componentTypes,
                                              textvariable=self.componentType,
                                              state="readonly")

        self.comboboxComponentType.grid(row=1,
                                        column=1,
                                        columnspan=2,
                                        sticky=W,
                                        padx=4,
                                        pady=4)

        self.labelTextToDisplay = Label(self.frame, text="Text to Display:")
        self.labelTextToDisplay.grid(row=2, column=0, sticky=E, padx=4, pady=4)
        self.inputTextToDisplay = Entry(self.frame,
                                        textvariable=self.textValue,
                                        width=40)
        self.inputTextToDisplay.grid(row=2,
                                     column=1,
                                     columnspan=2,
                                     sticky=W,
                                     padx=4,
                                     pady=4)

        self.labelImage = Label(self.frame,
                                textvariable=self.imagePath,
                                anchor=W)
        self.buttonImage = HoverButton(self.frame,
                                       text='Select File',
                                       command=lambda: self.selectImageFile(),
                                       width=12)
        self.buttonImage.grid(row=3, column=0, sticky=E, padx=4, pady=4)
        self.labelImage.grid(row=3, column=1, columnspan=2, sticky=W)

        self.labelFile = Label(self.frame,
                               textvariable=self.filePath,
                               anchor=W)
        self.buttonFile = HoverButton(self.frame,
                                      text='Select File',
                                      command=lambda: self.selectTextFile(),
                                      width=12)
        self.buttonFile.grid(row=4, column=0, sticky=E, padx=4, pady=4)
        self.labelFile.grid(row=4, column=1, columnspan=2, sticky=W)

        self.labelGap = Label(self.frame, text="Width of Gap:")
        self.labelGap.grid(row=5, column=0, sticky=E, padx=4, pady=(4, 0))
        self.gapFrame = Frame(self.frame)
        self.inputGap = Entry(self.gapFrame,
                              textvariable=self.gapValue,
                              width=4)
        self.inputGap.grid(row=0, column=0, sticky=W, pady=4)
        self.labelGapPixels = Label(self.gapFrame, text="pixels")
        self.labelGapPixels.grid(row=0, column=1, padx=2, sticky=W)
        self.gapFrame.grid(row=5,
                           column=1,
                           columnspan=2,
                           sticky=W,
                           padx=4,
                           pady=4)

        self.comboboxComponentType.bind("<<ComboboxSelected>>",
                                        self.updateGrid)
        self.setFields()
        self.updateGrid(None)

    def setFields(self):
        mp = self.parent.messagePart
        if mp:
            self.comboboxComponentType.set(mp.partType)
            if mp.partType == "Text":
                self.textValue.set(mp.value)
            elif mp.partType == "Image":
                self.imagePath.set(helperMethods.getFileNameFromPath(mp.value))
                self.imageValue.set(mp.value)
            elif mp.partType == "Text From File":
                self.filePath.set(helperMethods.getFileNameFromPath(mp.value))
                self.fileValue.set(mp.value)
            elif mp.partType == "Pixel Gap":
                self.gapValue.set(mp.value)
        else:
            self.comboboxComponentType.set("Text")

    def hideAllDropdownDependentFields(self):
        self.labelTextToDisplay.grid_remove()
        self.inputTextToDisplay.grid_remove()
        self.labelImage.grid_remove()
        self.buttonImage.grid_remove()
        self.labelFile.grid_remove()
        self.buttonFile.grid_remove()
        self.labelGap.grid_remove()
        self.gapFrame.grid_remove()

    def displayCurrentComponentTypeDependencies(self):
        if self.componentType.get() == "Text":
            self.labelTextToDisplay.grid()
            self.inputTextToDisplay.grid()
        elif self.componentType.get() == "Image":
            self.labelImage.grid()
            self.buttonImage.grid()
        elif self.componentType.get() == "Text From File":
            self.labelFile.grid()
            self.buttonFile.grid()
        elif self.componentType.get() == "Pixel Gap":
            self.labelGap.grid()
            self.gapFrame.grid()

    def updateGrid(self, e):
        self.hideAllDropdownDependentFields()
        self.displayCurrentComponentTypeDependencies()

    def selectImageFile(self):
        filename = filedialog.askopenfilename(
            initialdir=os.getcwd() + "/imagefiles",
            title="Select image file",
            filetypes=[("PNG", "*.png"),
                       ("JPEG", "*.jpg; *.jpeg; *.jpe; *.jfif")])
        if filename:
            self.imagePath.set(helperMethods.getFileNameFromPath(filename))
            self.imageValue.set(filename)

    def selectTextFile(self):
        filename = filedialog.askopenfilename(initialdir=os.getcwd(),
                                              title="Select text file",
                                              filetypes=[("txt files", "*.txt")
                                                         ])
        if filename:
            self.filePath.set(helperMethods.getFileNameFromPath(filename))
            self.fileValue.set(filename)

    def getValue(self):
        if self.componentType.get() == "Text":
            return self.textValue.get()
        elif self.componentType.get() == "Image":
            return self.imageValue.get()
        elif self.componentType.get() == "Text From File":
            return self.fileValue.get()
        elif self.componentType.get() == "Pixel Gap":
            return self.gapValue.get()
示例#7
0
class fen_info(Tk):
    """ Fenêtre permettant de saisir les informations sur les joueurs
    """
    def __init__(self):

        super().__init__()
        # Initialisation des pions à la valeur initiale.
        self.pion1 = "X"
        self.pion2 = "O"

        # Titre de la fenêtre
        self.title("Ultimate TIC-TAC-TOE")

        # Pour changer taille minimum de fenêtre et taille centrer,
        # changer variable self.width_fen, self.height_fen.
        self.width_fen, self.height_fen = 430, 500

        # Taille minimum de la fenêtre
        self.minsize(self.width_fen, self.height_fen)

        # Centrer la fenêtre.
        centreFen(self, self.width_fen, self.height_fen)

        # Création d'un canvas avec l'image "logo.gif"
        canvas = Canvas(self, width=280, height=100)
        self.img = PhotoImage(file="logo.gif")
        canvas.create_image(280, 100, anchor=SE, image=self.img)
        canvas.grid(row=0, columnspan=5, pady=10)

        # Libellé - Nouvelle Partie
        Label(self,
              text="Nouvelle partie",
              font=("Arial", 16),
              fg="#0080FF",
              justify=CENTER).grid(row=1, columnspan=5, padx=20, pady=5)
        separateur(20).grid(row=10, columnspan=5)

        # Sélection du type de partie avec bouton radio
        self.choixJoueur = IntVar()
        r1 = Radiobutton(self,
                         text="Jouer avec l'ordinateur",
                         variable=self.choixJoueur,
                         value=1,
                         command=self.define_choix)
        r1.select()
        r1.grid(row=20, column=0)
        r2 = Radiobutton(self,
                         text="Jouer avec un autre joueur",
                         variable=self.choixJoueur,
                         value=2,
                         command=self.define_choix)
        r2.grid(row=20, column=1)

        # Saisie du nom du joueur 1.
        f_j1 = Frame(self, borderwidth=1, padx=5, pady=5, relief=SUNKEN)
        f_j1.grid(row=30, columnspan=5, padx=5, pady=5)
        Label(f_j1, text="Nom joueur 1:").grid(row=1,
                                               column=0,
                                               sticky=E,
                                               padx=5,
                                               pady=5)
        self.nom_joueur1 = Entry(f_j1)
        self.nom_joueur1.grid(row=1, column=1)

        # Sélection du pion joueur 1. Le pion restant est automatiquement attribué au joueur 2.

        Label(f_j1, text="Choix de pion:").grid(row=1, column=2, padx=5)
        self.sel_pion = IntVar()
        p1 = Radiobutton(f_j1,
                         indicatoron=0,
                         width=5,
                         text="X",
                         variable=self.sel_pion,
                         value=1,
                         command=self.choix_pion)
        p1.grid(row=1, column=3, padx=2)
        p1.select()
        Radiobutton(f_j1,
                    indicatoron=0,
                    width=5,
                    text="O",
                    variable=self.sel_pion,
                    value=2,
                    command=self.choix_pion).grid(row=1, column=4, padx=2)

        # Saisie du nom du joueur 2. Apparaît seulement si on sélection 2 joueurs. Voir define_choix
        self.f_j2 = Frame(self,
                          width=420,
                          borderwidth=1,
                          padx=5,
                          pady=5,
                          relief=SUNKEN)
        Label(self.f_j2, text="Nom joueur 2").grid(row=1,
                                                   column=0,
                                                   sticky=E,
                                                   padx=5,
                                                   pady=5)
        self.nom_joueur2 = Entry(self.f_j2, state="disabled")
        self.nom_joueur2.grid(row=1, column=1)
        self.label_pion2 = Label(self.f_j2, text="Pion Joueur 2 = O")
        self.label_pion2.grid(row=1, column=2, padx=5)

        # Information sur l'ordinateur. Disparaît si on choisi 2 joueurs.
        self.f_ordi = Frame(self,
                            width=420,
                            borderwidth=1,
                            padx=5,
                            pady=5,
                            relief=SUNKEN)
        self.f_ordi.grid(row=40, columnspan=5, padx=5, pady=5)
        Label(self.f_ordi, text="Ordinateur = Colosse", font=("Arial", 12), fg="#0080FF")\
            .grid(row=1, column=0, sticky=E, padx = 5, pady = 5)
        self.pion_ordi = Label(self.f_ordi,
                               text="| Pion de l'ordinateur = O",
                               font=("Arial", 12),
                               fg="#0080FF")
        self.pion_ordi.grid(row=1, column=2)
        separateur(20).grid(row=50, columnspan=5)

        # Sélection de la force de l'ordinateur
        self.choixForce = IntVar()
        self.f1 = Radiobutton(self,
                              indicatoron=0,
                              width=20,
                              padx=20,
                              text="Facile",
                              variable=self.choixForce,
                              value=1,
                              command=self.define_choix)
        self.f1.select()
        self.f1.grid(row=60, columnspan=5)
        self.f2 = Radiobutton(self,
                              indicatoron=0,
                              width=20,
                              padx=20,
                              text="Moyen",
                              variable=self.choixForce,
                              value=2,
                              command=self.define_choix)
        self.f2.grid(row=61, columnspan=5)
        self.f3 = Radiobutton(self,
                              indicatoron=0,
                              width=20,
                              padx=20,
                              text="Difficile",
                              variable=self.choixForce,
                              value=3,
                              command=self.define_choix)
        self.f3.grid(row=62, columnspan=5)
        separateur(40).grid(row=70, column=0)

        #Button pour démarrer la partie
        self.bt_start = Button(text="Démarrer",
                               font=("Arial", 12),
                               fg="green",
                               command=self.demarrer_jeu)
        self.bt_start.grid(row=80, columnspan=5)

    def define_choix(self):
        """
            Fonction qui active ou désactive le nom du joueur 2 selon si on joue contre l'ordinateur ou contre
            un autre joueur
        """

        if self.choixJoueur.get() == 1:
            self.nom_joueur2.delete(0, END)
            self.nom_joueur2["state"] = "disabled"
            self.f1["state"] = "normal"
            self.f2["state"] = "normal"
            self.f3["state"] = "normal"
            self.f_j2.grid_remove()
            self.f_ordi.grid(row=40, columnspan=5, padx=5, pady=5)

        elif self.choixJoueur.get() == 2:
            self.nom_joueur2["state"] = "normal"
            self.f1["state"] = "disabled"
            self.f2["state"] = "disabled"
            self.f3["state"] = "disabled"
            self.f_j2.grid(row=40, columnspan=5, padx=5, pady=5)
            self.f_ordi.grid_remove()

    def choix_pion(self):
        # Définition des pions

        if self.sel_pion.get() == 1:
            self.pion1 = "X"
            self.pion2 = "O"
            self.label_pion2["text"] = "Pion Joueur 2 = {}".format(self.pion2)
            self.pion_ordi["text"] = "| Pion de l'ordinateur = {}".format(
                self.pion2)
        else:
            self.pion1 = "O"
            self.pion2 = "X"
            self.label_pion2["text"] = "Pion Joueur 2 = {}".format(self.pion2)
            self.pion_ordi["text"] = "| Pion de l'ordinateur = {}".format(
                self.pion2)

    def demarrer_jeu(self):
        """
        Démarrer la partie avec les informations saisie. Afficher le plateau
        """
        if self.choixJoueur.get() == 1:
            type2 = "Ordinateur"
            if self.nom_joueur1.get() != '':
                j1 = self.nom_joueur1.get()
                j2 = "Colosse"
            else:
                j1 = "Joueur 1"
                j2 = "Colosse"
        elif self.choixJoueur.get() == 2:
            type2 = "Personne"
            if self.nom_joueur1.get() != '' and self.nom_joueur2.get() != '':
                j1 = self.nom_joueur1.get()
                j2 = self.nom_joueur2.get()
            elif self.nom_joueur1.get() == '':
                j1 = "Joueur 1"
                if self.nom_joueur2.get() == '':
                    j2 = "Joueur 2"
                else:
                    j2 = self.nom_joueur2.get()
            else:
                j1 = self.nom_joueur1.get()
                if self.nom_joueur2.get() == '':
                    j2 = "Joueur 2"
                else:
                    j2 = self.nom_joueur2.get()

        p1 = self.pion1
        p2 = self.pion2
        force = self.choixForce.get()
        self.destroy()
        ma_fenetre = Fenetre(j1, j2, type2, p1, p2, force)
        ma_fenetre.mainloop()
示例#8
0
class Momentary:
    def __init__(self, master, valves):
        self.valves = valves

        self.master = master
        self.frame1 = Frame(master)
        self.frame2 = Frame(master)

        self.master.configure(bg='sky blue')
        self.frame1.configure(bg='sky blue')
        self.frame2.configure(bg='sky blue')

        index = 0
        while index < 6:
            self.frame1.grid_columnconfigure(index, minsize=6)
            self.frame2.grid_columnconfigure(index, minsize=6)

            self.frame1.grid_rowconfigure(index, minsize=140)
            self.frame2.grid_rowconfigure(index, minsize=140)
            index += 1

        self.end_all_image = PhotoImage(file="img/stop.png").subsample(x=6,
                                                                       y=6)
        self.end_all_button = Button(self.master,
                                     image=self.end_all_image,
                                     command=lambda: self.end_all())
        self.end_all_button.config(bg='brown3',
                                   activebackground='brown4',
                                   border=5,
                                   width=850)

        self.label = [
            Label(self.frame1, textvariable=self.valves[0].get_name()),
            Label(self.frame1, textvariable=self.valves[1].get_name()),
            Label(self.frame1, textvariable=self.valves[2].get_name()),
            Label(self.frame1, textvariable=self.valves[3].get_name()),
            Label(self.frame2, textvariable=self.valves[4].get_name()),
            Label(self.frame2, textvariable=self.valves[5].get_name()),
            Label(self.frame2, textvariable=self.valves[6].get_name()),
            Label(self.frame2, textvariable=self.valves[7].get_name())
        ]

        row = 0
        for each in self.label:
            each.config(width=7, height=2)
            each.config(bg='sky blue',
                        fg='RoyalBlue4',
                        font=('Lucida Console', 30),
                        padx=18)
            each.grid(row=row % 4, column=0)
            row += 1

        self.lightsA = [
            LED(self.frame1, 30, 'green1', 'green', 'dark green', 'Dark Green',
                False),
            LED(self.frame1, 30, 'green1', 'green', 'dark green', 'Dark Green',
                False),
            LED(self.frame1, 30, 'green1', 'green', 'dark green', 'Dark Green',
                False),
            LED(self.frame1, 30, 'green1', 'green', 'dark green', 'Dark Green',
                False),
            LED(self.frame2, 30, 'green1', 'green', 'dark green', 'Dark Green',
                False),
            LED(self.frame2, 30, 'green1', 'green', 'dark green', 'Dark Green',
                False),
            LED(self.frame2, 30, 'green1', 'green', 'dark green', 'Dark Green',
                False),
            LED(self.frame2, 30, 'green1', 'green', 'dark green', 'Dark Green',
                False)
        ]

        self.lightsB = [
            LED(self.frame1, 30, 'red', 'dark red', 'red4', 'DarkRed', False),
            LED(self.frame1, 30, 'red', 'dark red', 'red4', 'DarkRed', False),
            LED(self.frame1, 30, 'red', 'dark red', 'red4', 'DarkRed', False),
            LED(self.frame1, 30, 'red', 'dark red', 'red4', 'DarkRed', False),
            LED(self.frame2, 30, 'red', 'dark red', 'red4', 'DarkRed', False),
            LED(self.frame2, 30, 'red', 'dark red', 'red4', 'DarkRed', False),
            LED(self.frame2, 30, 'red', 'dark red', 'red4', 'DarkRed', False),
            LED(self.frame2, 30, 'red', 'dark red', 'red4', 'DarkRed', False)
        ]

        self.v = [
            IntVar(),
            IntVar(),
            IntVar(),
            IntVar(),
            IntVar(),
            IntVar(),
            IntVar(),
            IntVar()
        ]

        for each in self.v:
            each.set(3)

        self.a = [
            Radiobutton(self.frame1,
                        text='A',
                        command=lambda: self.activate_a(0),
                        value=1),
            Radiobutton(self.frame1,
                        text='A',
                        command=lambda: self.activate_a(1),
                        value=1),
            Radiobutton(self.frame1,
                        text='A',
                        command=lambda: self.activate_a(2),
                        value=1),
            Radiobutton(self.frame1,
                        text='A',
                        command=lambda: self.activate_a(3),
                        value=1),
            Radiobutton(self.frame2,
                        text='A',
                        command=lambda: self.activate_a(4),
                        value=1),
            Radiobutton(self.frame2,
                        text='A',
                        command=lambda: self.activate_a(5),
                        value=1),
            Radiobutton(self.frame2,
                        text='A',
                        command=lambda: self.activate_a(6),
                        value=1),
            Radiobutton(self.frame2,
                        text='A',
                        command=lambda: self.activate_a(7),
                        value=1)
        ]

        index = 0
        for each in self.a:
            each.grid(row=index % 4, column=2)
            each.config(width=4,
                        height=2,
                        indicatoron=0,
                        variable=self.v[index],
                        font=('Lucida Console', 30))
            each.config(bg='SkyBlue4',
                        activebackground='midnight blue',
                        selectcolor='midnight blue',
                        fg='white')
            each.config(activeforeground='white')
            index += 1

        self.b = [
            Radiobutton(self.frame1,
                        text='B',
                        command=lambda: self.activate_b(0),
                        value=0),
            Radiobutton(self.frame1,
                        text='B',
                        command=lambda: self.activate_b(1),
                        value=0),
            Radiobutton(self.frame1,
                        text='B',
                        command=lambda: self.activate_b(2),
                        value=0),
            Radiobutton(self.frame1,
                        text='B',
                        command=lambda: self.activate_b(3),
                        value=0),
            Radiobutton(self.frame2,
                        text='B',
                        command=lambda: self.activate_b(4),
                        value=0),
            Radiobutton(self.frame2,
                        text='B',
                        command=lambda: self.activate_b(5),
                        value=0),
            Radiobutton(self.frame2,
                        text='B',
                        command=lambda: self.activate_b(6),
                        value=0),
            Radiobutton(self.frame2,
                        text='B',
                        command=lambda: self.activate_b(7),
                        value=0)
        ]

        index = 0
        for each in self.b:
            each.grid(row=index % 4, column=3)
            each.config(width=4,
                        height=2,
                        indicatoron=0,
                        variable=self.v[index],
                        font=('Lucida Console', 30))
            each.config(bg='SkyBlue4',
                        activebackground='midnight blue',
                        selectcolor='midnight blue',
                        fg='white')
            each.config(activeforeground='white')
            index += 1

        self.end_image = PhotoImage(file="img/no.png").subsample(x=6, y=6)
        self.end_button = [
            Radiobutton(self.frame1,
                        image=self.end_image,
                        command=lambda: self.end(0)),
            Radiobutton(self.frame1,
                        image=self.end_image,
                        command=lambda: self.end(1)),
            Radiobutton(self.frame1,
                        image=self.end_image,
                        command=lambda: self.end(2)),
            Radiobutton(self.frame1,
                        image=self.end_image,
                        command=lambda: self.end(3)),
            Radiobutton(self.frame2,
                        image=self.end_image,
                        command=lambda: self.end(4)),
            Radiobutton(self.frame2,
                        image=self.end_image,
                        command=lambda: self.end(5)),
            Radiobutton(self.frame2,
                        image=self.end_image,
                        command=lambda: self.end(6)),
            Radiobutton(self.frame2,
                        image=self.end_image,
                        command=lambda: self.end(7)),
        ]

        index = 0
        for each in self.end_button:
            each.grid(row=index % 4, column=5)
            each.config(value=2, variable=self.v[index], indicatoron=0)
            each.config(bg='brown3', activebackground='brown4')
            index += 1

    def make_frame(self):
        self.frame1.grid(row=2, column=0, rowspan=5)
        self.frame2.grid(row=2, column=1, rowspan=5)
        self.end_all_button.grid(row=1, column=0, columnspan=2)

        row = 0
        for each in self.lightsA:
            each.grid(row=row % 4, column=1, padx=20, pady=20)
            row += 1

        row = 0
        for each in self.lightsB:
            each.grid(row=row % 4, column=4, padx=20, pady=20)
            row += 1

    def delete_frame(self):
        self.frame1.grid_remove()
        self.frame2.grid_remove()
        self.end_all_button.grid_remove()

        for each in self.lightsA:
            each.grid_remove()

        for each in self.lightsB:
            each.grid_remove()

    def activate_a(self, number):
        pin_number = 65 + number
        pin_opposite = 80 - number

        if self.v[number].get() == 1:
            self.lightsA[number].set_state(True)
            self.lightsB[number].set_state(False)

            wiringpi.digitalWrite(pin_number, 1)
            wiringpi.digitalWrite(pin_opposite, 0)

    def activate_b(self, number):
        pin_number = 80 - number
        pin_opposite = 65 + number

        if self.v[number].get() == 0:
            self.lightsA[number].set_state(False)
            self.lightsB[number].set_state(True)
            wiringpi.digitalWrite(pin_number, 1)
            wiringpi.digitalWrite(pin_opposite, 0)

    def end(self, number):
        pin_number = 65 + number
        pin_opposite = 80 - number

        wiringpi.digitalWrite(pin_number, 0)
        wiringpi.digitalWrite(pin_opposite, 0)

        self.v[number].set(3)
        self.lightsA[number].set_state(False)
        self.lightsB[number].set_state(False)

    def end_all(self):
        number = 0
        while number < 8:
            self.end(number)
            number += 1
 def hide(frame: tk.Frame):
     frame.grid_remove()
示例#10
0
文件: view.py 项目: joyfish/Programas
class PianoTutor:

    def __init__(self, root):
        self.root = root
        self.root.resizable(False, False)
        self.root.title('Piano Tutor')
        self.build_mode_selector_frame()
        self.build_score_sheet_frame()
        self.build_controls_frame()
        self.build_keyboard_frame()
        self.build_chords_frame()
        self.build_progressions_frame()
        self.build_scales_frame()

    def build_mode_selector_frame(self):
        self.mode_selector_frame = Frame(self.root, width=WINDOW_WIDTH,
                height=MODE_SELECTOR_HEIGHT, background='mint cream')
        self.mode_selector_frame.grid_propagate(False)
        self.mode_selector = ttk.Combobox(self.mode_selector_frame,
                values=CHOICES)
        self.mode_selector.bind('<<ComboboxSelected>>',
                                self.on_mode_changed)
        self.mode_selector.current(0)
        self.mode_selector.grid(
            row=0,
            column=1,
            columnspan=3,
            padx=10,
            pady=10,
            sticky='nsew',
            )
        self.mode_selector_frame.grid(row=0, column=0)

    def build_score_sheet_frame(self):
        self.score_sheet_frame = Frame(self.root, width=WINDOW_WIDTH,
                height=SCORE_DISPLAY_HEIGHT, background='SteelBlue1')
        self.score_sheet_frame.grid_propagate(False)
        Label(self.score_sheet_frame, text='placeholder for score sheet'
              , background='SteelBlue1').grid(row=1, column=1)
        self.score_sheet_frame.grid(row=1, column=0)

    def build_controls_frame(self):
        self.controls_frame = Frame(self.root, width=WINDOW_WIDTH,
                                    height=CONTROLS_FRAME_HEIGHT,
                                    background='cornsilk3')
        self.controls_frame.grid_propagate(False)
        self.controls_frame.grid(row=2, column=0)

    def build_keyboard_frame(self):
        self.keyboard_frame = Frame(self.root, width=WINDOW_WIDTH,
                                    height=KEYBOARD_HEIGHT,
                                    background='LavenderBlush2')
        self.keyboard_frame.grid_propagate(False)
        Label(self.keyboard_frame, text='placeholder for keyboard',
              background='LavenderBlush2').grid()
        self.keyboard_frame.grid(row=4, column=0, sticky='nsew')

    def build_scales_frame(self):
        self.scales_frame = Frame(self.controls_frame,
                                  width=WINDOW_WIDTH,
                                  height=CONTROLS_FRAME_HEIGHT,
                                  bg='SlateBlue3')
        Label(self.scales_frame, text='placeholder for scales frame'
              ).grid(row=1, column=1)
        self.scales_frame.grid(row=1, column=0, sticky='nsew')

    def build_chords_frame(self):
        self.chords_frame = Frame(self.controls_frame,
                                  width=WINDOW_WIDTH,
                                  height=CONTROLS_FRAME_HEIGHT,
                                  bg='cornsilk4')
        self.chords_frame.grid_propagate(False)
        Label(self.chords_frame, text='placeholder for chords frame'
              ).grid(row=1, column=1)
        self.chords_frame.grid(row=1, column=0, sticky='nsew')

    def build_progressions_frame(self):
        self.progressions_frame = Frame(self.controls_frame,
                width=WINDOW_WIDTH, height=CONTROLS_FRAME_HEIGHT,
                bg='plum2')
        self.progressions_frame.grid_propagate(False)
        Label(self.progressions_frame,
              text='placeholder for progression frame').grid(row=1,
                column=1)
        self.progressions_frame.grid(row=1, column=0, sticky='nsew')

    def on_mode_changed(self, event):
        selected_mode = self.mode_selector.get()
        if selected_mode == 'Scales':
            self.show_scales_frame()
        elif selected_mode == 'Chords':
            self.show_chords_frame()
        elif selected_mode == 'Chord Progressions':
            self.show_progressions_frame()

    def show_scales_frame(self):
        self.chords_frame.grid_remove()
        self.progressions_frame.grid_remove()
        self.scales_frame.grid()

    def show_chords_frame(self):
        self.chords_frame.grid()
        self.progressions_frame.grid_remove()
        self.scales_frame.grid_remove()

    def show_progressions_frame(self):
        self.chords_frame.grid_remove()
        self.progressions_frame.grid()
        self.scales_frame.grid_remove()
示例#11
0
class Momentary:
    def __init__(self, master, valves):
        self.valves = valves

        self.master = master
        self.frame1 = Frame(master)
        self.frame2 = Frame(master)

        self.master.configure(bg='sky blue')
        self.frame1.configure(bg='sky blue')
        self.frame2.configure(bg='sky blue')

        index = 0
        while index < 6:
            self.frame1.grid_columnconfigure(index, minsize=6)
            self.frame2.grid_columnconfigure(index, minsize=6)

            self.frame1.grid_rowconfigure(index, minsize=140)
            self.frame2.grid_rowconfigure(index, minsize=140)
            index += 1

        self.end_all_image = PhotoImage(file="img/stop.png").subsample(x=6, y=6)
        self.end_all_button = Button(self.master, image=self.end_all_image, command=lambda: self.end_all() )
        self.end_all_button.config(bg='brown3', activebackground='brown4', border=5, width=850)

        self.label = [Label(self.frame1, textvariable=self.valves[0].get_name()),
                      Label(self.frame1, textvariable=self.valves[1].get_name()),
                      Label(self.frame1, textvariable=self.valves[2].get_name()),
                      Label(self.frame1, textvariable=self.valves[3].get_name()),
                      Label(self.frame2, textvariable=self.valves[4].get_name()),
                      Label(self.frame2, textvariable=self.valves[5].get_name()),
                      Label(self.frame2, textvariable=self.valves[6].get_name()),
                      Label(self.frame2, textvariable=self.valves[7].get_name())]

        row = 0
        for each in self.label:
            each.config(width=7, height=2)
            each.config(bg='sky blue', fg='RoyalBlue4', font=('Lucida Console', 30), padx=18)
            each.grid(row=row % 4, column=0)
            row += 1

        self.lightsA = [LED(self.frame1, 30, 'green1', 'green', 'dark green', 'Dark Green', False),
                        LED(self.frame1, 30, 'green1', 'green', 'dark green', 'Dark Green', False),
                        LED(self.frame1, 30, 'green1', 'green', 'dark green', 'Dark Green', False),
                        LED(self.frame1, 30, 'green1', 'green', 'dark green', 'Dark Green', False),
                        LED(self.frame2, 30, 'green1', 'green', 'dark green', 'Dark Green', False),
                        LED(self.frame2, 30, 'green1', 'green', 'dark green', 'Dark Green', False),
                        LED(self.frame2, 30, 'green1', 'green', 'dark green', 'Dark Green', False),
                        LED(self.frame2, 30, 'green1', 'green', 'dark green', 'Dark Green', False)
                        ]

        self.lightsB = [LED(self.frame1, 30, 'red', 'dark red', 'red4', 'DarkRed', False),
                        LED(self.frame1, 30, 'red', 'dark red', 'red4', 'DarkRed', False),
                        LED(self.frame1, 30, 'red', 'dark red', 'red4', 'DarkRed', False),
                        LED(self.frame1, 30, 'red', 'dark red', 'red4', 'DarkRed', False),
                        LED(self.frame2, 30, 'red', 'dark red', 'red4', 'DarkRed', False),
                        LED(self.frame2, 30, 'red', 'dark red', 'red4', 'DarkRed', False),
                        LED(self.frame2, 30, 'red', 'dark red', 'red4', 'DarkRed', False),
                        LED(self.frame2, 30, 'red', 'dark red', 'red4', 'DarkRed', False)
                        ]

        self.v = [IntVar(),
                  IntVar(),
                  IntVar(),
                  IntVar(),
                  IntVar(),
                  IntVar(),
                  IntVar(),
                  IntVar()]

        for each in self.v:
            each.set(3)

        self.a = [Radiobutton(self.frame1, text='A', command=lambda: self.activate_a(0), value=1),
                  Radiobutton(self.frame1, text='A', command=lambda: self.activate_a(1), value=1),
                  Radiobutton(self.frame1, text='A', command=lambda: self.activate_a(2), value=1),
                  Radiobutton(self.frame1, text='A', command=lambda: self.activate_a(3), value=1),
                  Radiobutton(self.frame2, text='A', command=lambda: self.activate_a(4), value=1),
                  Radiobutton(self.frame2, text='A', command=lambda: self.activate_a(5), value=1),
                  Radiobutton(self.frame2, text='A', command=lambda: self.activate_a(6), value=1),
                  Radiobutton(self.frame2, text='A', command=lambda: self.activate_a(7), value=1)]

        index = 0
        for each in self.a:
            each.grid(row=index % 4, column=2)
            each.config(width=4, height=2,  indicatoron=0, variable=self.v[index], font=('Lucida Console', 30))
            each.config(bg='SkyBlue4', activebackground='midnight blue', selectcolor='midnight blue', fg='white')
            each.config(activeforeground='white')
            index += 1

        self.b = [Radiobutton(self.frame1, text='B', command=lambda: self.activate_b(0), value=0),
                  Radiobutton(self.frame1, text='B', command=lambda: self.activate_b(1), value=0),
                  Radiobutton(self.frame1, text='B', command=lambda: self.activate_b(2), value=0),
                  Radiobutton(self.frame1, text='B', command=lambda: self.activate_b(3), value=0),
                  Radiobutton(self.frame2, text='B', command=lambda: self.activate_b(4), value=0),
                  Radiobutton(self.frame2, text='B', command=lambda: self.activate_b(5), value=0),
                  Radiobutton(self.frame2, text='B', command=lambda: self.activate_b(6), value=0),
                  Radiobutton(self.frame2, text='B', command=lambda: self.activate_b(7), value=0)]

        index = 0
        for each in self.b:
            each.grid(row=index % 4, column=3)
            each.config(width=4, height=2,  indicatoron=0, variable=self.v[index], font=('Lucida Console', 30))
            each.config(bg='SkyBlue4', activebackground='midnight blue', selectcolor='midnight blue', fg='white')
            each.config(activeforeground='white')
            index += 1

        self.end_image = PhotoImage(file="img/no.png").subsample(x=6, y=6)
        self.end_button = [Radiobutton(self.frame1, image=self.end_image, command=lambda: self.end(0)),
                           Radiobutton(self.frame1, image=self.end_image, command=lambda: self.end(1)),
                           Radiobutton(self.frame1, image=self.end_image, command=lambda: self.end(2)),
                           Radiobutton(self.frame1, image=self.end_image, command=lambda: self.end(3)),
                           Radiobutton(self.frame2, image=self.end_image, command=lambda: self.end(4)),
                           Radiobutton(self.frame2, image=self.end_image, command=lambda: self.end(5)),
                           Radiobutton(self.frame2, image=self.end_image, command=lambda: self.end(6)),
                           Radiobutton(self.frame2, image=self.end_image, command=lambda: self.end(7)),
                           ]

        index = 0
        for each in self.end_button:
            each.grid(row=index % 4, column=5)
            each.config(value=2, variable=self.v[index], indicatoron=0)
            each.config(bg='brown3', activebackground='brown4')
            index += 1
        

    def make_frame(self):
        self.frame1.grid(row=2, column=0, rowspan=5)
        self.frame2.grid(row=2, column=1, rowspan=5)
        self.end_all_button.grid(row=1, column=0, columnspan=2)

        row = 0
        for each in self.lightsA:
            each.grid(row=row % 4, column=1, padx=20, pady=20)
            row += 1

        row = 0
        for each in self.lightsB:
            each.grid(row=row % 4, column=4, padx=20, pady=20)
            row += 1


    def delete_frame(self):
        self.frame1.grid_remove()
        self.frame2.grid_remove()
        self.end_all_button.grid_remove()

        for each in self.lightsA:
            each.grid_remove()

        for each in self.lightsB:
            each.grid_remove()

    def activate_a(self, number):
        pin_number = 65 + number
        pin_opposite = 80 - number

        if self.v[number].get() == 1:
            self.lightsA[number].set_state(True)
            self.lightsB[number].set_state(False)
            
            wiringpi.digitalWrite(pin_number, 1)
            wiringpi.digitalWrite(pin_opposite, 0)

    def activate_b(self, number):
        pin_number = 80 - number
        pin_opposite = 65 + number

        if self.v[number].get() == 0:
            self.lightsA[number].set_state(False)
            self.lightsB[number].set_state(True)
            wiringpi.digitalWrite(pin_number, 1)
            wiringpi.digitalWrite(pin_opposite, 0)
            

    def end(self, number):
        pin_number = 65 + number
        pin_opposite = 80 - number

        wiringpi.digitalWrite(pin_number, 0)
        wiringpi.digitalWrite(pin_opposite, 0)

        self.v[number].set(3)
        self.lightsA[number].set_state(False)
        self.lightsB[number].set_state(False)

    def end_all(self):
        number = 0
        while number < 8:
            self.end(number)
            number += 1
示例#12
0
class PianoTutor:
    def __init__(self, root):
        self.root = root
        self.root.resizable(False, False)
        self.root.title('Piano Tutor')
        self.keys = []
        self.load_json_files()
        self.keys_to_highlight = []
        self.build_mode_selector_frame()
        self.build_score_sheet_frame()
        self.build_controls_frame()
        self.build_keyboard_frame()
        self.build_chords_frame()
        self.build_progressions_frame()
        self.build_scales_frame()
        self.find_scale()

    def load_json_files(self):
        with open(SCALES_JSON_FILE, 'r') as f:
            self.scales = json.load(f, object_pairs_hook=OrderedDict)
        with open(CHORDS_JSON_FILE, 'r') as f:
            self.chords = json.load(f, object_pairs_hook=OrderedDict)

    def on_chord_changed(self, event):
        self.remove_all_key_highlights()
        self.find_chord(event)

    def on_chords_key_changed(self, event):
        self.remove_all_key_highlights()
        self.find_chord(event)

    def find_chord(self, event=None):
        self.selected_chord = self.chords_selector.get()
        self.chords_selected_key = self.chords_key_selector.get()
        index_of_selected_key = KEYS.index(self.chords_selected_key)
        self.keys_to_highlight = [ ALL_KEYS[i+index_of_selected_key] for \
                              i in self.chords[self.selected_chord]]
        self.highlight_list_of_keys(self.keys_to_highlight)
        play_chord_in_new_thread(self.keys_to_highlight)

    def on_scale_changed(self, event):
        self.remove_all_key_highlights()
        self.find_scale(event)

    def on_scale_key_changed(self, event):
        self.remove_all_key_highlights()
        self.find_scale(event)

    def find_scale(self, event=None):
        self.selected_scale = self.scale_selector.get()
        self.scale_selected_key = self.scale_key_selector.get()
        index_of_selected_key = KEYS.index(self.scale_selected_key)
        self.keys_to_highlight = [ ALL_KEYS[i+index_of_selected_key] \
                              for i in self.scales[self.selected_scale]]
        self.highlight_list_of_keys(self.keys_to_highlight)
        play_scale_in_new_thread(self.keys_to_highlight)

    def highlight_list_of_keys(self, key_names):
        for key in key_names:
            self.highlight_key(key)

    def highlight_key(self, key_name):
        if len(key_name) == 2:
            img = WHITE_KEY_PRESSED_IMAGE
        elif len(key_name) == 3:
            img = BLACK_KEY_PRESSED_IMAGE
        key_img = PhotoImage(file=img)
        for widget in self.keys:
            if widget.name == key_name:
                widget.configure(image=key_img)
                widget.image = key_img

    def remove_key_highlight(self, key_name):
        if len(key_name) == 2:
            img = WHITE_KEY_IMAGE
        elif len(key_name) == 3:
            img = BLACK_KEY_IMAGE
        key_img = PhotoImage(file=img)
        for widget in self.keys:
            if widget.name == key_name:
                widget.configure(image=key_img)
                widget.image = key_img

    def remove_all_key_highlights(self):
        for key in self.keys_to_highlight:
            self.remove_key_highlight(key)
        self.keys_to_highlight = []

    def build_mode_selector_frame(self):
        self.mode_selector_frame = Frame(self.root,
                                         width=WINDOW_WIDTH,
                                         height=MODE_SELECTOR_HEIGHT)
        self.mode_selector_frame.grid_propagate(False)
        self.mode_selector = ttk.Combobox(self.mode_selector_frame,
                                          values=CHOICES)
        self.mode_selector.bind('<<ComboboxSelected>>', self.on_mode_changed)
        self.mode_selector.current(0)
        self.mode_selector.grid(
            row=0,
            column=1,
            columnspan=3,
            padx=10,
            pady=10,
            sticky='nsew',
        )
        self.mode_selector_frame.grid(row=0, column=0)

    def build_score_sheet_frame(self):
        self.score_sheet_frame = Frame(self.root,
                                       width=WINDOW_WIDTH,
                                       height=SCORE_DISPLAY_HEIGHT,
                                       background='SteelBlue1')
        self.score_sheet_frame.grid_propagate(False)
        Label(self.score_sheet_frame,
              text='placeholder for score sheet',
              background='SteelBlue1').grid(row=1, column=1)
        self.score_sheet_frame.grid(row=1, column=0)

    def build_controls_frame(self):
        self.controls_frame = Frame(self.root,
                                    width=WINDOW_WIDTH,
                                    height=CONTROLS_FRAME_HEIGHT)
        self.controls_frame.grid_propagate(False)
        self.controls_frame.grid(row=2, column=0)

    def build_keyboard_frame(self):
        self.keyboard_frame = Frame(self.root,
                                    width=WINDOW_WIDTH,
                                    height=KEYBOARD_HEIGHT,
                                    background='LavenderBlush2')
        self.keyboard_frame.grid_propagate(False)
        self.keyboard_frame.grid(row=4, column=0, sticky='nsew')
        for (index, key) in enumerate(WHITE_KEY_NAMES):
            x = WHITE_KEY_X_COORDINATES[index]
            self.create_key(WHITE_KEY_IMAGE, key, x)
        for (index, key) in enumerate(BLACK_KEY_NAMES):
            x = BLACK_KEY_X_COORDINATES[index]
            self.create_key(BLACK_KEY_IMAGE, key, x)

    def build_scales_frame(self):
        self.scales_frame = Frame(self.controls_frame,
                                  width=WINDOW_WIDTH,
                                  height=CONTROLS_FRAME_HEIGHT)
        self.scales_frame.grid(row=1, column=0, sticky='nsew')
        Label(self.scales_frame, text='Select scale').grid(row=0, \
                                column=1, sticky='w', padx=10,pady=1)
        self.scale_selector = ttk.Combobox(self.scales_frame, \
                                values=[k for k in self.scales.keys()])
        self.scale_selector.current(0)
        self.scale_selector.bind("<<ComboboxSelected>>", \
                                            self.on_scale_changed)
        self.scale_selector.grid(row=1, column=1, sticky='e', padx=10,\
                                                                pady=10)
        Label(self.scales_frame, text='in the key of').grid(row=0, \
                                column=2, sticky='w', padx=10,pady=1)
        self.scale_key_selector = ttk.Combobox(self.scales_frame, \
                                    values=[k for k in KEYS])
        self.scale_key_selector.current(0)
        self.scale_key_selector.bind("<<ComboboxSelected>>", \
                                    self.on_scale_key_changed)
        self.scale_key_selector.grid(row=1, column=2, sticky='e', \
                                    padx=10, pady=10)

    def build_chords_frame(self):
        self.chords_frame = Frame(self.controls_frame,
                                  width=WINDOW_WIDTH,
                                  height=CONTROLS_FRAME_HEIGHT)
        self.chords_frame.grid_propagate(False)
        self.chords_frame.grid(row=1, column=0, sticky='nsew')
        Label(self.chords_frame, text='Select Chord').grid(row=0, \
                            column=1, sticky='w', padx=10,pady=1)
        self.chords_selector = ttk.Combobox(self.chords_frame, \
                            values=[k for k in self.chords.keys()])
        self.chords_selector.current(0)
        self.chords_selector.bind("<<ComboboxSelected>>", \
                                    self.on_chord_changed)
        self.chords_selector.grid(row=1, column=1, sticky='e', \
                                        padx=10, pady=10)
        Label(self.chords_frame, text='in the key of').grid(row=0, \
                                column=2, sticky='w', padx=10,pady=1)
        self.chords_key_selector = ttk.Combobox(self.chords_frame, \
                                        values=[k for k in KEYS])
        self.chords_key_selector.current(0)
        self.chords_key_selector.bind("<<ComboboxSelected>>", \
                                    self.on_chords_key_changed)
        self.chords_key_selector.grid(row=1,
                                      column=2,
                                      sticky='e',
                                      padx=10,
                                      pady=10)

    def build_progressions_frame(self):
        self.progressions_frame = Frame(self.controls_frame,
                                        width=WINDOW_WIDTH,
                                        height=CONTROLS_FRAME_HEIGHT)
        self.progressions_frame.grid_propagate(False)
        Label(self.progressions_frame,
              text='placeholder for progression frame').grid(row=1, column=1)
        self.progressions_frame.grid(row=1, column=0, sticky='nsew')

    def on_mode_changed(self, event):
        self.remove_all_key_highlights()
        selected_mode = self.mode_selector.get()
        if selected_mode == 'Scales':
            self.show_scales_frame()
            self.find_scale()
        elif selected_mode == 'Chords':
            self.show_chords_frame()
            self.find_chord()
        elif selected_mode == 'Chord Progressions':
            self.show_progressions_frame()

    def show_scales_frame(self):
        self.chords_frame.grid_remove()
        self.progressions_frame.grid_remove()
        self.scales_frame.grid()

    def show_chords_frame(self):
        self.chords_frame.grid()
        self.progressions_frame.grid_remove()
        self.scales_frame.grid_remove()

    def show_progressions_frame(self):
        self.chords_frame.grid_remove()
        self.progressions_frame.grid()
        self.scales_frame.grid_remove()

    def create_key(self, img, key_name, x_coordinate):
        key_image = PhotoImage(file=img)
        label = Label(self.keyboard_frame, image=key_image, border=0)
        label.image = key_image
        label.place(x=x_coordinate, y=0)
        label.name = key_name
        label.bind('<Button-1>', self.on_key_pressed)
        label.bind('<ButtonRelease-1>', self.on_key_released)
        self.keys.append(label)
        return label

    def change_image_to_pressed(self, event):
        if len(event.widget.name) == 2:
            img = WHITE_KEY_PRESSED_IMAGE
        elif len(event.widget.name) == 3:
            img = BLACK_KEY_PRESSED_IMAGE
        key_img = PhotoImage(file=img)
        event.widget.configure(image=key_img)
        event.widget.image = key_img

    def change_image_to_unpressed(self, event):
        if len(event.widget.name) == 2:
            img = WHITE_KEY_IMAGE
        elif len(event.widget.name) == 3:
            img = BLACK_KEY_IMAGE
        key_img = PhotoImage(file=img)
        event.widget.configure(image=key_img)
        event.widget.image = key_img

    def on_key_pressed(self, event):
        play_note(event.widget.name)
        self.change_image_to_pressed(event)

    def on_key_released(self, event):
        print(event.widget.name + ' released')
        self.change_image_to_unpressed(event)
示例#13
0
class Spectrogram(Module):
    def __init__(self, app):
        info(' - initializing module: Spectrogram')

        self.app = app

        self.frame = Frame(self.app.BOTTOM)
        self.frame.grid(row=0,
                        column=1,
                        pady=(self.app.pady * 2, self.app.pady / 2))
        self.axis_frame = Frame(self.app.BOTTOM)
        self.axis_frame.grid(row=0,
                             column=0,
                             sticky='e',
                             pady=(self.app.pady * 2, self.app.pady / 2))
        self.canvas_width = self.app.TextGrid.canvas_width
        self.canvas_height = 106
        self.canvas = Canvas(self.frame,
                             width=self.canvas_width,
                             height=self.canvas_height,
                             background='gray',
                             highlightthickness=0)
        self.spectrogram = None
        self.spec_freq_max = DoubleVar()
        self.wl = DoubleVar()
        self.dyn_range = DoubleVar()
        self.clicktime = -1
        self.specClick = False
        self.oldSelected = None
        self.doDefaults()

        #make spinboxes & buttons for spectrogram specs
        self.spinwin = Frame(self.axis_frame)
        #spinboxes
        axis_ceil_box = Spinbox(self.spinwin,
                                textvariable=self.spec_freq_max,
                                command=self.drawSpectrogram,
                                width=7,
                                increment=100,
                                from_=0,
                                to_=100000)
        axis_ceil_box.bind('<Return>', self.drawSpectrogram)
        axis_ceil_box.bind('<Escape>', lambda ev: self.spinwin.focus())
        wl_box = Spinbox(self.spinwin,
                         textvariable=self.wl,
                         command=self.drawSpectrogram,
                         width=7,
                         increment=0.0005,
                         from_=0,
                         to_=1)
        wl_box.bind('<Return>', self.drawSpectrogram)
        wl_box.bind('<Escape>', lambda ev: self.spinwin.focus())
        dyn_range_box = Spinbox(self.spinwin,
                                textvariable=self.dyn_range,
                                command=self.drawSpectrogram,
                                width=7,
                                increment=10,
                                from_=0,
                                to_=10000)
        dyn_range_box.bind('<Return>', self.drawSpectrogram)
        dyn_range_box.bind('<Escape>', lambda ev: self.spinwin.focus())
        #buttons
        default_btn = Button(self.spinwin,
                             text='Standards',
                             command=self.restoreDefaults,
                             takefocus=0)
        apply_btn = Button(self.spinwin,
                           text='Apply',
                           command=self.drawSpectrogram,
                           takefocus=0)

        # self.axis_frame.create_window(wwidth,self.canvas_height, window=self.spinwin, anchor='ne')
        #grid spinboxes & buttons on subframe
        axis_ceil_box.grid(row=0, columnspan=2, sticky='ne')
        wl_box.grid(row=1, columnspan=2, sticky='ne')
        dyn_range_box.grid(row=2, columnspan=2, sticky='ne')
        default_btn.grid(row=3)
        apply_btn.grid(row=3, column=1)

        self.grid()

        self.canvas.bind('<Button-1>', self.jumpToFrame)
        # self.canvas.bind('<Shift-Button-1>', self.jumpToFrame)

    def doDefaults(self):
        self.spec_freq_max.set(5000.0)
        self.wl.set(0.005)
        self.dyn_range.set(90)

    def restoreDefaults(self):
        self.doDefaults()
        self.drawSpectrogram()

    def update(self):
        '''
        Removes and redraws lines on top of Spectrogram corresponding to selected interval(s)
        '''
        self.canvas.delete('line')
        self.drawInterval()

    def reset(self):
        self.drawSpectrogram()
        self.drawInterval()

    def drawSpectrogram(self, event=None):
        '''
        Extracts spectrogram data from sound, and draws it to canvas
        '''
        if not LIBS_INSTALLED:
            return

        if self.app.Audio.current:
            sound = parselmouth.Sound(self.app.Audio.current)

            ts_fac = decimal.Decimal(10000.0)
            wl = decimal.Decimal(self.wl.get())
            start_time = decimal.Decimal(self.app.TextGrid.start)
            end_time = decimal.Decimal(self.app.TextGrid.end)

            # the spectrogram is for the audio file, so it makes sense
            # to get the duration from the audio file and not from the
            # textgrid -JNW
            if start_time == end_time:
                end_time = decimal.Decimal(sound.get_total_duration())
            duration = end_time - start_time
            #duration = decimal.Decimal(sound.get_total_duration())
            # in case there isn't a TextGrid or there's some other issue: -JNW

            self.ts = duration / ts_fac
            # the amount taken off in spectrogram creation seems to be
            # ( 2 * ts * floor( wl / ts ) ) + ( duration % ts )
            # but we've defined ts as duration / 10000, so duration % ts = 0
            # so the amount to increase the length by is ts * floor( wl / ts )
            # at either end - D.S.
            extra = self.ts * math.floor(wl / self.ts)
            start_time = max(0, start_time - extra)
            end_time = min(end_time + extra, sound.get_total_duration())
            sound_clip = sound.extract_part(from_time=start_time,
                                            to_time=end_time)

            spec = sound_clip.to_spectrogram(
                window_length=wl,
                time_step=self.ts,
                maximum_frequency=self.spec_freq_max.get())
            self.spectrogram = 10 * np.log10(np.flip(spec.values, 0))

            # self.spectrogram += self.spectrogram.min()
            # self.spectrogram *= (60.0 / self.spectrogram.max())

            mx = self.spectrogram.max()
            dyn = self.dyn_range.get()
            # debug(self.spectrogram.min(), self.spectrogram.max())
            self.spectrogram = self.spectrogram.clip(mx - dyn, mx) - mx
            # debug(self.spectrogram.min(), self.spectrogram.max())
            self.spectrogram *= (-255.0 / dyn)
            # self.spectrogram += 60
            # debug(self.spectrogram.min(), self.spectrogram.max())

            img = PIL.Image.fromarray(self.spectrogram)
            if img.mode != 'RGB':
                img = img.convert('RGB')
            # contrast = ImageEnhance.Contrast(img)
            # img = contrast.enhance(5)
            # self.canvas_height = img.height
            img = img.resize((self.canvas_width, self.canvas_height))

            photo_img = ImageTk.PhotoImage(img)
            self.canvas.config(height=self.canvas_height)

            # self.canvas.create_image(0,0, anchor='nw', image=photo_img)
            # self.canvas.create_image(self.canvas_width/2,self.canvas_height/2, image=photo_img)
            if self.app.TextGrid.selectedItem:
                tags = self.app.TextGrid.selectedItem[0].gettags(
                    self.app.TextGrid.selectedItem[1])
            self.canvas.delete('all')
            img = self.canvas.create_image(self.canvas_width,
                                           self.canvas_height,
                                           anchor='se',
                                           image=photo_img)
            self.img = photo_img
            #pass on selected-ness
            if self.app.TextGrid.selectedItem:
                if self.app.TextGrid.selectedItem[0] == self.canvas:
                    self.app.TextGrid.selectedItem = (self.canvas, img)
                    #pass on tags
                    for tag in tags:
                        self.canvas.addtag_all(tag)

    def drawInterval(self):
        '''
        Adapted with permission from
        https://courses.engr.illinois.edu/ece590sip/sp2018/spectrograms1_wideband_narrowband.html
        by Mark Hasegawa-Johnson
        '''
        if self.app.TextGrid.selectedItem:
            widg = self.app.TextGrid.selectedItem[0]
            itm = self.app.TextGrid.selectedItem[1]

            if widg in self.app.TextGrid.tier_pairs:  #if widg is label
                itvl_canvas = self.app.TextGrid.tier_pairs[widg]
                for i in itvl_canvas.find_withtag('line'):
                    loc = itvl_canvas.coords(i)[0]
                    self.canvas.create_line(loc,
                                            0,
                                            loc,
                                            self.canvas_height,
                                            tags='line',
                                            fill='blue')
            elif widg in self.app.TextGrid.tier_pairs.values(
            ):  #if widg is textgrid canvas
                if itm - 1 in widg.find_all():
                    l_loc = widg.coords(itm - 1)[0]
                    self.canvas.create_line(l_loc,
                                            0,
                                            l_loc,
                                            self.canvas_height,
                                            tags='line',
                                            fill='blue')
                if itm + 1 in widg.find_all():
                    r_loc = widg.coords(itm + 1)[0]
                    self.canvas.create_line(r_loc,
                                            0,
                                            r_loc,
                                            self.canvas_height,
                                            tags='line',
                                            fill='blue')
            elif widg == self.canvas:
                l_time, r_time = self.app.TextGrid.getMinMaxTime()
                l_loc = self.timeToX(float(l_time))
                r_loc = self.timeToX(float(r_time))
                self.canvas.create_line(l_loc,
                                        0,
                                        l_loc,
                                        self.canvas_height,
                                        tags='line',
                                        fill='blue')
                self.canvas.create_line(r_loc,
                                        0,
                                        r_loc,
                                        self.canvas_height,
                                        tags='line',
                                        fill='blue')

            #draw selected frame
            if self.app.TextGrid.firstFrame <= self.app.frame <= self.app.TextGrid.lastFrame:
                xcoord = self.app.TextGrid.frames_canvas.coords(
                    self.app.TextGrid.highlighted_frame)[0]
                self.canvas.create_line(xcoord,
                                        0,
                                        xcoord,
                                        self.canvas_height,
                                        tags='line',
                                        fill='red')
            #draw line where user last clicked on spectrogram
            if self.clicktime != -1 and self.specClick == False:
                x = self.timeToX(self.clicktime)
                self.canvas.create_line(x,
                                        0,
                                        x,
                                        self.canvas_height,
                                        tags='line',
                                        fill='green')

    def jumpToFrame(self, event):
        '''  '''
        #restore textgrid selected interval between clicks
        if not self.app.TextGrid.selectedItem:
            key = next(iter(self.app.TextGrid.tier_pairs))
            wdg = self.app.TextGrid.tier_pairs[key]
            self.app.TextGrid.selectedItem = (wdg, wdg.find_all()[0])
            self.app.TextGrid.setSelectedIntvlFrames(
                self.app.TextGrid.selectedItem)
        if self.app.TextGrid.selectedItem[0] == self.canvas:
            self.app.TextGrid.selectedItem = self.oldSelected
            self.app.TextGrid.setSelectedIntvlFrames(
                self.app.TextGrid.selectedItem)
        #prevents wiping of canvases because of mouse click
        # self.app.resized = False
        # draw line at click location
        x = self.canvas.canvasx(event.x)
        self.clicktime = self.xToTime(x)
        #jump to new frame
        frame = self.app.TextGrid.my_find_closest(
            self.app.TextGrid.frames_canvas, self.canvas.canvasx(event.x))
        framenum = self.app.TextGrid.frames_canvas.gettags(frame)[0][5:]
        self.app.frame = int(framenum)
        self.app.framesUpdate()
        #remember which interval was selected before specgram click
        if event.state == 1:
            self.oldSelected = self.app.TextGrid.selectedItem
            #for selecting & zooming interval (w/ shift)
            self.specClick = True

    def xToTime(self, x):
        ''' converts from a x coordinate (relative to the canvas) to the timestamp at that coordinate'''
        return (x * float(self.app.TextGrid.end - self.app.TextGrid.start) /
                self.canvas_width) + float(self.app.TextGrid.start)

    def timeToX(self, time):
        ''' converts from a time to the x coordinate on a canvas representing that time'''
        return self.canvas_width * (time - float(
            self.app.TextGrid.start)) / float(self.app.TextGrid.end -
                                              self.app.TextGrid.start)

    def grid(self):
        '''
        Put tkinter items on app
        '''
        self.canvas.grid(row=0, column=0, sticky='news')
        self.spinwin.grid(row=0, column=0, sticky='ne')
        # self.axis_canvas.grid(row=0,column=0,sticky='se')

    def grid_remove(self):
        self.canvas.grid_remove()
        self.spinwin.grid_remove()
示例#14
0
class Playback(Module):
    '''
    Module to handle playback of audio and video files.
    '''
    def __init__(self, app):
        self.app = app
        self.current = None
        if AUDIO_LIBS_INSTALLED:
            info( ' - initializing module: Audio' )
            self.sfile = None
            self.p = pyaudio.PyAudio()
            self.currentInterval = None
            self.started = False
            self.paused = False
            self.sync = threading.Event()
            self.stoprequest = threading.Event()

            # widget management
            self.frame = Frame(self.app.BOTTOM)
            self.playBtn = Button(self.frame, text="Play/Pause", command=self.playpauseAV, state='disabled', takefocus=0) # NOTE: not currently appearing
            self.app.bind('<space>', self.playpauseAV )
            self.app.bind('<Escape>', self.stopAV )
        if VIDEO_LIBS_INSTALLED:
            info( ' - initializing module: Video' )
            self.app.bind('<space>', self.playpauseAV )
            self.app.bind('<Escape>', self.stopAV )
        self.reset()

    def update(self):
        '''
        don't change the audio file when we change frames
        '''
        pass

    def reset(self):
        '''
        try to load an audio file
        '''
        if AUDIO_LIBS_INSTALLED:
            self.current = None
            audioFallbacks = [ '.wav', '.flac', '.ogg', '.mp3' ]
            for codec in audioFallbacks:
                if self.loadAudio( codec ) == True:
                    self.playBtn.config( state='normal' )
                    return

    def loadAudio(self, codec):
        '''
        load an audio file with a specific codec
        '''
        audiofile = self.app.Data.getFileLevel( codec )
        if audiofile != None:
            try:
                audiofile = self.app.Data.unrelativize(audiofile)
                self.sfile = AudioSegment.from_file( audiofile )
                self.current = audiofile
                self.duration = len(self.sfile)/1000.0
                return True
            except Exception as e:
                error('Unable to load audio file: `%s`' % audiofile, e)
                return False

    def playpauseAV(self, event):
        '''

        '''
        # debug(self.started, self.paused, '1858')
        if self.started == False or self.currentInterval != self.app.TextGrid.selectedItem: #if we haven't started playing or we're in a new interval
            #reset monitoring variables
            self.currentInterval = self.app.TextGrid.selectedItem
            self.started = False
            self.paused = False

            if self.app.TextGrid.selectedItem:
                start, end = self.app.TextGrid.getMinMaxTime()
            else:
                start = self.app.TextGrid.start
                end = self.app.TextGrid.end

            # if VIDEO_LIBS_INSTALLED and AUDIO_LIBS_INSTALLED:
            #   self.readyVideo()
            #   self.readyAudio(start, end)
            #   self.playAudio()
            # elif AUDIO_LIBS_INSTALLED:
            #   self.readyAudio(start, end)
            #   self.playAudio()
            # elif VIDEO_LIBS_INSTALLED:
            #   self.readyVideo()
            #   self.dicomframeQ = queue.Queue()
            #   for i in range(len(self.pngs)):
            #       self.dicomframeQ.put(self.pngs[i])
            #   self.playVideoNoAudio()

            if self.app.Dicom.isLoaded():
                self.readyVideo()
            if AUDIO_LIBS_INSTALLED:
                self.readyAudio(start, end)
                self.playAudio()
            elif self.app.Dicom.isLoaded():
                self.dicomframeQ = queue.Queue()
                for i in range(len(self.pngs)):
                    self.dicomframeQ.put(self.pngs[i])
                self.playVideoNoAudio()

        elif self.started == True:
            if self.paused == False:
                self.paused = True
                self.stream.stop_stream()
            else:
                self.paused = False
                self.playAudio()

    def readyAudio(self, start, end):
        '''

        '''
        #audio stuff
        start_idx = round(float(start)*1000)
        end_idx = round(float(end)*1000)
        self.flen = float(self.app.TextGrid.frame_len)
        fpb = 512
        extrafs = (end_idx-start_idx)%fpb
        extrasecs = extrafs/self.sfile.frame_rate
        pad = AudioSegment.silent(duration=round(extrasecs*1000))
        seg_nopad = self.sfile[start_idx:end_idx]
        self.seg = seg_nopad + pad
        # seg.append()
        self.audioframe = 0

        # open stream using callback (3)
        self.stream = self.p.open(format=self.p.get_format_from_width(self.seg.sample_width),
                        channels=self.seg.channels,
                        rate=self.seg.frame_rate,
                        frames_per_buffer=fpb,
                        output=True,
                        start=False,
                        stream_callback=self.callback)

        # debug(self.seg.frame_count()/fpb, 'number of chunks')
        # debug(self.seg.frame_count()%fpb, 'last chunk size')
        # self.chunkcount = 0

    def readyVideo(self):
        '''

        '''
        self.app.Trace.reset()
        tags = self.app.TextGrid.selectedItem[0].gettags(self.app.TextGrid.selectedItem[1])
        framenums = [tag[5:] for tag in tags if tag[:5]=='frame']
        self.framestart = int(framenums[0])
        imgs = self.app.Dicom.getFrames(framenums)
        canvas = self.app.Dicom.zframe.canvas
        bbox = canvas.bbox(canvas.find_all()[0])
        dim = (bbox[2] - bbox[0], bbox[3] - bbox[1])
        self.pngs = []
        traces = self.app.Data.getTopLevel('traces')
        file = self.app.Data.getCurrentFilename()
        l = util.CROSSHAIR_SELECT_RADIUS
        for frame, img in zip(framenums, imgs):
            img = img.resize(dim)
            draw = ImageDraw.Draw(img)
            for name in traces:
                color = traces[name]['color']
                if file in traces[name]['files'] and frame in traces[name]['files'][file]:
                    for pt in traces[name]['files'][file][frame]:
                        x = int(pt['x'] * img.width)
                        y = int(pt['y'] * img.height)
                        draw.line((x-l, y, x+l, y), fill=color)
                        draw.line((x, y-l, x, y+l), fill=color)
            del draw
            self.pngs.append(ImageTk.PhotoImage(img))

        #video w/audio stuff
        self.dicomframe_timer = 0
        self.dicomframe_num = 1
        self.dicomframeQ = queue.Queue()
        self.dicomframeQ.put(self.pngs[0]) #put now, because audio callback puts frames when audio segments end
        # for i in range(len(self.pngs)):
        #   self.dicomframeQ.put(self.pngs[i])

    def callback(self, in_data, frame_count, time_info, status):
        '''
        Called by pyaudio stream. Gets chunks of audio ready for playing
        With video capabilities, also updates video frame information
        '''
        # self.sync.clear()
        # self.chunkcount+=1
        data = b''.join([self.seg.get_frame(i) for i in range(self.audioframe, self.audioframe+frame_count)])
        # debug(len(data), 'line 1960')
        self.audioframe+=frame_count

        if self.app.Dicom.isLoaded():
            #check & update video frame
            canvas = self.app.Dicom.zframe.canvas
            callbacklen = frame_count/self.seg.frame_rate
            self.dicomframe_timer += callbacklen
            #go to next frame
            if self.dicomframe_timer % self.flen != self.dicomframe_timer and self.dicomframe_num < len(self.pngs):
                floor = math.floor(self.dicomframe_timer/self.flen)
                # debug(floor, 'line 1961')
                self.dicomframe_timer = self.dicomframe_timer-self.flen*floor
                if floor > 1:
                    for i in range(floor-1):
                        # debug(self.dicomframe_num+self.framestart+i, 'putting frame into Q')
                        if self.dicomframe_num+i < len(self.pngs):
                            self.dicomframeQ.put(self.pngs[self.dicomframe_num+i])
                else:
                    self.dicomframeQ.put(self.pngs[self.dicomframe_num])
                # self.sync.set()
                self.dicomframe_num+=floor

                # debug(self.dicomframe_num, len(self.pngs), 'line 1968')
            # else: #stop video loop
                if self.dicomframe_num >= len(self.pngs):
                    self.stoprequest.set()

        return (data, pyaudio.paContinue)

    def playAudio(self):
        self.stream.start_stream()
        self.started = True
        if self.app.Dicom.isLoaded():
            self.playVideoWithAudio()
        else:
            pass #write a loop that keeps audio playing
        # stop stream (6)
        if self.stoprequest.is_set():
            self.stopAV()
        # self.stream.stop_stream()
        # if self.stoprequest.is_set():
        #   self.stream.close()
        #   self.started = False
        # debug(self.chunkcount)
        # close PyAudio (7)
        # self.p.terminate() # NOTE: needs to be removed in order to play multiple audio files in a row

    def playVideoWithAudio(self):
        '''

        '''
        # self.sync.wait()
        if self.paused == True:
            return
        canvas = self.app.Dicom.zframe.canvas
        # debug(self.dicomframeQ.qsize(),'line 1991')
        try:
            pic = self.dicomframeQ.get(timeout=.5)
            canvas.itemconfig(canvas.find_all()[0] , image=pic )
            # canvas.lift(pic)
            # canvas.img = pic
            canvas.update()
        except Exception as e:
            error(e)
        # debug(pic, 'displayed')
        # debug(self.dicomframe_num+self.framestart, 'displayed')
        if not self.stoprequest.is_set() or not self.dicomframeQ.empty(): #should this if be at the top?
            self.playVideoWithAudio()
            # canvas.after(10, self.playVideoWithAudio)

    def playVideoNoAudio(self):
        '''

        '''
        canvas = self.app.Dicom.zframe.canvas
        # pic = self.dicomframeQ.get()
        pic = self.dicomframeQ.get(block=False)
        canvas.itemconfig( canvas.find_all()[0], image=pic )
        canvas.update()
        if not self.dicomframeQ.empty() and self.stoprequest.is_set() == False: #should this if be at the top?
            self.playVideoNoAudio()

    def stopAV(self,event=None):
        self.stoprequest.set()
        if AUDIO_LIBS_INSTALLED:
            self.stream.stop_stream()
            self.stream.close()
        self.started = False
        self.paused = False
        self.app.framesJumpTo()
        self.stoprequest.clear()

    def grid(self):
        ''' grid widgets '''
        self.frame.grid( row=0 )
        self.playBtn.grid()

    def grid_remove(self):
        ''' remove widgets from grid '''
        self.frame.grid_remove()
        self.playBtn.grid_remove()
示例#15
0
class Tab(ABC):
    def __init__(self, view, tab_control):
        self.view = view
        self.bandas_estandar_repository = RepositoryProvider.provide_bandas_estandar_repository(
        )
        self.tab_frame = tab_control.agregar_tab(self, self.titulo_tab)
        self.construir_tab()

    @abstractmethod
    def obtener_bandas(self):
        pass

    def construir_tab(self):
        self.construir_frame_titulo()
        self.construir_frame_grafica()
        self.construir_frame_medicion()

    def construir_frame_titulo(self):
        self.frame_titulo_grafica = Frame(self.tab_frame)
        self.frame_titulo_grafica.config(width=400,
                                         borderwidth=2,
                                         relief="groove")
        self.frame_titulo_grafica.grid(row=0,
                                       column=0,
                                       sticky="nsew",
                                       padx=10,
                                       pady=(15, 0))
        self.label_titulo_grafica = Label(self.frame_titulo_grafica)
        self.label_titulo_grafica.config(
            text="Nivel de respuesta impulsional - Curva de decaimiento",
            bg="#0c005a")
        self.label_titulo_grafica.pack(fill="both", expand="True")

    def construir_frame_grafica(self):
        self.frame_grafica = Frame(self.tab_frame)
        self.frame_grafica.grid(row=1, column=0, padx=10, pady=10)
        self.frame_label_grafica = Frame(self.frame_grafica)
        self.frame_label_grafica.config(width=600, height=400)
        self.frame_label_grafica.pack_propagate(False)
        self.frame_label_grafica.grid(row=0, column=0)
        self.label_grafica = Label(self.frame_label_grafica)
        self.label_grafica.config(borderwidth=2, relief="groove", bg="#5893d4")
        self.label_grafica.pack(expand="True", fill="both")
        self.frame_toolbar = Frame(self.frame_grafica)
        self.frame_toolbar.config(width=400, height=40, borderwidth=2)
        self.frame_toolbar.pack_propagate(False)
        self.frame_toolbar.grid(row=1, column=0, sticky="nsew")
        self.construir_plot()

    def construir_plot(self):
        self.figura = Figure(figsize=(6, 4), dpi=100)
        self.figura.patch.set_facecolor("#becbff")
        self.sistema_ejes = self.figura.add_subplot(1, 1, 1)
        self.sistema_ejes.set_facecolor("#dee1ec")
        self.limpiar_ejes()

        self.canvas = FigureCanvasTkAgg(self.figura, master=self.label_grafica)
        self.canvas.get_tk_widget().pack(side=BOTTOM, fill=BOTH, expand=True)

        toolbar = NavigationToolbar2Tk(self.canvas, self.frame_toolbar)
        toolbar.update()

    def limpiar_ejes(self):
        self.sistema_ejes.cla()
        self.sistema_ejes.set_xlabel('Tiempo (s)')
        self.sistema_ejes.set_ylabel('Nivel (dB)')
        self.sistema_ejes.set_xlim(left=0, auto=True)
        self.sistema_ejes.set_ylim(bottom=-120, top=0, auto=True)

    def construir_frame_medicion(self):
        self.frame_medicion = Frame(self.tab_frame)
        self.frame_medicion.grid(row=0, column=1, rowspan=2, sticky="nsew")
        self.construir_frame_bandas()

    def construir_frame_bandas(self):

        self.construir_seleccion_banda()
        self.construir_frame_rts()

    def construir_seleccion_banda(self):

        self.frame_titulo_bandas = Label(self.frame_medicion)
        self.frame_titulo_bandas.config(borderwidth=2, relief="groove")
        self.frame_titulo_bandas.grid(row=0,
                                      column=0,
                                      sticky="nsew",
                                      padx=10,
                                      pady=(15, 0))
        self.label_titulo_bandas_octava = Label(self.frame_titulo_bandas)
        self.label_titulo_bandas_octava.config(text=self.titulo_bandas_text,
                                               bg="#0c005a")
        self.label_titulo_bandas_octava.pack(ipadx=10,
                                             expand="True",
                                             fill="both")
        self.frame_medicion_bandas = Frame(self.frame_medicion)
        self.frame_medicion_bandas.grid(row=1,
                                        column=0,
                                        sticky="nsew",
                                        padx=10,
                                        pady=(20, 0))
        bandas_estandar = self.obtener_bandas()
        self.banda_seleccionada = StringVar()
        self.banda_seleccionada.set(bandas_estandar[0])
        self.combobox_banda = OptionMenu(self.frame_medicion_bandas,
                                         self.banda_seleccionada,
                                         *bandas_estandar)
        self.combobox_banda.config(relief="groove",
                                   borderwidth=0,
                                   bg="#5893d4",
                                   activebackground="#0060ca",
                                   width=20)
        self.combobox_banda['menu'].config(bg="#5893d4",
                                           activebackground="#0060ca")
        self.combobox_banda.grid(row=0, column=0, padx=10)
        self.ponderacion_A_checked = BooleanVar(False)
        self.checkbutton_ponderacion_A = Checkbutton(
            self.frame_medicion_bandas)
        self.checkbutton_ponderacion_A.config(
            text="Ponderación A",
            variable=self.ponderacion_A_checked,
            selectcolor="#5e0606")
        self.checkbutton_ponderacion_A.grid(row=0, column=1, padx=20)
        self.boton_calcular = Button(self.frame_medicion_bandas)
        self.boton_calcular.config(text="Calcular",
                                   command=self.view.on_calcular,
                                   bg="#5e0606",
                                   width=20)
        self.boton_calcular.grid(row=0, column=2, padx=10)

    def construir_frame_rts(self):

        self.frame_rts = Frame(self.frame_medicion)
        self.frame_rts.config(borderwidth=2, relief='ridge')
        self.frame_rts.grid(row=4, column=0, padx=10, pady=(15, 0))

        self.frame_titulo_rts = Label(self.frame_rts)
        self.frame_titulo_rts.config(borderwidth=2, relief="groove")
        self.frame_titulo_rts.grid(row=0,
                                   column=0,
                                   sticky="nsew",
                                   padx=10,
                                   pady=10,
                                   columnspan=2)
        self.label_titulo_rts = Label(self.frame_titulo_rts)
        self.label_titulo_rts.config(text="Tiempos de reverberación",
                                     bg="#0c005a")
        self.label_titulo_rts.pack(ipadx=10, expand="True", fill="both")
        self.frame_titulo_linealidad = Label(self.frame_rts)
        self.frame_titulo_linealidad.config(borderwidth=2, relief="groove")
        self.frame_titulo_linealidad.grid(row=0,
                                          column=2,
                                          sticky="nsew",
                                          padx=10,
                                          pady=10,
                                          columnspan=4)
        self.label_titulo_linealidad = Label(self.frame_titulo_linealidad)
        self.label_titulo_linealidad.config(text="Parámetros de linealidad",
                                            bg="#0c005a")
        self.label_titulo_linealidad.pack(ipadx=10, expand="True", fill="both")

        self.construir_frame_edt()
        self.construir_frame_t20()
        self.construir_frame_t30()
        self.construir_frame_curvatura()

        self.construir_frame_progressbar()

    def construir_frame_edt(self):

        self.frame_edt = Frame(self.frame_rts)
        self.frame_edt.grid(row=1, column=0, pady=(0, 10), columnspan=2)
        self.label_edt = Label(self.frame_edt)
        self.label_edt.config(text="EDT",
                              bg="#5893d4",
                              borderwidth=2,
                              relief="groove",
                              width=4)
        self.label_edt.grid(row=0, column=0, padx=(0, 10), pady=10)
        self.edt_var = StringVar()
        self.label_res_edt = Label(self.frame_edt)
        self.label_res_edt.config(relief="sunken",
                                  bg="#becbff",
                                  borderwidth=2,
                                  width=10,
                                  textvariable=self.edt_var,
                                  fg="black")
        self.label_res_edt.grid(row=0, column=1, padx=(10, 0), pady=10)
        self.frame_linealidad_edt = Frame(self.frame_rts)
        self.frame_linealidad_edt.grid(row=1,
                                       column=2,
                                       pady=(0, 10),
                                       columnspan=4)
        self.label_r_edt = Label(self.frame_linealidad_edt)
        self.label_r_edt.config(text="r",
                                bg="#5893d4",
                                borderwidth=2,
                                relief="groove",
                                width=4)
        self.label_r_edt.grid(row=0, column=0, padx=10, pady=10)
        self.r_edt_var = StringVar()
        self.label_res_r_edt = Label(self.frame_linealidad_edt)
        self.label_res_r_edt.config(relief="sunken",
                                    bg="#becbff",
                                    borderwidth=2,
                                    width=10,
                                    textvariable=self.r_edt_var,
                                    fg="black")
        self.label_res_r_edt.grid(row=0, column=1, padx=10, pady=10)
        self.label_xi_edt = Label(self.frame_linealidad_edt)
        self.label_xi_edt.config(text="ξ",
                                 bg="#5893d4",
                                 borderwidth=2,
                                 relief="groove",
                                 width=4)
        self.label_xi_edt.grid(row=0, column=2, padx=10, pady=10)
        self.xi_edt_var = StringVar()
        self.label_res_xi_edt = Label(self.frame_linealidad_edt)
        self.label_res_xi_edt.config(relief="sunken",
                                     bg="#becbff",
                                     borderwidth=2,
                                     width=10,
                                     fg="black",
                                     textvariable=self.xi_edt_var)
        self.label_res_xi_edt.grid(row=0, column=3, padx=10, pady=10)

    def construir_frame_t20(self):

        self.frame_t20 = Frame(self.frame_rts)
        self.frame_t20.grid(row=2, column=0, pady=(0, 10), columnspan=2)
        self.label_t20 = Label(self.frame_t20)
        self.label_t20.config(text="T20",
                              bg="#5893d4",
                              borderwidth=2,
                              relief="groove",
                              width=4)
        self.label_t20.grid(row=0, column=0, padx=(0, 10), pady=10, sticky='w')
        self.t20_var = StringVar()
        self.label_res_t20 = Label(self.frame_t20)
        self.label_res_t20.config(relief="sunken",
                                  borderwidth=2,
                                  bg="#becbff",
                                  width=10,
                                  textvariable=self.t20_var,
                                  fg='black')
        self.label_res_t20.grid(row=0,
                                column=1,
                                padx=(10, 0),
                                pady=10,
                                sticky='e')
        self.frame_linealidad_t20 = Frame(self.frame_rts)
        self.frame_linealidad_t20.grid(row=2,
                                       column=2,
                                       pady=(0, 10),
                                       columnspan=4)
        self.label_r_t20 = Label(self.frame_linealidad_t20)
        self.label_r_t20.config(text="r",
                                bg="#5893d4",
                                borderwidth=2,
                                relief="groove",
                                width=4)
        self.label_r_t20.grid(row=0, column=2, padx=10, pady=10)
        self.r_t20_var = StringVar()
        self.label_res_r_t20 = Label(self.frame_linealidad_t20)
        self.label_res_r_t20.config(relief="sunken",
                                    bg="#becbff",
                                    borderwidth=2,
                                    width=10,
                                    textvariable=self.r_t20_var,
                                    fg='black')
        self.label_res_r_t20.grid(row=0, column=3, padx=10, pady=10)
        self.label_xi_t20 = Label(self.frame_linealidad_t20)
        self.label_xi_t20.config(text="ξ",
                                 bg="#5893d4",
                                 borderwidth=2,
                                 relief="groove",
                                 width=4)
        self.label_xi_t20.grid(row=0, column=4, padx=10, pady=10)
        self.xi_t20_var = StringVar()
        self.label_res_xi_t20 = Label(self.frame_linealidad_t20)
        self.label_res_xi_t20.config(relief="sunken",
                                     bg="#becbff",
                                     borderwidth=2,
                                     width=10,
                                     fg='black',
                                     textvariable=self.xi_t20_var)

        self.label_res_xi_t20.grid(row=0, column=5, padx=10, pady=10)

    def construir_frame_t30(self):
        self.frame_t30 = Frame(self.frame_rts)
        self.frame_t30.grid(row=3, column=0, pady=(0, 10), columnspan=2)
        self.label_t30 = Label(self.frame_t30)
        self.label_t30.config(text="T30",
                              bg="#5893d4",
                              borderwidth=2,
                              relief="groove",
                              width=4)
        self.label_t30.grid(row=0, column=0, padx=(0, 10), pady=10, sticky='w')
        self.t30_var = StringVar()
        self.label_res_t30 = Label(self.frame_t30)
        self.label_res_t30.config(relief="sunken",
                                  borderwidth=2,
                                  bg="#becbff",
                                  width=10,
                                  textvariable=self.t30_var,
                                  fg='black')
        self.label_res_t30.grid(row=0,
                                column=1,
                                padx=(10, 0),
                                pady=10,
                                sticky='e')
        self.frame_linealidad_t30 = Frame(self.frame_rts)
        self.frame_linealidad_t30.grid(row=3,
                                       column=2,
                                       pady=(0, 10),
                                       columnspan=4)
        self.label_r_t30 = Label(self.frame_linealidad_t30)
        self.label_r_t30.config(text="r",
                                bg="#5893d4",
                                borderwidth=2,
                                relief="groove",
                                width=4)
        self.label_r_t30.grid(row=0, column=2, padx=10, pady=10)
        self.r_t30_var = StringVar()
        self.label_res_r_t30 = Label(self.frame_linealidad_t30)
        self.label_res_r_t30.config(relief="sunken",
                                    bg="#becbff",
                                    borderwidth=2,
                                    width=10,
                                    textvariable=self.r_t30_var,
                                    fg='black')
        self.label_res_r_t30.grid(row=0, column=3, padx=10, pady=10)
        self.label_xi_t30 = Label(self.frame_linealidad_t30)
        self.label_xi_t30.config(text="ξ",
                                 bg="#5893d4",
                                 borderwidth=2,
                                 relief="groove",
                                 width=4)
        self.label_xi_t30.grid(row=0, column=4, padx=10, pady=10)
        self.xi_t30_var = StringVar()
        self.label_res_xi_t30 = Label(self.frame_linealidad_t30)
        self.label_res_xi_t30.config(relief="sunken",
                                     bg="#becbff",
                                     borderwidth=2,
                                     width=10,
                                     fg='black',
                                     textvariable=self.xi_t30_var)
        self.label_res_xi_t30.grid(row=0, column=5, padx=10, pady=10)

    def construir_frame_curvatura(self):
        self.frame_curvatura = Frame(self.frame_rts)
        self.frame_curvatura.grid(row=4,
                                  column=2,
                                  pady=(0, 10),
                                  columnspan=4,
                                  sticky='e')
        self.label_curvatura = Label(self.frame_curvatura)
        self.label_curvatura.config(text="C",
                                    bg="#5893d4",
                                    borderwidth=2,
                                    relief="groove",
                                    width=4)
        self.label_curvatura.grid(row=0,
                                  column=0,
                                  padx=(0, 10),
                                  pady=10,
                                  sticky='w')
        self.curvatura_var = StringVar()
        self.label_res_curvatura = Label(self.frame_curvatura)
        self.label_res_curvatura.config(relief="sunken",
                                        borderwidth=2,
                                        bg="#becbff",
                                        width=10,
                                        textvariable=self.curvatura_var,
                                        fg='black')
        self.label_res_curvatura.grid(row=0, column=1, padx=10, pady=10)

    def get_frecuencia_central_banda_seleccionada(self):
        return float(self.banda_seleccionada.get())

    def get_tipo(self):
        return self.tipo

    def verificar_ponderacion_A(self):
        return self.ponderacion_A_checked.get()

    def desactivar(self):
        self.combobox_banda.config(state=DISABLED)
        self.checkbutton_ponderacion_A.config(state=DISABLED)
        self.boton_calcular.config(state=DISABLED)

    def activar(self):
        self.combobox_banda.config(state=NORMAL)
        self.checkbutton_ponderacion_A.config(state=NORMAL)
        self.boton_calcular.config(state=NORMAL)

    def graficar(self, nivel_respuesta_impulsional, curva_decaimiento):
        dominio_temporal_ri = nivel_respuesta_impulsional.get_dominio_temporal(
        )
        valores_ri = nivel_respuesta_impulsional.get_valores()
        dominio_temporal_cd = curva_decaimiento.get_dominio_temporal()
        valores_cd = curva_decaimiento.get_valores()
        self.limpiar_ejes()
        self.sistema_ejes.plot(dominio_temporal_ri,
                               valores_ri,
                               color='#0000ff',
                               linewidth=0.5,
                               label='Nivel respuesta impulsional')
        self.sistema_ejes.plot(dominio_temporal_cd,
                               valores_cd,
                               color="#ff0000",
                               linewidth=1,
                               label='Curva de decaimiento')
        self.sistema_ejes.legend()
        self.canvas.draw()

    def mostrar_tiempos_de_reverberacion(self, edt, t20, t30):
        self.edt_var.set(str(round(edt, 4)) + "seg")
        self.t20_var.set(str(round(t20, 4)) + "seg")
        self.t30_var.set(str(round(t30, 4)) + "seg")

    def mostrar_parametros_de_linealidad(self, edt, t20, t30, curvatura):
        self.r_edt_var.set(round(edt.get_coef_correlacion(), 4))
        self.xi_edt_var.set(str(round(edt.get_xi(), 4)) + "‰")
        self.r_t20_var.set(round(t20.get_coef_correlacion(), 4))
        self.xi_t20_var.set(str(round(t20.get_xi(), 4)) + "‰")
        self.r_t30_var.set(round(t30.get_coef_correlacion(), 4))
        self.xi_t30_var.set(str(round(t30.get_xi(), 4)) + "‰")
        self.curvatura_var.set(str(round(curvatura, 4)) + "%")

    def construir_frame_progressbar(self):
        self.pb_frame = Frame(self.frame_medicion)
        self.pb_frame.config(padx=20, pady=20)

        self.frame_calculando = Frame(self.pb_frame)
        self.frame_calculando.grid(row=0, column=0, pady=10)
        self.label_calculando = Label(self.frame_calculando)
        self.label_calculando.config(text="Calculando")
        self.label_calculando.pack(expand="True", fill="both")
        self.progressbar = Progressbar(self.pb_frame)
        self.progressbar.config(mode="indeterminate", length=250)
        self.progressbar.grid(row=1, column=0, pady=10)

    def activar_progressbar(self):
        self.pb_frame.grid(row=5, column=0)
        self.progressbar.start(10)

    def desactivar_progressbar(self):
        self.progressbar.stop()
        self.pb_frame.grid_remove()

    def redibujar_canvas(self):
        self.canvas.draw()
        self.canvas.get_tk_widget().pack()

    def ocultar_grafica(self):
        self.canvas.get_tk_widget().pack_forget()
示例#16
0
class PianoTutor:
    def __init__(self, root):
        self.root = root
        self.root.resizable(False, False)
        self.root.title('Piano Tutor')
        self.keys = []
        self.progression_buttons = []
        self.load_json_files()
        self.keys_to_highlight = []
        self.build_mode_selector_frame()
        self.build_score_sheet_frame()
        self.build_controls_frame()
        self.build_keyboard_frame()
        self.build_chords_frame()
        self.build_progressions_frame()
        self.build_scales_frame()
        self.find_scale()

    def load_json_files(self):
        with open(SCALES_JSON_FILE, 'r') as f:
            self.scales = json.load(f, object_pairs_hook=OrderedDict)
        with open(CHORDS_JSON_FILE, 'r') as f:
            self.chords = json.load(f, object_pairs_hook=OrderedDict)
        with open(PROGRESSIONS_JSON_FILE, 'r') as f:
            self.progressions = json.load(f, object_pairs_hook=OrderedDict)

    def on_progression_scale_changed(self, event):
        selected_progression_scale = \
            self.progression_scale_selector.get()
        progressions = [
            k for k in self.progressions[selected_progression_scale].keys()
        ]
        self.progression_selector['values'] = progressions
        self.progression_selector.current(0)
        self.show_progression_buttons()

    def on_progression_key_changed(self, event):
        self.show_progression_buttons()

    def on_progression_changed(self, event):
        self.show_progression_buttons()

    def destroy_current_progression_buttons(self):
        for buttons in self.progression_buttons:
            buttons.destroy()

    def show_progression_buttons(self):
        self.destroy_current_progression_buttons()
        selected_progression_scale = \
            self.progression_scale_selector.get()
        selected_progression = self.progression_selector.get().split('-')
        self.progression_buttons = []
        for i in range(len(selected_progression)):
            self.progression_buttons.append(
                Button(self.progressions_frame,
                       text=selected_progression[i],
                       command=partial(self.on_progression_button_clicked, i)))
            sticky = ('W' if i == 0 else 'E')
            col = (i if i > 1 else 1)
            self.progression_buttons[i].grid(column=col,
                                             row=2,
                                             sticky=sticky,
                                             padx=10)

    def on_progression_button_clicked(self, i):
        self.remove_all_key_highlights()
        selected_progression = self.progression_selector.get().split('-')[i]
        if any(x.isupper() for x in selected_progression):
            selected_chord = 'Major'
        else:
            selected_chord = 'Minor'
        key_offset = ROMAN_TO_NUMBER[selected_progression]
        selected_key = self.progression_key_selector.get()
        index_of_selected_key = (KEYS.index(selected_key) + key_offset) \
            % 12
        self.keys_to_highlight = [
            ALL_KEYS[j + index_of_selected_key]
            for j in self.chords[selected_chord]
        ]
        self.score_maker.draw_chord(self.keys_to_highlight)
        self.highlight_list_of_keys(self.keys_to_highlight)
        play_chord_in_new_thread(self.keys_to_highlight)

    def on_chord_changed(self, event):
        self.remove_all_key_highlights()
        self.find_chord(event)

    def on_chords_key_changed(self, event):
        self.remove_all_key_highlights()
        self.find_chord(event)

    def find_chord(self, event=None):
        self.selected_chord = self.chords_selector.get()
        self.chords_selected_key = self.chords_key_selector.get()
        index_of_selected_key = KEYS.index(self.chords_selected_key)
        self.keys_to_highlight = [
            ALL_KEYS[i + index_of_selected_key]
            for i in self.chords[self.selected_chord]
        ]
        self.score_maker.draw_chord(self.keys_to_highlight)
        self.highlight_list_of_keys(self.keys_to_highlight)
        play_chord_in_new_thread(self.keys_to_highlight)

    def on_scale_changed(self, event):
        self.remove_all_key_highlights()
        self.find_scale(event)

    def on_scale_key_changed(self, event):
        self.remove_all_key_highlights()
        self.find_scale(event)

    def find_scale(self, event=None):
        self.selected_scale = self.scale_selector.get()
        self.scale_selected_key = self.scale_key_selector.get()
        index_of_selected_key = KEYS.index(self.scale_selected_key)
        self.keys_to_highlight = [
            ALL_KEYS[i + index_of_selected_key]
            for i in self.scales[self.selected_scale]
        ]
        self.score_maker.draw_notes(self.keys_to_highlight)
        self.highlight_list_of_keys(self.keys_to_highlight)
        play_scale_in_new_thread(self.keys_to_highlight)

    def highlight_list_of_keys(self, key_names):
        for key in key_names:
            self.highlight_key(key)

    def highlight_key(self, key_name):
        if len(key_name) == 2:
            img = WHITE_KEY_PRESSED_IMAGE
        elif len(key_name) == 3:
            img = BLACK_KEY_PRESSED_IMAGE
        key_img = PhotoImage(file=img)
        for widget in self.keys:
            if widget.name == key_name:
                widget.configure(image=key_img)
                widget.image = key_img

    def remove_key_highlight(self, key_name):
        if len(key_name) == 2:
            img = WHITE_KEY_IMAGE
        elif len(key_name) == 3:
            img = BLACK_KEY_IMAGE
        key_img = PhotoImage(file=img)
        for widget in self.keys:
            if widget.name == key_name:
                widget.configure(image=key_img)
                widget.image = key_img

    def remove_all_key_highlights(self):
        for key in self.keys_to_highlight:
            self.remove_key_highlight(key)
        self.keys_to_highlight = []

    def build_mode_selector_frame(self):
        self.mode_selector_frame = Frame(self.root,
                                         width=WINDOW_WIDTH,
                                         height=MODE_SELECTOR_HEIGHT)
        self.mode_selector_frame.grid_propagate(False)
        self.mode_selector = ttk.Combobox(self.mode_selector_frame,
                                          values=CHOICES)
        self.mode_selector.bind('<<ComboboxSelected>>', self.on_mode_changed)
        self.mode_selector.current(0)
        self.mode_selector.grid(row=0,
                                column=1,
                                columnspan=3,
                                padx=10,
                                pady=10,
                                sticky='nsew')
        self.mode_selector_frame.grid(row=0, column=0)

    def build_score_sheet_frame(self):
        self.score_sheet_frame = Frame(self.root,
                                       width=WINDOW_WIDTH,
                                       height=SCORE_DISPLAY_HEIGHT)
        self.score_sheet_frame.grid_propagate(False)
        self.score_sheet_frame.grid(row=1, column=0)
        self.score_maker = ScoreMaker(self.score_sheet_frame)

    def build_controls_frame(self):
        self.controls_frame = Frame(self.root,
                                    width=WINDOW_WIDTH,
                                    height=CONTROLS_FRAME_HEIGHT)
        self.controls_frame.grid_propagate(False)
        self.controls_frame.grid(row=2, column=0)

    def build_keyboard_frame(self):
        self.keyboard_frame = Frame(self.root,
                                    width=WINDOW_WIDTH,
                                    height=KEYBOARD_HEIGHT,
                                    background='LavenderBlush2')
        self.keyboard_frame.grid_propagate(False)
        self.keyboard_frame.grid(row=4, column=0, sticky='nsew')
        for (index, key) in enumerate(WHITE_KEY_NAMES):
            x = WHITE_KEY_X_COORDINATES[index]
            self.create_key(WHITE_KEY_IMAGE, key, x)
        for (index, key) in enumerate(BLACK_KEY_NAMES):
            x = BLACK_KEY_X_COORDINATES[index]
            self.create_key(BLACK_KEY_IMAGE, key, x)

    def build_scales_frame(self):
        self.scales_frame = Frame(self.controls_frame,
                                  width=WINDOW_WIDTH,
                                  height=CONTROLS_FRAME_HEIGHT)
        self.scales_frame.grid(row=1, column=0, sticky='nsew')
        Label(self.scales_frame, text='Select scale').grid(row=0,
                                                           column=1,
                                                           sticky='w',
                                                           padx=10,
                                                           pady=1)
        self.scale_selector = ttk.Combobox(
            self.scales_frame, values=[k for k in self.scales.keys()])
        self.scale_selector.current(0)
        self.scale_selector.bind('<<ComboboxSelected>>', self.on_scale_changed)
        self.scale_selector.grid(row=1, column=1, sticky='e', padx=10, pady=10)
        Label(self.scales_frame, text='in the key of').grid(row=0,
                                                            column=2,
                                                            sticky='w',
                                                            padx=10,
                                                            pady=1)
        self.scale_key_selector = ttk.Combobox(self.scales_frame,
                                               values=[k for k in KEYS])
        self.scale_key_selector.current(0)
        self.scale_key_selector.bind('<<ComboboxSelected>>',
                                     self.on_scale_key_changed)
        self.scale_key_selector.grid(row=1,
                                     column=2,
                                     sticky='e',
                                     padx=10,
                                     pady=10)

    def build_chords_frame(self):
        self.chords_frame = Frame(self.controls_frame,
                                  width=WINDOW_WIDTH,
                                  height=CONTROLS_FRAME_HEIGHT)
        self.chords_frame.grid_propagate(False)
        self.chords_frame.grid(row=1, column=0, sticky='nsew')
        Label(self.chords_frame, text='Select Chord').grid(row=0,
                                                           column=1,
                                                           sticky='w',
                                                           padx=10,
                                                           pady=1)
        self.chords_selector = ttk.Combobox(
            self.chords_frame, values=[k for k in self.chords.keys()])
        self.chords_selector.current(0)
        self.chords_selector.bind('<<ComboboxSelected>>',
                                  self.on_chord_changed)
        self.chords_selector.grid(row=1,
                                  column=1,
                                  sticky='e',
                                  padx=10,
                                  pady=10)
        Label(self.chords_frame, text='in the key of').grid(row=0,
                                                            column=2,
                                                            sticky='w',
                                                            padx=10,
                                                            pady=1)
        self.chords_key_selector = ttk.Combobox(self.chords_frame,
                                                values=[k for k in KEYS])
        self.chords_key_selector.current(0)
        self.chords_key_selector.bind('<<ComboboxSelected>>',
                                      self.on_chords_key_changed)
        self.chords_key_selector.grid(row=1,
                                      column=2,
                                      sticky='e',
                                      padx=10,
                                      pady=10)

    def build_progressions_frame(self):
        self.progressions_frame = Frame(self.controls_frame,
                                        width=WINDOW_WIDTH,
                                        height=CONTROLS_FRAME_HEIGHT)
        self.progressions_frame.grid_propagate(False)
        self.progressions_frame.grid(row=1, column=0, sticky='nsew')
        Label(self.progressions_frame, text='Select Scale').grid(row=0,
                                                                 column=1,
                                                                 sticky='w',
                                                                 padx=10,
                                                                 pady=1)
        Label(self.progressions_frame,
              text='Select Progression').grid(row=0,
                                              column=2,
                                              sticky='w',
                                              padx=10,
                                              pady=1)
        Label(self.progressions_frame, text='in the Key of').grid(row=0,
                                                                  column=3,
                                                                  sticky='w',
                                                                  padx=10,
                                                                  pady=1)

        self.progression_scale_selector = \
            ttk.Combobox(self.progressions_frame, values=[k for k in
                         self.progressions.keys()], width=18)
        self.progression_scale_selector.bind('<<ComboboxSelected>>',
                                             self.on_progression_scale_changed)
        self.progression_scale_selector.current(0)
        self.progression_scale_selector.grid(row=1,
                                             column=1,
                                             sticky='w',
                                             padx=10,
                                             pady=10)

        self.progression_selector = \
            ttk.Combobox(self.progressions_frame, values=[k for k in
                         self.progressions['Major'].keys()], width=18)
        self.progression_selector.bind('<<ComboboxSelected>>',
                                       self.on_progression_changed)
        self.progression_selector.current(0)
        self.progression_selector.grid(row=1,
                                       column=2,
                                       sticky='w',
                                       padx=10,
                                       pady=10)

        self.progression_key_selector = \
            ttk.Combobox(self.progressions_frame, values=KEYS, width=18)
        self.progression_key_selector.current(0)
        self.progression_key_selector.bind('<<ComboboxSelected>>',
                                           self.on_progression_key_changed)
        self.progression_key_selector.grid(row=1,
                                           column=3,
                                           sticky='w',
                                           padx=10,
                                           pady=10)

    def on_mode_changed(self, event):
        self.remove_all_key_highlights()
        selected_mode = self.mode_selector.get()
        if selected_mode == 'Scales':
            self.show_scales_frame()
            self.find_scale()
        elif selected_mode == 'Chords':
            self.show_chords_frame()
            self.find_chord()
        elif selected_mode == 'Chord Progressions':
            self.show_progressions_frame()
            self.show_progression_buttons()

    def show_scales_frame(self):
        self.chords_frame.grid_remove()
        self.progressions_frame.grid_remove()
        self.scales_frame.grid()

    def show_chords_frame(self):
        self.chords_frame.grid()
        self.progressions_frame.grid_remove()
        self.scales_frame.grid_remove()

    def show_progressions_frame(self):
        self.chords_frame.grid_remove()
        self.progressions_frame.grid()
        self.scales_frame.grid_remove()

    def create_key(self, img, key_name, x_coordinate):
        key_image = PhotoImage(file=img)
        label = Label(self.keyboard_frame, image=key_image, border=0)
        label.image = key_image
        label.place(x=x_coordinate, y=0)
        label.name = key_name
        label.bind('<Button-1>', self.on_key_pressed)
        label.bind('<ButtonRelease-1>', self.on_key_released)
        self.keys.append(label)
        return label

    def change_image_to_pressed(self, event):
        if len(event.widget.name) == 2:
            img = WHITE_KEY_PRESSED_IMAGE
        elif len(event.widget.name) == 3:
            img = BLACK_KEY_PRESSED_IMAGE
        key_img = PhotoImage(file=img)
        event.widget.configure(image=key_img)
        event.widget.image = key_img

    def change_image_to_unpressed(self, event):
        if len(event.widget.name) == 2:
            img = WHITE_KEY_IMAGE
        elif len(event.widget.name) == 3:
            img = BLACK_KEY_IMAGE
        key_img = PhotoImage(file=img)
        event.widget.configure(image=key_img)
        event.widget.image = key_img

    def on_key_pressed(self, event):
        play_note(event.widget.name)
        self.change_image_to_pressed(event)

    def on_key_released(self, event):
        self.change_image_to_unpressed(event)
示例#17
0
class fen_info(Tk):
    """ Fenêtre permettant de saisir les informations sur les joueurs
    """

    def __init__(self):

        super().__init__()
        # Initialisation des pions à la valeur initiale.
        self.pion1 = "X"
        self.pion2 = "O"

        # Titre de la fenêtre
        self.title("Ultimate TIC-TAC-TOE")

        # Pour changer taille minimum de fenêtre et taille centrer,
        # changer variable self.width_fen, self.height_fen.
        self.width_fen, self.height_fen = 430, 500

        # Taille minimum de la fenêtre
        self.minsize(self.width_fen, self.height_fen)

        # Centrer la fenêtre.
        centreFen(self, self.width_fen, self.height_fen)

        # Création d'un canvas avec l'image "logo.gif"
        canvas = Canvas(self, width=280, height=100)
        self.img = PhotoImage(file="logo.gif")
        canvas.create_image(280, 100, anchor=SE, image=self.img)
        canvas.grid(row=0, columnspan=5, pady=10)

        # Libellé - Nouvelle Partie
        Label(self, text="Nouvelle partie", font=("Arial", 16), fg="#0080FF", justify=CENTER).grid(
            row=1, columnspan=5, padx = 20, pady = 5)
        separateur(20).grid(row=10,columnspan=5)

        # Sélection du type de partie avec bouton radio
        self.choixJoueur = IntVar()
        r1 = Radiobutton(self, text="Jouer avec l'ordinateur",
                         variable = self.choixJoueur, value = 1, command=self.define_choix)
        r1.select()
        r1.grid(row=20, column=0)
        r2 = Radiobutton(self, text="Jouer avec un autre joueur",
                         variable = self.choixJoueur, value = 2, command=self.define_choix)
        r2.grid(row=20, column=1)

        # Saisie du nom du joueur 1.
        f_j1 = Frame(self, borderwidth=1, padx=5, pady=5, relief=SUNKEN)
        f_j1.grid(row=30, columnspan=5, padx=5, pady=5)
        Label(f_j1, text="Nom joueur 1:").grid(row=1, column=0, sticky=E, padx = 5, pady = 5)
        self.nom_joueur1 = Entry(f_j1)
        self.nom_joueur1.grid(row=1,column=1)

        # Sélection du pion joueur 1. Le pion restant est automatiquement attribué au joueur 2.

        Label(f_j1, text="Choix de pion:").grid(row=1, column=2, padx=5)
        self.sel_pion=IntVar()
        p1 = Radiobutton(f_j1, indicatoron=0, width=5, text="X",
                         variable=self.sel_pion, value=1, command=self.choix_pion)
        p1.grid(row=1, column=3, padx=2)
        p1.select()
        Radiobutton(f_j1, indicatoron=0, width=5, text="O", variable=self.sel_pion, value=2,
                    command=self.choix_pion).grid(row=1, column=4, padx=2)

        # Saisie du nom du joueur 2. Apparaît seulement si on sélection 2 joueurs. Voir define_choix
        self.f_j2 = Frame(self, width=420, borderwidth=1, padx=5, pady=5, relief=SUNKEN)
        Label(self.f_j2, text="Nom joueur 2").grid(row=1, column=0, sticky=E, padx = 5, pady = 5)
        self.nom_joueur2 = Entry(self.f_j2, state="disabled")
        self.nom_joueur2.grid(row=1, column=1)
        self.label_pion2 = Label(self.f_j2, text="Pion Joueur 2 = O")
        self.label_pion2.grid(row=1, column=2, padx=5)

        # Information sur l'ordinateur. Disparaît si on choisi 2 joueurs.
        self.f_ordi = Frame(self, width=420, borderwidth=1, padx=5, pady=5, relief=SUNKEN)
        self.f_ordi.grid(row=40, columnspan=5, padx=5, pady=5)
        Label(self.f_ordi, text="Ordinateur = Colosse", font=("Arial", 12), fg="#0080FF")\
            .grid(row=1, column=0, sticky=E, padx = 5, pady = 5)
        self.pion_ordi = Label(self.f_ordi, text="| Pion de l'ordinateur = O",
                               font=("Arial", 12), fg="#0080FF")
        self.pion_ordi.grid(row=1, column=2)
        separateur(20).grid(row=50,columnspan=5)

        # Sélection de la force de l'ordinateur
        self.choixForce = IntVar()
        self.f1 = Radiobutton(self, indicatoron=0, width = 20,
                         padx = 20, text="Facile", variable=self.choixForce, value=1, command=self.define_choix)
        self.f1.select()
        self.f1.grid(row=60, columnspan=5)
        self.f2 = Radiobutton(self, indicatoron=0, width = 20,
                         padx = 20, text="Moyen", variable=self.choixForce, value=2, command=self.define_choix)
        self.f2.grid(row=61, columnspan=5)
        self.f3 = Radiobutton(self, indicatoron=0, width = 20,
                         padx = 20, text="Difficile", variable=self.choixForce, value=3, command=self.define_choix)
        self.f3.grid(row=62, columnspan=5)
        separateur(40).grid(row=70, column=0)

        #Button pour démarrer la partie
        self.bt_start = Button(text="Démarrer", font=("Arial", 12), fg="green", command=self.demarrer_jeu)
        self.bt_start.grid(row=80, columnspan=5)

    def define_choix(self):

        """
            Fonction qui active ou désactive le nom du joueur 2 selon si on joue contre l'ordinateur ou contre
            un autre joueur
        """

        if self.choixJoueur.get()==1:
            self.nom_joueur2.delete(0, END)
            self.nom_joueur2["state"]="disabled"
            self.f1["state"]="normal"
            self.f2["state"]="normal"
            self.f3["state"]="normal"
            self.f_j2.grid_remove()
            self.f_ordi.grid(row=40, columnspan=5, padx=5, pady=5)

        elif self.choixJoueur.get()==2:
            self.nom_joueur2["state"]="normal"
            self.f1["state"]="disabled"
            self.f2["state"]="disabled"
            self.f3["state"]="disabled"
            self.f_j2.grid(row=40, columnspan=5, padx=5, pady=5)
            self.f_ordi.grid_remove()

    def choix_pion(self):
        # Définition des pions

        if self.sel_pion.get()==1:
            self.pion1="X"
            self.pion2="O"
            self.label_pion2["text"]="Pion Joueur 2 = {}".format(self.pion2)
            self.pion_ordi["text"]="| Pion de l'ordinateur = {}".format(self.pion2)
        else:
            self.pion1="O"
            self.pion2="X"
            self.label_pion2["text"]="Pion Joueur 2 = {}".format(self.pion2)
            self.pion_ordi["text"]="| Pion de l'ordinateur = {}".format(self.pion2)

    def demarrer_jeu(self):
        """
        Démarrer la partie avec les informations saisie. Afficher le plateau
        """
        if self.choixJoueur.get()==1:
            type2 = "Ordinateur"
            if self.nom_joueur1.get()!='':
                j1 = self.nom_joueur1.get()
                j2 = "Colosse"
            else:
                j1 = "Joueur 1"
                j2 = "Colosse"
        elif self.choixJoueur.get()==2:
            type2 = "Personne"
            if self.nom_joueur1.get()!='' and self.nom_joueur2.get()!='':
                j1 = self.nom_joueur1.get()
                j2 = self.nom_joueur2.get()
            elif self.nom_joueur1.get()=='':
                j1 = "Joueur 1"
                if self.nom_joueur2.get()=='':
                    j2 = "Joueur 2"
                else:
                    j2 = self.nom_joueur2.get()
            else:
                j1 = self.nom_joueur1.get()
                if self.nom_joueur2.get()=='':
                    j2 = "Joueur 2"
                else:
                    j2 = self.nom_joueur2.get()

        p1 = self.pion1
        p2 = self.pion2
        force = self.choixForce.get()
        self.destroy()
        ma_fenetre = Fenetre(j1, j2, type2, p1, p2, force)
        ma_fenetre.mainloop()
示例#18
0
class GUI(Tk):
    'Graphic user interface using Tkinter, main / root window'

    def __init__(self, root, worker):
        'Generate object for main / root window.'
        self.root = root
        self.worker = worker
        ### "constants" for the gui ###
        if self.worker.storage.windows:
            self.JOBLISTLENGTH = 10
            self.BUTTONWIDTH = 16
            self.BIGENTRYWIDTH = 128
            self.INTWIDTH = 6
            self.TARGETWIDTH = 160
            self.PADX = 8
            self.PADY = 8
            self.OPTPADX = 6
            self.CHNGWIDTH = 144
            self.CHNGHEIGHT = 12
            self.MSGHEIGHT = 8
        else:
            self.JOBLISTLENGTH = 10
            self.BUTTONWIDTH = 16
            self.BIGENTRYWIDTH = 96
            self.INTWIDTH = 6
            self.TARGETWIDTH = 120
            self.PADX = 8
            self.PADY = 8
            self.OPTPADX = 6
            self.CHNGWIDTH = 128
            self.CHNGHEIGHT = 14
            self.MSGHEIGHT = 8
        ###############################
        self.__close2quit__()  # handle closing of root window
        self.jobs = []  # start with empty list for the jobs
        self.root.title('Social Media Downloader')  # window title for somedo
        self.__set_icon__(
            self.root)  # give the window manager an application icon
        frame_jobs = LabelFrame(
            self.root, text=' \u25a4 Jobs '
        )  # in this tk-frame the jobs will be displayed
        frame_jobs.pack(fill=X, expand=True, padx=self.PADX, pady=self.PADY)
        frame_jobs_inner = Frame(frame_jobs)
        frame_jobs_inner.pack(fill=X,
                              expand=True,
                              padx=self.PADX,
                              pady=self.PADY)
        self.tk_jobbuttons = []
        self.jobbuttons = []
        self.upbuttons = []
        self.downbuttons = []
        for i in range(self.JOBLISTLENGTH):
            frame_row = Frame(frame_jobs_inner)
            frame_row.pack(fill=X, expand=True)
            self.tk_jobbuttons.append(StringVar(frame_row))
            self.jobbuttons.append(
                Button(frame_row,
                       textvariable=self.tk_jobbuttons[i],
                       anchor=W,
                       command=partial(self.__job_edit__, i)))
            self.jobbuttons[i].pack(side=LEFT, fill=X, expand=True)
            self.upbuttons.append(
                Button(frame_row,
                       text='\u2191',
                       command=partial(self.__job_up__, i)))
            self.upbuttons[i].pack(side=LEFT)
            self.downbuttons.append(
                Button(frame_row,
                       text='\u2193',
                       command=partial(self.__job_down__, i)))
            self.downbuttons[i].pack(side=LEFT)
        self.colour_fg = self.jobbuttons[0].cget('fg')
        self.colour_bg = self.jobbuttons[0].cget('bg')
        frame_row = Frame(frame_jobs_inner)
        frame_row.pack(fill=BOTH, expand=True)
        self.startbutton = Button(frame_row,
                                  text="\u25b9 Start jobs",
                                  width=self.BUTTONWIDTH,
                                  command=self.__start__)
        self.startbutton.pack(side=LEFT, pady=self.PADY)
        Label(frame_row, text=' ').pack(side=LEFT)
        self.stopbutton = Button(frame_row,
                                 text="\u25ad Stop / Abort",
                                 width=self.BUTTONWIDTH,
                                 state=DISABLED,
                                 command=self.__stop__)
        self.stopbutton.pack(side=LEFT, padx=self.PADX, pady=self.PADY)
        self.purgebutton = Button(frame_row,
                                  text='\u2672 Purge job list',
                                  width=self.BUTTONWIDTH,
                                  command=self.__purge_jobs__)
        self.purgebutton.pack(side=RIGHT, pady=self.PADY)
        frame_row = LabelFrame(self.root, text=' + Add Job ')  # add job frame
        frame_row.pack(fill=X, expand=True, padx=self.PADX, pady=self.PADY)
        self.modulebuttons = dict()
        for i in self.worker.modulenames:  # generate buttons for the modules
            self.modulebuttons[i] = Button(frame_row,
                                           text='\u271a %s' % i,
                                           font='bold',
                                           height=3,
                                           command=partial(
                                               self.__new_job__, i))
            self.modulebuttons[i].pack(side=LEFT,
                                       fill=BOTH,
                                       expand=True,
                                       padx=self.PADX,
                                       pady=self.PADY)
        self.frame_changeling = LabelFrame(
            self.root)  # frame for configuration or messages
        self.frame_changeling.pack(fill=X,
                                   expand=True,
                                   padx=self.PADX,
                                   pady=self.PADY)
        self.frame_messages = Frame(self.frame_changeling)  # message frame
        self.text_messages = scrolledtext.ScrolledText(self.frame_messages,
                                                       padx=self.PADX,
                                                       pady=self.PADY,
                                                       height=self.MSGHEIGHT)
        self.text_messages.pack(fill=BOTH,
                                expand=True,
                                padx=self.PADX,
                                pady=self.PADY)
        self.text_messages.bind("<Key>", lambda e: "break")
        self.worker.logger.addHandler(GUILogHandler(
            self.text_messages))  # give tk loghandler to worker
        self.frame_config = Frame(self.frame_changeling)  # config frame
        nb_config = ttk.Notebook(
            self.frame_config)  # here is the tk-notebook for the modules
        nb_config.pack(padx=self.PADX, pady=self.PADY)
        frame_nb = ttk.Frame(nb_config)
        nb_config.add(frame_nb, text='General')
        frame_row = Frame(frame_nb)
        frame_row.pack(fill=BOTH, expand=True)
        Label(frame_row,
              text='Output directory:',
              anchor=E,
              width=self.BUTTONWIDTH).pack(side=LEFT, padx=self.PADX)
        self.tk_outdir = StringVar(frame_row, self.worker.storage.outdir)
        self.tk_outdir_entry = Entry(frame_row,
                                     textvariable=self.tk_outdir,
                                     width=self.BIGENTRYWIDTH)
        self.tk_outdir_entry.pack(side=LEFT)
        Button(frame_row, text='...',
               command=self.__output_dir__).pack(side=LEFT,
                                                 padx=self.PADX,
                                                 pady=self.PADY)
        frame_row = Frame(frame_nb)
        frame_row.pack(fill=BOTH, expand=True)
        Label(frame_row, text='Chrome path:', anchor=E,
              width=self.BUTTONWIDTH).pack(side=LEFT,
                                           padx=self.PADX,
                                           pady=self.PADY)
        self.tk_chrome = StringVar(frame_row, self.worker.chrome.path)
        self.tk_chrome_entry = Entry(frame_row,
                                     textvariable=self.tk_chrome,
                                     width=self.BIGENTRYWIDTH)
        self.tk_chrome_entry.pack(side=LEFT)
        Button(frame_row, text='...',
               command=self.__chrome__).pack(side=LEFT, padx=self.PADX)
        self.tk_logins = dict()  # login credentials
        self.tk_login_entries = dict()
        for i in self.worker.MODULES:  # notebook tabs for the module configuration
            if i['login'] != None:
                frame_nb = ttk.Frame(nb_config)
                nb_config.add(frame_nb, text=i['name'])
                self.tk_logins[i['name']], self.tk_login_entries[
                    i['name']] = self.__login_frame__(
                        frame_nb, i['name'], self.worker.logins[i['name']])
        frame_row = Frame(self.frame_config)
        frame_row.pack(side=LEFT, anchor=N)
        Button(frame_row,
               text="\u2912 Save configuration",
               width=self.BUTTONWIDTH,
               command=self.__save_config__).pack(side=LEFT,
                                                  padx=self.PADX,
                                                  pady=self.PADY)
        Button(frame_row,
               text="\u2913 Load configuration",
               width=self.BUTTONWIDTH,
               command=self.__load_config__).pack(side=LEFT,
                                                  padx=self.PADX,
                                                  pady=self.PADY)
        Label(self.frame_changeling, width=self.CHNGWIDTH).grid(row=1,
                                                                column=0)
        Label(self.frame_changeling, height=self.CHNGHEIGHT).grid(row=0,
                                                                  column=1)
        frame_row = LabelFrame(self.root, text=' \u2191\u2193 ')
        frame_row.pack(fill=X, expand=True, padx=self.PADX, pady=self.PADY)
        self.button_toggle = Button(frame_row,
                                    command=self.__toggle_config__,
                                    width=self.BUTTONWIDTH)
        self.button_toggle.pack(side=LEFT, padx=self.PADX, pady=self.PADY)
        self.button_clear = Button(frame_row,
                                   text='\u2610 Clear messages',
                                   command=self.__clear_messages__,
                                   width=self.BUTTONWIDTH)
        self.button_clear.pack(side=LEFT, padx=self.PADX, pady=self.PADY)
        self.__enable_config__()
        frame_row = Frame(self.root)
        frame_row.pack(fill=X, expand=True)
        for i in ('README.md', 'README.txt', 'README.md.txt', 'README'):
            try:
                with open(self.worker.storage.rootdir +
                          self.worker.storage.slash + i,
                          'r',
                          encoding='utf-8') as f:
                    self.about_help = f.read()
                    Button(frame_row,
                           text="\u2370 About / Help",
                           width=self.BUTTONWIDTH,
                           command=self.__help__).pack(side=LEFT,
                                                       padx=self.PADX,
                                                       pady=self.PADY)
                    break
            except:
                continue
        self.quitbutton = Button(frame_row,
                                 text="\u2297 Quit",
                                 width=self.BUTTONWIDTH,
                                 command=self.__quit__)
        self.quitbutton.pack(side=RIGHT, padx=self.PADX, pady=self.PADY)

    def __set_icon__(self, master):
        'Try to Somedo icon for the window'
        try:
            master.call(
                'wm', 'iconphoto', master._w,
                PhotoImage(
                    file='%s%ssomedo.png' %
                    (self.worker.storage.icondir, self.worker.storage.slash)))
        except:
            pass

    def __quit__(self):
        'Close the app'
        if messagebox.askyesno('Quit', 'Close this Application?'):
            self.__terminate__()

    def __close2quit__(self):
        'Ask to quit on close windows by "X"'
        self.root.protocol("WM_DELETE_WINDOW", self.__quit__)

    def __close2stop__(self):
        'Ask to stop job(s) on close windows by "X"'
        self.root.protocol("WM_DELETE_WINDOW", self.__stop__)

    def __close2kill__(self):
        'Ask to kill Somedo immediatly on close windows by "X"'
        self.root.protocol("WM_DELETE_WINDOW", self.__kill__)

    def __login_frame__(self, frame, module, login):
        'Create Tk Frame for login credentials'
        tk_login = dict()
        tk_login_entry = dict()
        for i in login:
            frame_row = Frame(frame)
            frame_row.pack(fill=BOTH, expand=True)
            Label(frame_row,
                  text=i,
                  anchor=E,
                  padx=self.PADX,
                  width=self.BUTTONWIDTH).pack(side=LEFT)
            tk_login[i] = StringVar(frame_row)
            if self.worker.logins[module] != None:
                tk_login[i].set(login[i])
            tk_login_entry[i] = Entry(frame_row,
                                      textvariable=tk_login[i],
                                      show='*',
                                      width=self.BIGENTRYWIDTH)
            tk_login_entry[i].pack(side=LEFT)
            tk_hide = BooleanVar(frame_row, True)
            Checkbutton(frame_row,
                        text='hide',
                        variable=tk_hide,
                        command=partial(self.__hide_entry__, tk_login_entry[i],
                                        tk_hide)).pack(side=LEFT)
        return tk_login, tk_login_entry

    def __hide_entry__(self, entry, check):
        'Toggle hidden login credentials'
        if check.get():
            entry.config(show='*')
        else:
            entry.config(show='')

    def __job_dialog__(self, job, row):
        'Open window to edit a job'
        self.__disable_jobbuttons__()
        self.job_dialog_root.title(job['module'])
        frame_row = LabelFrame(self.job_dialog_root, text=' \u229a Target(s) ')
        frame_row.pack(fill=BOTH, expand=True, padx=self.PADX, pady=self.PADY)
        tk_job = {
            'module': job['module'],
            'target': StringVar(frame_row, job['target'])
        }  # tk variables for the job configuration
        tk_target_entry = Entry(frame_row,
                                textvariable=tk_job['target'],
                                width=self.TARGETWIDTH)
        tk_target_entry.pack(side=LEFT, padx=self.PADX, pady=self.PADY)
        tk_job['options'] = dict()  # tk variables for the options
        if job['options'] != None:
            frame_grid = LabelFrame(self.job_dialog_root,
                                    text=' \u2714 Options ')
            frame_grid.pack(fill=BOTH,
                            expand=True,
                            padx=self.PADX,
                            pady=self.PADY)
            for i in self.worker.options[job['module']]:
                definition = self.worker.options[job['module']][i]
                value = job['options'][i]
                Label(frame_grid, text=definition['name']).grid(
                    row=definition['row'],
                    column=definition['column'] * 2,
                    sticky=E,
                    pady=self.PADY)
                if isinstance(value, bool):  # checkbutton for boolean
                    tk_job['options'][i] = BooleanVar(frame_grid, value)
                    Checkbutton(frame_grid,
                                variable=tk_job['options'][i]).grid(
                                    row=definition['row'],
                                    column=definition['column'] * 2 + 1,
                                    sticky=W)
                    width = 0
                elif isinstance(value, int):  # integer
                    tk_job['options'][i] = IntVar(frame_grid, value)
                    width = self.INTWIDTH
                elif isinstance(value, str):  # string
                    tk_job['options'][i] = StringVar(frame_grid, value)
                    width = self.BUTTONWIDTH
                if width != 0:
                    Entry(frame_grid,
                          textvariable=tk_job['options'][i],
                          width=width).grid(row=definition['row'],
                                            column=definition['column'] * 2 +
                                            1,
                                            sticky=W,
                                            padx=self.OPTPADX)
        if job['login'] != None:
            frame_login = LabelFrame(self.job_dialog_root,
                                     text=' \u2737 Login')
            frame_login.pack(fill=BOTH,
                             expand=True,
                             padx=self.PADX,
                             pady=self.PADY)
            tk_job['login'], dummy = self.__login_frame__(
                frame_login, job['module'], job['login'])
        frame_row = Frame(self.job_dialog_root)
        frame_row.pack(fill=BOTH, expand=True)
        if row == len(self.jobs):
            Button(frame_row,
                   text="Add job",
                   width=self.BUTTONWIDTH,
                   command=partial(self.__add_job__,
                                   tk_job)).pack(side=LEFT,
                                                 padx=self.PADX,
                                                 pady=self.PADY)
        else:
            Button(frame_row,
                   text="Update job",
                   width=self.BUTTONWIDTH,
                   command=partial(self.__update_job__, tk_job,
                                   row)).pack(side=LEFT,
                                              padx=self.PADX,
                                              pady=self.PADY)
            Button(frame_row,
                   text="Remove job",
                   width=self.BUTTONWIDTH,
                   command=partial(self.__remove_job__,
                                   row)).pack(side=LEFT,
                                              padx=self.PADX,
                                              pady=self.PADY)
        Button(frame_row,
               text="Quit, do nothing",
               width=self.BUTTONWIDTH,
               command=self.__quit_job_dialog__).pack(side=RIGHT,
                                                      padx=self.PADX,
                                                      pady=self.PADY)

    def __quit_job_dialog__(self):
        'Close the job configuration window'
        self.job_dialog_root.destroy()
        self.__enable_jobbuttons__()

    def __get_login__(self, module):
        'Get login credentials for a module from root window'
        if self.worker.logins[module] == None:
            return None
        return {
            i: self.tk_logins[module][i].get()
            for i in self.worker.logins[module]
        }

    def __new_job__(self, module):
        'Create new job to add to job list'
        if len(self.jobs
               ) == self.JOBLISTLENGTH - 1:  # check if free space in job list
            return
        job = self.worker.new_job(module)
        if self.worker.logins[module] != None:
            job['login'] = self.__get_login__(module)
        self.job_dialog_root = Tk()
        self.__job_dialog__(job, len(self.jobs))

    def __job_edit__(self, row):
        'Edit or remove jobin job list'
        if row >= len(self.jobs):
            return
        self.job_dialog_root = Tk()
        self.__job_dialog__(self.jobs[row], row)

    def __tk2job__(self, tk_job):
        'Get Tk values for a job'
        job = {
            'module': tk_job['module'],
            'target': tk_job['target'].get(),
            'options':
            {i: tk_job['options'][i].get()
             for i in tk_job['options']}
        }
        try:
            job['login'] = {
                i: tk_job['login'][i].get()
                for i in tk_job['login']
            }
        except:
            job['login'] = None
        return job

    def __add_job__(self, tk_job):
        'Add job to list'
        if tk_job['target'].get() == '':  # no target, no job
            return
        self.job_dialog_root.destroy()
        self.__enable_jobbuttons__()
        self.jobs.append(self.__tk2job__(tk_job))
        self.__update_joblist__()

    def __update_job__(self, tk_job, row):
        'Update job in list'
        if tk_job['target'].get() == '':  # no target, no job
            return
        self.job_dialog_root.destroy()
        self.__enable_jobbuttons__()
        self.jobs[row] = self.__tk2job__(tk_job)
        self.__update_joblist__()

    def __purge_jobs__(self):
        'Purge job list'
        if len(self.jobs) < 1:
            return
        if messagebox.askyesno('Purge job list',
                               'Are you sure to remove all jobs fromk list?'):
            self.jobs = []
            self.__update_joblist__()

    def __job_text__(self, row):
        'Generate string for one job button'
        if row >= len(self.jobs):
            return ''
        return '%s - %s' % (self.jobs[row]['module'], self.jobs[row]['target'])

    def __update_joblist__(self):
        'Update the list of jobs'
        for i in range(self.JOBLISTLENGTH):
            self.tk_jobbuttons[i].set(self.__job_text__(i))

    def __job_up__(self, row):
        'Move job up in list'
        if row > 0:
            self.jobs[row], self.jobs[row - 1] = self.jobs[row -
                                                           1], self.jobs[row]
            self.__update_joblist__()

    def __job_down__(self, row):
        'Move job down in list'
        if row < (len(self.jobs) - 1):
            self.jobs[row], self.jobs[row + 1] = self.jobs[row +
                                                           1], self.jobs[row]
            self.__update_joblist__()

    def __remove_job__(self, row):
        'Remove job from list'
        if messagebox.askyesno('Remove job', 'Are you sure?'):
            self.job_dialog_root.destroy()
            self.__enable_jobbuttons__()
            self.jobs.pop(row)
            self.__update_joblist__()

    def __output_dir__(self):
        'Set path to output directory.'
        path = filedialog.askdirectory(initialdir="~/",
                                       title='Destination directory')
        if path != ():
            self.tk_outdir_entry.delete(0, END)
            self.tk_outdir_entry.insert(0, path)
            self.worker.storage.outdir = path

    def __chrome__(self):
        'Set path to chrome.'
        path = filedialog.askopenfilename(title='chrome',
                                          filetypes=[('All files', '*.*')])
        if path != () and path != '':
            self.tk_chrome_entry.delete(0, END)
            self.tk_chrome_entry.insert(0, path)
            self.worker.chrome.path = path

    def __save_config__(self):
        'Save configuration to file.'
        path = filedialog.asksaveasfilename(title='Configuration file',
                                            filetypes=[
                                                ('Somedo configuration files',
                                                 '*.smdc')
                                            ])
        if path[-5:] != '.smdc':
            path += '.smdc'
        try:
            self.worker.storage.json_dump(
                {
                    'Output': self.tk_outdir.get(),
                    'Chrome': self.tk_chrome.get(),
                    'Modules': {
                        i: self.__get_login__(i)
                        for i in self.worker.modulenames
                        if self.worker.logins[i] != None
                    }
                }, path)
        except:
            messagebox.showerror('Error', 'Could not save configuration file')

    def __load_config__(self):
        'Load configuration from file.'
        path = filedialog.askopenfilename(title='Configuration file',
                                          filetypes=[
                                              ('Somedo configuration files',
                                               '*.smdc'), ('All files', '*.*')
                                          ])
        if path != () and path != '':
            try:
                config = self.worker.storage.json_load(path)
            except:
                messagebox.showerror('Error',
                                     'Could not load configuration file')
                return
            try:
                self.tk_outdir_entry.delete(0, END)
                self.tk_outdir_entry.insert(0, config['Output'])
                self.worker.storage.outdir = config['Output']
                self.tk_chrome_entry.delete(0, END)
                self.tk_chrome_entry.insert(0, config['Chrome'])
                self.worker.chrome.path = config['Chrome']
                for i in config['Modules']:
                    for j in config['Modules'][i]:
                        self.tk_login_entries[i][j].delete(0, END)
                        self.tk_login_entries[i][j].insert(
                            0, config['Modules'][i][j])
            except:
                messagebox.showerror('Error',
                                     'Could not decode configuration file')

    def __help__(self):
        'Open window to show About / Help'
        help_win = Tk()
        help_win.wm_title('About / Help')
        text = scrolledtext.ScrolledText(help_win,
                                         padx=self.PADX,
                                         pady=self.PADY,
                                         width=self.TARGETWIDTH)
        text.bind("<Key>", lambda e: "break")
        text.insert(END, self.about_help)
        text.pack()
        Button(help_win,
               text="Close",
               width=self.BUTTONWIDTH,
               command=help_win.destroy).pack(padx=self.PADX,
                                              pady=self.PADY,
                                              side=RIGHT)

    def __disable_jobbuttons__(self):
        'Disable the job related buttons except Abort'
        for i in range(self.JOBLISTLENGTH):
            self.jobbuttons[i].config(state=DISABLED)
            self.upbuttons[i].config(state=DISABLED)
            self.downbuttons[i].config(state=DISABLED)
        self.startbutton.config(state=DISABLED)
        self.purgebutton.config(state=DISABLED)
        for i in self.worker.modulenames:
            self.modulebuttons[i].config(state=DISABLED)

    def __enable_jobbuttons__(self):
        'Enable the job related buttons except Abort'
        for i in range(self.JOBLISTLENGTH):
            self.jobbuttons[i].config(state='normal')
            self.upbuttons[i].config(state='normal')
            self.downbuttons[i].config(state='normal')
        self.startbutton.config(state='normal')
        self.purgebutton.config(state='normal')
        for i in self.worker.modulenames:
            self.modulebuttons[i].config(state='normal')

    def __disable_quitbutton__(self):
        'Disable the button Quit and enable Abort'
        self.quitbutton.config(state=DISABLED)
        self.stopbutton.config(state='normal')

    def __enable_quitbutton__(self):
        'Enable the button Quit and disable Abort'
        self.quitbutton.config(state='normal')
        self.stopbutton.config(state=DISABLED)

    def __enable_config__(self):
        'Enable configuration frame'
        self.config_visible = True
        self.frame_changeling.config(text=' \u2737 Configuration ')
        self.frame_config.grid(row=0, column=0, sticky=W + E + N + S)
        self.frame_messages.grid_remove()
        self.button_toggle.config(text='\u2609 Show Messages')
        self.button_clear.config(state=DISABLED)

    def __enable_messages__(self):
        'Enable configuration frame'
        self.config_visible = False
        self.frame_changeling.config(text=' \u2709 Messages')
        self.frame_config.grid_remove()
        self.frame_messages.grid(row=0, column=0, sticky=W + E + N + S)
        self.button_toggle.config(text='\u2609 Show Configuration')
        self.button_clear.config(state='normal')

    def __toggle_config__(self):
        'Toggle Configuration / Messages'
        if self.config_visible:
            self.__enable_messages__()
        else:
            self.__enable_config__()

    def __clear_messages__(self):
        'Clear message / logging output fild'
        if messagebox.askyesno('Somedo', 'Clear messages?'):
            self.text_messages.delete('1.0', END)

    def __write_message__(self, msg):
        'Write to message fiels'
        self.text_messages.insert(END, msg + '\n')
        self.text_messages.yview(END)

    def __start__(self):
        'Start the jobs'
        if len(self.jobs) < 1:
            messagebox.showerror('Error', 'Nothing to do')
            return
        try:  # check if task is running
            if self.thread_worker.isAlive():
                return
        except:
            pass
        self.__disable_jobbuttons__()
        self.__disable_quitbutton__()
        self.__enable_messages__()
        self.__close2stop__()
        self.stop = Event()  # to stop working thread
        self.stop_set = False
        self.running_job = 0
        self.thread_worker = Thread(target=self.__worker__)
        self.thread_worker.start()  # start work
        self.thread_showjob = Thread(target=self.__showjob__)
        self.thread_showjob.start()  # start work

    def __stop__(self):
        'Stop running job but give results based on already optained data'
        if self.stop_set:
            self.__kill__()
            return
        try:  # check if task is running
            if self.thread_worker.isAlive() and messagebox.askyesno(
                    'Somedo', 'Stop running task?'):
                self.stop.set()
        except:
            pass
        self.running_job = -1
        self.stop_set = True

    def __kill__(self):
        'Kill Somedo immediatly'
        if messagebox.askyesno(
                'Somedo',
                'Kill Somedo as fast as possible?\n\nAlready downloaded data mightbe lost!'
        ):
            self.__terminate__()

    def __worker__(self):
        'Execute jobs'
        if len(self.jobs) > 1:
            self.__write_message__('\n--- Executing jobs ---\n')
            while self.running_job < len(self.jobs):
                self.worker.execute_job(self.jobs[self.running_job],
                                        jobnumber=self.running_job + 1,
                                        stop=self.stop)
                self.running_job += 1
        else:
            self.__write_message__('\n--- Executing job ---\n')
            self.worker.execute_job(self.jobs[self.running_job],
                                    stop=self.stop)
        self.__write_message__('\n--- Done ---\n')
        self.__close2quit__()
        self.__enable_jobbuttons__()
        self.__enable_quitbutton__()

    def __showjob__(self):
        'Show what the worker is doing'
        while self.thread_worker.isAlive():
            running = self.running_job
            self.jobbuttons[running].config(fg=self.colour_bg)
            self.jobbuttons[running].config(bg=self.colour_fg)
            sleep(0.75)
            self.jobbuttons[running].config(fg=self.colour_fg)
            self.jobbuttons[running].config(bg=self.colour_bg)
            sleep(0.75)

    def __terminate__(self):
        'Terminate GUI'
        try:
            if self.thread_worker.isAlive():
                raise SystemExit('Worker thread was still running')
        except:
            pass
        try:
            if self.thread_showjob.isAlive():
                raise SystemExit('Thread that indicates job was still running')
        except:
            pass
        self.root.quit()