示例#1
0
 def draw(self, mf, verbose=False, color="SystemButtonFace"):
     unit_frame = LabelFrame(mf, padx=10, pady=10, bg=color)
     unit_frame.grid(row=self.row, column=self.col)
     if verbose:
         mf.update()
         sleep(0.05)
     Label(unit_frame, text=("  " if self.number == 0 else str(self.number))).pack()
     if verbose:
         mf.update()
         sleep(0.1)
         unit_frame.configure(bg="SystemButtonFace", fg="SystemButtonFace")
         mf.update()
         sleep(0.05)
示例#2
0
titleframe = Frame(root)
titleframe.configure(background=bg_colour)
titleframe.grid(row=0, column=0)

editframeTitle = Label(root,
                       text="Manage Entries",
                       background=bg_colour,
                       pady=5)

editframe = LabelFrame(root,
                       text="Manage Entries",
                       borderwidth=1,
                       labelanchor='n',
                       labelwidget=editframeTitle,
                       font=("Myriad Pro Bold", 10))
editframe.configure(background=bg_colour)
editframe.grid(row=2, column=0, padx=40, pady=25)

roadtax_tab = ttk.Notebook(root)

bodyframe = Frame(roadtax_tab)
bodyframe.configure(background=bg_colour)
bodyframe.grid()

roadtax_tab.add(bodyframe, text="Roadtax")
roadtax_tab.enable_traversal()
roadtax_tab.grid(row=1, column=0, sticky=S)

title = Label(titleframe,
              font=("Courier", 28),
              text="Road-Tax Renewal Tracker",
        mf_msg = 'The file sqm-example-logo.png is missing.'

    if not mf_msg:
        return

    root.withdraw()
    messagebox.showerror('Warning', mf_msg)
    root.destroy()
    sys.exit()


# Check for essential files.
file_checks()

quiz_name_btn_frame = LabelFrame(root)
quiz_name_btn_frame.configure(borderwidth=2, relief='ridge')
quiz_name_btn_frame.grid(row=0, column=0, sticky=W + E)

# Frame for big yellow btn display.
load_logo_btn_frame = LabelFrame(root)
load_logo_btn_frame.configure(borderwidth=2, relief='ridge', bg='limegreen')
load_logo_btn_frame.grid(row=1, column=0, sticky=W + E)

# Frame for logo display.
logo_frame = LabelFrame(root, width=454, height=253)
logo_frame.configure(borderwidth=2, relief='ridge', bg='grey')
logo_frame.grid(row=2, column=0)

ttips.Create(logo_frame, 'Your image will be auto resized\n'
             'if it is not 450x253 pixels.',
             fontname="helvetica",
示例#4
0
def openaboutwindow(main_root_title):
    global about_window

    # Defines the path to config.ini and opens it for reading/writing
    config_file = 'Runtime/config.ini'  # Creates (if doesn't exist) and defines location of config.ini
    config = ConfigParser()
    config.read(config_file)

    try:  # If "About" window is already opened, display a message, then close the "About" window
        if about_window.winfo_exists():
            messagebox.showinfo(
                title=f'"{about_window.wm_title()}" Info!',
                parent=about_window,
                message=
                f'"{about_window.wm_title()}" is already opened, closing window instead'
            )
            about_window.destroy()
            return
    except NameError:
        pass

    def about_exit_function():  # Exit function when hitting the 'X' button
        func_parser = ConfigParser()
        func_parser.read(config_file)
        if func_parser['save_window_locations'][
                'about'] == 'yes':  # If auto save position on close is checked
            try:
                if func_parser['save_window_locations'][
                        'about position'] != about_window.geometry():
                    func_parser.set('save_window_locations', 'about position',
                                    about_window.geometry())
                    with open(config_file, 'w') as configfile:
                        func_parser.write(configfile)
            except (Exception, ):
                pass

        about_window.destroy()  # Close window

    about_window = Toplevel()
    about_window.title('About')
    about_window.configure(background="#434547")
    if config['save_window_locations']['about position'] == '' or config[
            'save_window_locations']['about'] == 'no':
        window_height = 650
        window_width = 720
        screen_width = about_window.winfo_screenwidth()
        screen_height = about_window.winfo_screenheight()
        x_coordinate = int((screen_width / 2) - (window_width / 2))
        y_coordinate = int((screen_height / 2) - (window_height / 2))
        about_window.geometry("{}x{}+{}+{}".format(window_width, window_height,
                                                   x_coordinate, y_coordinate))
    elif config['save_window_locations']['about position'] != '' and config[
            'save_window_locations']['about'] == 'yes':
        about_window.geometry(
            config['save_window_locations']['about position'])
    about_window.resizable(False, False)
    about_window.protocol('WM_DELETE_WINDOW', about_exit_function)

    about_window.grid_columnconfigure(0, weight=1)

    detect_font = font.nametofont(
        "TkDefaultFont")  # Get default font value into Font object
    set_font = detect_font.actual().get("family")

    about_information_frame = LabelFrame(about_window,
                                         text=' About ',
                                         labelanchor="nw")
    about_information_frame.grid(column=0,
                                 row=0,
                                 columnspan=1,
                                 padx=5,
                                 pady=(0, 3),
                                 sticky=N + S + E + W)
    about_information_frame.configure(fg="#3498db",
                                      bg="#434547",
                                      bd=3,
                                      font=(set_font, 10, "bold"))
    about_information_frame.grid_rowconfigure(0, weight=1)
    about_information_frame.grid_columnconfigure(0, weight=1)

    about_window_text = Text(about_information_frame,
                             background="#434547",
                             foreground="white",
                             relief=FLAT,
                             height=10)
    about_window_text.pack()
    about_window_text.insert(INSERT, f"{main_root_title}\n")
    about_window_text.insert(INSERT, "\n")
    about_window_text.insert(
        INSERT,
        "Development: jlw4049\n\nContributors: BassThatHertz, aaronrausch")
    about_window_text.insert(INSERT, "\n\n")
    about_window_text.insert(
        INSERT,
        "Power audio encoding GUI, that mostly uses FFMPEG at the heart. \n")
    about_window_text.configure(state=DISABLED)

    about_information_frame = LabelFrame(about_window,
                                         text=' License ',
                                         labelanchor="nw")
    about_information_frame.grid(column=0,
                                 row=1,
                                 columnspan=1,
                                 padx=5,
                                 pady=(0, 3),
                                 sticky=N + S + E + W)
    about_information_frame.configure(fg="#3498db",
                                      bg="#434547",
                                      bd=3,
                                      font=(set_font, 10, "bold"))
    about_information_frame.grid_rowconfigure(0, weight=1)
    about_information_frame.grid_columnconfigure(0, weight=1)

    license_text = """
    Copyright (c) 2012-2022 Scott Chacon and others

    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
    "Software"), to deal in the Software without restriction, including
    without limitation the rights to use, copy, modify, merge, publish,
    distribute, sublicense, and/or sell copies of the Software, and to
    permit persons to whom the Software is furnished to do so, subject to
    the following conditions:
    
    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
    LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
    OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    """

    about_window_license = Text(about_information_frame,
                                background="#434547",
                                foreground="white",
                                relief=FLAT)
    about_window_license.pack(anchor='center')
    about_window_license.insert(INSERT, license_text)
    about_window_license.configure(state=DISABLED)
def show_streams_mediainfo_function(x):  # Stream Viewer
    global stream_win_text_area, exit_stream_window, stream_window
    video_input = pathlib.Path(x)  # "x" is passed through from main GUI

    # Defines the path to config.ini and opens it for reading/writing
    config_file = 'Runtime/config.ini'  # Creates (if it doesn't exist) and defines location of config.ini
    config = ConfigParser()
    config.read(config_file)

    detect_font = font.nametofont("TkDefaultFont")  # Get default font value into Font object
    set_font = detect_font.actual().get("family")
    # set_font_size = detect_font.actual().get("size")

    try:
        stream_win_text_area.config(state=NORMAL)
        stream_win_text_area.delete(1.0, END)
    except (NameError, TclError):
        stream_window = Toplevel()
        stream_window.title("Audio Streams")
        stream_window.configure(background="#434547")
        stream_window.resizable(False, False)  # Disable resize of this window
        if config['save_window_locations']['audio window - view streams - position'] != '' and \
                config['save_window_locations']['audio window - view streams'] == 'yes':
            stream_window.geometry(config['save_window_locations']['audio window - view streams - position'])
        stream_window.protocol('WM_DELETE_WINDOW', exit_stream_window)
        stream_window.grid_columnconfigure(0, weight=1)
        stream_window.grid_rowconfigure(0, weight=1)

        stream_window_frame = LabelFrame(stream_window, text=' Audio Streams ', labelanchor="n")
        stream_window_frame.grid(column=0, row=0, columnspan=1, padx=5, pady=(0, 3), sticky=N + S + E + W)
        stream_window_frame.configure(fg="#3498db", bg="#434547", bd=3, font=(set_font, 10, "bold"))
        stream_window_frame.grid_rowconfigure(0, weight=1)
        stream_window_frame.grid_columnconfigure(0, weight=1)

        stream_win_text_area = scrolledtext.ScrolledText(stream_window_frame, width=80, height=25, tabs=10, spacing2=3,
                                                         spacing1=2, spacing3=3)
        stream_win_text_area.config(bg='black', fg='#CFD2D1', bd=8)
        stream_win_text_area.grid(column=0, pady=5, padx=5, sticky=N + E + S + W)

    character_space = 30  # Can be changed to adjust space of all items in the list automatically
    media_info = MediaInfo.parse(video_input)  # Uses pymediainfo to get information for track selection
    for track in media_info.tracks:  # For loop to loop through mediainfo tracks
        # Formatting --------------------------------------------------------------------------------------------------
        if track.track_type == 'Audio':  # Only grab audio track information
            if str(track.stream_identifier) != 'None':  # Gets stream #
                audio_track_id_space = 'Track#' + ' ' * int(f'{character_space - len("Track#")}')
                audio_track_id = audio_track_id_space + f': {str(int(track.stream_identifier) + 1)}\n'
            else:
                audio_track_id = ''
            if str(track.format) != 'None':  # Gets format string of tracks (aac, ac3 etc...)
                audio_format_space = 'Codec' + ' ' * int(f'{character_space - len("Codec")}')
                audio_format = audio_format_space + f": {str(track.commercial_name)} - ({str(track.format).lower()})\n"
            else:
                audio_format = ''
            if str(track.channel_s) != 'None':  # Gets audio channels of input tracks
                audio_channel_space = 'Channels' + ' ' * int(f'{character_space - len("Channels")}')
                if str(track.channel_s) == '8':
                    show_channels = '7.1'
                elif str(track.channel_s) == '6':
                    show_channels = '5.1'
                elif str(track.channel_s) == '3':
                    show_channels = '2.1'
                else:
                    show_channels = str(track.channel_s)
                audio_channels = audio_channel_space + f": {show_channels} - {str(track.channel_layout)}\n"
            else:
                audio_channels = ''
            if str(track.bit_rate_mode) != 'None':  # Gets audio bit rate mode
                audio_bitrate_mode_space = 'Bit rate mode' + ' ' * int(f'{character_space - len("Bit rate mode")}')
                if str(track.other_bit_rate_mode) != 'None':  # Get secondary string of audio bit rate mode
                    audio_bitrate_mode = audio_bitrate_mode_space + f": {str(track.bit_rate_mode)} / " \
                                                                    f"{str(track.other_bit_rate_mode[0])}\n"
                else:
                    audio_bitrate_mode = audio_bitrate_mode_space + f": {str(track.bit_rate_mode)}\n"
            else:
                audio_bitrate_mode = ''
            if str(track.other_bit_rate) != 'None':  # Gets audio bit rate of input tracks
                audio_bitrate_space = 'Bit rate' + ' ' * int(f'{character_space - len("Bit rate")}')
                audio_bitrate = audio_bitrate_space + f": {str(track.other_bit_rate[0])}\n"
            else:
                audio_bitrate = ''
            if str(track.other_language) != 'None':  # Gets audio language of input tracks
                audio_language_space = 'Language' + ' ' * int(f'{character_space - len("Language")}')
                audio_language = audio_language_space + f": {str(track.other_language[0])}\n"
            else:
                audio_language = ''
            if str(track.title) != 'None':  # Gets audio title of input tracks
                audio_title_space = 'Title' + ' ' * int(f'{character_space - len("Title")}')
                if len(str(track.title)) > 40:  # Counts title character length
                    audio_title = audio_title_space + f": {str(track.title)[:40]}...\n"  # If title > 40 characters
                else:
                    audio_title = audio_title_space + f": {str(track.title)}\n"  # If title is < 40 characters
            else:
                audio_title = ''
            if str(track.other_sampling_rate) != 'None':  # Gets audio sampling rate of input tracks
                audio_sampling_rate_space = 'Sampling Rate' + ' ' * int(f'{character_space - len("Sampling Rate")}')
                audio_sampling_rate = audio_sampling_rate_space + f": {str(track.other_sampling_rate[0])}\n"
            else:
                audio_sampling_rate = ''
            if str(track.other_duration) != 'None':  # Gets audio duration of input tracks
                audio_duration_space = 'Duration' + ' ' * int(f'{character_space - len("Duration")}')
                audio_duration = audio_duration_space + f": {str(track.other_duration[0])}\n"
            else:
                audio_duration = ''
            if str(track.delay) != 'None':  # Gets audio delay of input tracks
                if str(track.delay) == '0':
                    audio_delay = ''
                else:
                    audio_delay_space = 'Delay' + ' ' * int(f'{character_space - len("Delay")}')
                    audio_del_to_vid_space = 'Delay to Video' + ' ' * int(f'{character_space - len("Delay to Video")}')
                    audio_delay = audio_delay_space + f': {str(track.delay)}ms\n' \
                                  + audio_del_to_vid_space + f': {str(track.delay_relative_to_video)}ms\n '
            else:
                audio_delay = ''
            if str(track.other_stream_size) != 'None':  # Get tracks stream size
                audio_track_size_space = 'Stream size' + ' ' * int(f'{character_space - len("Stream size")}')
                audio_track_stream_size = audio_track_size_space + f": {str(track.other_stream_size[4])}\n"
            else:
                audio_track_stream_size = ''
            if str(track.other_bit_depth) != 'None':  # Get tracks bit-depth
                audio_track_b_depth_space = 'Bit Depth' + ' ' * int(f'{character_space - len("Bit Depth")}')
                audio_track_bit_depth = audio_track_b_depth_space + f": {(track.other_bit_depth[0])}\n"
            else:
                audio_track_bit_depth = ''
            if str(track.compression_mode) != 'None':
                audio_track_compression_space = 'Compression' + ' ' * int(f'{character_space - len("Compression")}')
                audio_track_compression = audio_track_compression_space + f": {str(track.compression_mode)}\n"
            else:
                audio_track_compression = ''
            if str(track.default) != 'None':  # Get tracks default boolean
                audio_track_default_space = 'Default' + ' ' * int(f'{character_space - len("Default")}')
                audio_track_default = audio_track_default_space + f": {str(track.default)}\n"
            else:
                audio_track_default = ''
            if str(track.forced) != 'None':  # Get tracks forced boolean
                audio_track_forced_space = 'Forced' + ' ' * int(f'{character_space - len("Forced")}')
                audio_track_forced = audio_track_forced_space + f": {str(track.forced)}"
            else:
                audio_track_forced = ''

            # ---------------------------------------------------------------------------------------------- Formatting
            audio_track_info = str(audio_track_id + audio_format + audio_channels + audio_bitrate_mode +
                                   audio_bitrate + audio_sampling_rate + audio_delay + audio_duration +
                                   audio_language + audio_title + audio_track_stream_size + audio_track_bit_depth +
                                   audio_track_compression + audio_track_default + audio_track_forced)  # Formatting
            media_info_track_string = 80 * '#' + '\n' + audio_track_info + '\n' + 80 * '#' + '\n'  # String to insert
            stream_win_text_area.configure(state=NORMAL)  # Enable textbox
            stream_win_text_area.insert(INSERT, media_info_track_string)  # Insert string
            stream_win_text_area.insert(INSERT, '\n')  # Insert a newline
            stream_win_text_area.configure(state=DISABLED)  # Disable textbox

    def right_click_menu_func(x_y_pos):  # Function for mouse button 3 (right click) to pop up menu
        right_click_menu.tk_popup(x_y_pos.x_root, x_y_pos.y_root)  # This gets the position of cursor

    def copy_selected_text():  # Function to copy only selected text
        pya_hotkey('ctrl', 'c')
        time_sleep(.01)  # Slow program incase ctrl+c is slower

    right_click_menu = Menu(stream_window, tearoff=False)  # This is the right click menu
    right_click_menu.add_command(label='Copy Selected Text', command=copy_selected_text)
    right_click_menu.add_command(label='Copy All Text', command=pyperclip_copy(stream_win_text_area.get(1.0, END)))
    stream_window.bind('<Button-3>', right_click_menu_func)  # Uses mouse button 3 (right click) to pop up menu
    Hovertip(stream_win_text_area, 'Right click to copy', hover_delay=1200)  # Hover tip tool-tip
示例#6
0
class _get_value_v2(_Dialog):
    def body(self, master):
        dialogframe = Frame(master, width=426, height=213)
        self.dialogframe = dialogframe
        dialogframe.pack()

        self.RadioGroup_1_StringVar = StringVar()

        self.make_Entry_1(self.dialogframe)  #       Entry:  at Main(3,2)
        self.make_Label_1(
            self.dialogframe)  #       Label: Input XXX Value : at Main(1,1)
        self.make_Label_2(
            self.dialogframe)  #       Label: definition : at Main(2,1)
        self.make_Label_3(self.dialogframe)  #       Label: XXX= : at Main(3,1)
        self.make_RadioGroup_1(
            self.dialogframe)  #  RadioGroup: XXX= : at Main(4,1)
        self.make_Radiobutton_1(
            self.RadioGroup_1)  # Radiobutton: True : at RadioGroup_1(2,1)
        self.make_Radiobutton_2(
            self.RadioGroup_1)  # Radiobutton: False : at RadioGroup_1(3,1)

        self.RadioGroup_1_StringVar.set("1")
        self.RadioGroup_1_StringVar_traceName = self.RadioGroup_1_StringVar.trace_variable(
            "w", self.RadioGroup_1_StringVar_Callback)
        # >>>>>>insert any user code below this comment for section "top_of_init"

        if type(False) == self.dialogOptions['val_type']:
            self.Label_3.grid_remove()
            self.Entry_1.grid_remove()
            value = self.dialogOptions.get('value', True)
            if value:
                self.RadioGroup_1_StringVar.set("1")
            else:
                self.RadioGroup_1_StringVar.set("2")

        else:
            self.RadioGroup_1.grid_remove()

        self.Entry_1.focus_set()
        self.Entry_1.select_range(0, END)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Entry_1"
    def make_Entry_1(self, frame):
        """       Entry:  at Main(3,2)"""
        self.Entry_1 = Entry(frame, width="30")
        self.Entry_1.grid(row=3, column=2, sticky="w", columnspan="1")
        self.Entry_1_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Entry_1"
        value = self.dialogOptions.get('value', '')
        self.Entry_1_StringVar.set(value)

        self.Entry_1.configure(textvariable=self.Entry_1_StringVar)
        self.Entry_1_StringVar_traceName = self.Entry_1_StringVar.trace_variable(
            "w", self.Entry_1_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_1"
    def make_Label_1(self, frame):
        """       Label: Input XXX Value : at Main(1,1)"""
        self.Label_1 = Label(frame, text="Input XXX Value", width="60")
        self.Label_1.grid(row=1, column=1, columnspan="2")

        # >>>>>>insert any user code below this comment for section "make_Label_1"
        name = self.dialogOptions.get('label', '')
        if not name:
            name = self.dialogOptions.get('name', '')
        self.Label_1.configure(text='Input: ' + name)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_2"
    def make_Label_2(self, frame):
        """       Label: definition : at Main(2,1)"""
        self.Label_2 = Label(frame, text="definition", width="60", height="4")
        self.Label_2.grid(row=2, column=1, columnspan="2")

        # >>>>>>insert any user code below this comment for section "make_Label_2"
        desc = self.dialogOptions.get('desc', '')
        self.Label_2.configure(text=desc, wraplength=400)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_3"
    def make_Label_3(self, frame):
        """       Label: XXX= : at Main(3,1)"""
        self.Label_3 = Label(frame, text="XXX=", width="20", anchor="e")
        self.Label_3.grid(row=3, column=1, sticky="e")

        # >>>>>>insert any user code below this comment for section "make_Label_3"
        name = self.dialogOptions.get('name', '')
        self.Label_3.configure(text=name + '=')

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_RadioGroup_1"
    def make_RadioGroup_1(self, frame):
        """  RadioGroup: XXX= : at Main(4,1)"""
        self.RadioGroup_1 = LabelFrame(frame,
                                       width="60",
                                       height="50",
                                       text="XXX=")
        self.RadioGroup_1.grid(row=4, column=1, columnspan="2")

        # >>>>>>insert any user code below this comment for section "make_RadioGroup_1"
        name = self.dialogOptions.get('label', '')
        if not name:
            name = self.dialogOptions.get('name', '')
        self.RadioGroup_1.configure(text='Input: ' + name)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Radiobutton_1"
    def make_Radiobutton_1(self, frame):
        """ Radiobutton: True : at RadioGroup_1(2,1)"""
        self.Radiobutton_1 = Radiobutton(frame,
                                         value="1",
                                         text="True",
                                         width="15",
                                         anchor="w")
        self.Radiobutton_1.grid(row=2, column=1)

        # >>>>>>insert any user code below this comment for section "make_Radiobutton_1"

        self.Radiobutton_1.configure(variable=self.RadioGroup_1_StringVar)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Radiobutton_2"
    def make_Radiobutton_2(self, frame):
        """ Radiobutton: False : at RadioGroup_1(3,1)"""
        self.Radiobutton_2 = Radiobutton(frame,
                                         value="2",
                                         text="False",
                                         width="15",
                                         anchor="w")
        self.Radiobutton_2.grid(row=3, column=1)

        # >>>>>>insert any user code below this comment for section "make_Radiobutton_2"

        self.Radiobutton_2.configure(variable=self.RadioGroup_1_StringVar)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Entry_1_StringVar_traceName"
    def Entry_1_StringVar_Callback(self, varName, index, mode):
        """       Entry:  at Main(3,2)"""
        pass

        # >>>>>>insert any user code below this comment for section "Entry_1_StringVar_traceName"
        # replace, delete, or comment-out the following
        #print( "Entry_1_StringVar_Callback varName, index, mode",varName, index, mode )
        #print( "    new StringVar value =",self.Entry_1_StringVar.get() )

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "RadioGroup_1_StringVar_traceName"
    def RadioGroup_1_StringVar_Callback(self, varName, index, mode):
        """  RadioGroup: XXX= : at Main(4,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "RadioGroup_1_StringVar_traceName"
        # replace, delete, or comment-out the following
        #print( "RadioGroup_1_StringVar_Callback varName, index, mode",varName, index, mode )
        #print( "    new StringVar value =",self.RadioGroup_1_StringVar.get() )

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "standard_message_dialogs"

    # standard message dialogs... showinfo, showwarning, showerror
    def ShowInfo(self, title='Title', message='your message here.'):
        tkinter.messagebox.showinfo(title, message)
        return

    def ShowWarning(self, title='Title', message='your message here.'):
        tkinter.messagebox.showwarning(title, message)
        return

    def ShowError(self, title='Title', message='your message here.'):
        tkinter.messagebox.showerror(title, message)
        return

    # standard question dialogs... askquestion, askokcancel, askyesno, or askretrycancel
    # return True for OK, Yes, Retry, False for Cancel or No
    def AskYesNo(self, title='Title', message='your question here.'):
        return tkinter.messagebox.askyesno(title, message)

    def AskOK_Cancel(self, title='Title', message='your question here.'):
        return tkinter.messagebox.askokcancel(title, message)

    def AskRetryCancel(self, title='Title', message='your question here.'):
        return tkinter.messagebox.askretrycancel(title, message)

    # return "yes" for Yes, "no" for No
    def AskQuestion(self, title='Title', message='your question here.'):
        return tkinter.messagebox.askquestion(title, message)

    # END of standard message dialogs

    # >>>>>>insert any user code below this comment for section "standard_message_dialogs"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "dialog_validate"
    def validate(self):
        self.result = {}  # return a dictionary of results

        #self.result["Entry_1"] = self.Entry_1_StringVar.get()
        #self.result["RadioGroup_1"] = self.RadioGroup_1_StringVar.get()

        # >>>>>>insert any user code below this comment for section "dialog_validate"

        value = self.Entry_1_StringVar.get()
        #print('Entered value=',value, type(value) )

        if type(11.11) == self.dialogOptions['val_type']:
            try:
                value = eval(value)
            except:
                self.ShowError(
                    title='Invalid Float',
                    message='"%s" NOT recognized as float\nPlease Try Again.' %
                    value)
                return 0

            if is_float(value) or is_int(
                    value):  # accept an integer as a float
                value = floatCast(value)
            else:
                print('    Rejected float value=', value, type(value))
                self.ShowError(
                    title='Invalid Float',
                    message='"%s" is NOT a float\nPlease Try Again.' % value)
                return 0

            # if float violates clamp, issue an error
            name = self.dialogOptions.get('label', '')
            if not name:
                name = self.dialogOptions.get('name', '')

            if name in value_clampD:
                min_value, max_value = value_clampD[name]
                if value < min_value or value > max_value:
                    # violates range
                    self.ShowError(
                        title='Invalid %s Value' % name,
                        message='"%s" MUST be >=%g and <=%g\nPlease Try Again.'
                        % (name, min_value, max_value))
                    return 0

        elif type(123) == self.dialogOptions['val_type']:
            try:
                value = eval(value)
            except:
                self.ShowError(
                    title='Invalid Integer',
                    message='"%s" NOT recognized as integer\nPlease Try Again.'
                    % value)
                return 0

            if is_int(value):
                value = intCast(value)
            else:
                self.ShowError(
                    title='Invalid Integer',
                    message='"%s" is NOT a float\nPlease Try Again.' % value)
                return 0

        elif type("string") == self.dialogOptions['val_type']:
            value = str(value)

        elif type(False) == self.dialogOptions['val_type']:
            value = self.RadioGroup_1_StringVar.get() == '1'
            #print('Returning Boolean Value =', value, type(value))

        self.result["return_value"] = value
        #print('Dialog result =', self.result)

        return 1

    """
    # for testing, reinstate this code below
    def Button_1_Click(self, event): #click method for component ID=1
        desc = 'radius of curvature just downstream of throat (Rdownstream / Rthrt) this could be a very long description and we would just need to wrap it.'
        value = False
        dialog = _get_value_v2(self.master, "Test Dialog", 
                 dialogOptions={'name':'Area Ratio', 'value':value, 'desc':desc, 'val_type':type(value)})

    """

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "end"

    def apply(self):
        pass
示例#7
0
class GUI:

    # Initialize GUI here
    def __init__(self):

        #  Modify root title & prevent empty Tkinter GUI window from appearing
        self.root = Tk()
        self.root.title("Pyxe Auto-Compiler")
        self.root.withdraw()

        # Popup that gets created when you click the 'About' menu option
        def about_popup():
            top = Toplevel()
            top.title("About Me")
            top.geometry = "500x400"
            top.resizable(False, False)
            top.iconbitmap(pyxe_favicon)

            about_labelframe = LabelFrame(top,
                                          labelanchor="nw",
                                          text="Developer Profile:",
                                          width=600,
                                          height=200,
                                          font=('', 10))
            about_labelframe.pack(fill="both", expand=True, padx=3, pady=3)

            profile_photo = Image.open(
                resource_path(
                    r"pyxe_resources\data\DutytoDevelop_Profile_Pic.png"))
            resized = profile_photo.resize((150, 150))
            profile_photo_resize = ImageTk.PhotoImage(resized)

            canvas = Canvas(about_labelframe, height=150, width=150)
            canvas.create_image(75, 75, image=profile_photo_resize)
            canvas.image = profile_photo_resize
            canvas.grid(row=1, column=1, padx=3, pady=(3, 0), sticky="nsew")

            about_label = Label(
                about_labelframe,
                text="Name: Nicholas H.\nGitHub: DutytoDevelop",
                font=('', 10, 'bold'))
            about_label.configure(anchor="center", justify='center')
            about_label.grid(row=2,
                             column=1,
                             padx=3,
                             pady=(0, 3),
                             sticky="nsew")
            return

        # Open default web browser to the Pyxe GitHub repository page
        def open_help_page():
            help_page_url = "https://GitHub.com/DutytoDevelop/Pyxe"
            webbrowser.open_new(help_page_url)

        self.menubar = Menu(self.root)
        self.optionmenu = Menu(self.menubar, tearoff=0)
        self.menubar.add_cascade(label="Options", menu=self.optionmenu)
        self.optionmenu.add_command(label="About...", command=about_popup)
        self.optionmenu.add_command(label="Help", command=open_help_page)
        self.optionmenu.add_separator()
        self.optionmenu.add_command(label="Exit", command=self.exit_compiler)
        self.root.config(menu=self.menubar)

        #  A grid frame that helps layout the widgets on the root window
        self.frame = Frame(self.root)
        Grid.rowconfigure(self.root, 0, weight=1)
        Grid.columnconfigure(self.root, 0, weight=1)
        self.frame.grid_columnconfigure(2, weight=1)

        #  These widgets make up the function allowing you to select a Python file to compile
        Label(self.frame, text='Python File:').grid(row=1,
                                                    column=1,
                                                    sticky="E")

        #  Variable that connects that's being typed to the textbox
        self.program_filepath_textbox = Entry(self.frame)
        self.program_filepath_textbox.configure(width=80, state="disabled")
        self.program_filepath_textbox.grid(row=1,
                                           column=2,
                                           sticky='EW',
                                           padx=(0, 5),
                                           pady=5,
                                           ipadx=5)

        self.file_selection_button = Button(
            self.frame,
            text='Select Python File',
            command=lambda: self.python_get_filepath_of_file(
                title="Select Python File",
                initialdir=project_dir,
                filetypes=[("Python File", "*.py")],
                element=self.program_filepath_textbox))
        self.file_selection_button.configure(width=20)
        self.file_selection_button.grid(row=1,
                                        column=3,
                                        padx=5,
                                        pady=5,
                                        sticky="EW")

        #  These widgets make up the function allowing you to select a picture to be the program's favicon
        Label(self.frame, text='Program Icon:').grid(row=2,
                                                     column=1,
                                                     sticky="E")

        self.icon_filepath_textbox = Entry(self.frame)
        self.icon_filepath_textbox.configure(width=80, state="disabled")
        self.icon_filepath_textbox.grid(row=2,
                                        column=2,
                                        sticky='EW',
                                        padx=(0, 5),
                                        pady=5,
                                        ipadx=5)

        self.python_icon_selector = Button(
            self.frame,
            text='Select Program Icon',
            command=lambda: self.python_get_filepath_of_file(
                title="Select Program Icon",
                initialdir=project_dir,
                filetypes=[("Pictures", "*.jpg;*.jpeg,*.png;*.svg;*.ico")],
                element=self.icon_filepath_textbox))
        self.python_icon_selector.configure(width=20)
        self.python_icon_selector.grid(row=2,
                                       column=3,
                                       padx=5,
                                       pady=5,
                                       sticky="EW")

        #  These widgets make up the function allowing you to give a name to the executable
        Label(self.frame, text='Program Name:').grid(row=3,
                                                     column=1,
                                                     sticky="E")

        self.program_name_textbox = Entry(self.frame)
        self.program_name_textbox.configure(width=80)
        self.program_name_textbox.grid(row=3,
                                       column=2,
                                       sticky='EW',
                                       padx=(0, 5),
                                       pady=5,
                                       ipadx=5)

        #  Radio button options will return a boolean and GUI converts that into '--onefile' or '--onedir' parameter
        self.radiobtn_compile_option = BooleanVar()

        self.onefile_compile = Radiobutton(
            self.frame,
            text="One File",
            variable=self.radiobtn_compile_option,
            value=True,
            command=None)
        self.onefile_compile.grid(row=3,
                                  column=3,
                                  sticky='W',
                                  padx=(0, 5),
                                  pady=5,
                                  ipadx=5)

        self.onedir_compile = Radiobutton(
            self.frame,
            text="One Dir",
            variable=self.radiobtn_compile_option,
            value=False,
            command=None)
        self.onedir_compile.grid(row=3,
                                 column=3,
                                 sticky='E',
                                 padx=(0, 5),
                                 pady=5,
                                 ipadx=5)
        self.radiobtn_compile_option.set(
            True)  # Set this option as the default option

        #  These widgets make up the function allowing you to select where you want to create the executable
        Label(self.frame, text='Build Folder:').grid(row=4,
                                                     column=1,
                                                     sticky="E")

        self.build_directory_textbox = Entry(self.frame)
        self.build_directory_textbox.configure(state='disabled')
        self.build_directory_textbox.grid(row=4,
                                          column=2,
                                          sticky='EW',
                                          padx=(0, 5),
                                          pady=5,
                                          ipadx=5)

        select_directory = Button(self.frame,
                                  text="Select Directory",
                                  command=lambda: self.set_directory_path(
                                      title="Select Directory",
                                      initialdir=project_dir,
                                      element=self.build_directory_textbox))
        select_directory.configure(width=20)
        select_directory.grid(row=4,
                              column=3,
                              sticky="EW",
                              padx=10,
                              pady=5,
                              ipadx=5)

        #  These widgets make up the function allowing you to select where you add the data
        Label(self.frame, text='Data Folders:').grid(row=5,
                                                     column=1,
                                                     sticky="E")

        self.data_folder_directory_textbox = Entry(self.frame)
        self.data_folder_directory_textbox.configure(state='disabled')
        self.data_folder_directory_textbox.grid(row=5,
                                                column=2,
                                                sticky='EW',
                                                padx=(0, 5),
                                                pady=5,
                                                ipadx=5)

        add_data_folder = Button(
            self.frame,
            text="Add Folder",
            command=lambda: self.set_directory_path(
                title="Add Path",
                initialdir=project_dir,
                element=self.data_folder_directory_textbox,
                append_directory=True))
        add_data_folder.configure(width=8)
        add_data_folder.grid(row=5,
                             column=3,
                             sticky="W",
                             padx=10,
                             pady=5,
                             ipadx=5)

        clear_data_folder = Button(
            self.frame,
            text="Clear",
            command=lambda: self.set_directory_path(
                title="Add Directory",
                initialdir=project_dir,
                element=self.data_folder_directory_textbox,
                append_directory=True))
        clear_data_folder.configure(width=8)
        clear_data_folder.grid(row=5,
                               column=3,
                               sticky="E",
                               padx=10,
                               pady=5,
                               ipadx=5)

        #  These widgets make up the function that allows you to compile the executable
        self.compile_button = Button(
            self.frame,
            text="Compile",
            command=lambda: thread_function(function=self.compile_executable))
        self.compile_button.grid(row=6,
                                 column=1,
                                 columnspan=2,
                                 sticky='EW',
                                 padx=(10, 5),
                                 pady=5,
                                 ipadx=5)

        self.compilation_section = LabelFrame(self.frame,
                                              text='Console Output:',
                                              labelanchor="nw")
        self.compilation_section.configure(height=11)
        self.compilation_section.grid(row=7,
                                      column=1,
                                      columnspan=4,
                                      sticky="NESW",
                                      padx=10,
                                      pady=10)

        self.compiler_text = ScrolledText(self.compilation_section,
                                          yscrollcommand=True,
                                          bg='lightgrey',
                                          font=('Nimbus Mono L', 9),
                                          fg='green')
        self.compiler_text.configure(height=11, state="disabled")
        self.compiler_text.bind("<Key>", lambda e: "break")
        self.compiler_text.yview_pickplace("end")
        self.compiler_text.pack(expand=True, fill="both", padx=5, pady=7)

        #  This widget make up the function allowing you to discontinue compiling the executable
        self.quit_button = Button(self.frame,
                                  text="Quit",
                                  command=lambda: self.exit_compiler())
        self.quit_button.grid(row=6,
                              column=3,
                              sticky='EW',
                              padx=10,
                              pady=5,
                              ipadx=5)

        #  Expand self.frame to fit the root window
        self.frame.grid(sticky="nsew", padx=2, pady=2)

        #  GUI size and placement on the screen
        self.screen_width = GetSystemMetrics(0)
        self.screen_height = GetSystemMetrics(1)
        self.app_width = 800
        self.app_height = 430
        self.root.geometry(
            str(self.app_width) + "x" + str(self.app_height) + "+" +
            str(int((self.screen_width / 2) - (self.app_width / 2))) + "+" +
            str(int((self.screen_height / 2) - (self.app_height / 2))))

        #  The icon that appears in the corner of the executable
        self.root.iconbitmap(pyxe_favicon)

        #  Restricts the GUI from being resized
        self.root.resizable(False, False)

        #  Get rid of extra GUI window when creating dialog boxes
        self.root.deiconify()

    #  Grab filepath of Python file
    def python_get_filepath_of_file(self, title, initialdir, filetypes,
                                    element):
        self.title = title
        self.initialdir = initialdir
        self.filetypes = filetypes
        self.python_get_filepath = self.get_filepath_of_file(
            title, initialdir, filetypes)
        self.element = element
        self.element.configure(state="enabled")
        self.set_entrybox_text(element, self.python_get_filepath)
        self.element.configure(state="disabled")
        return

    #  Function that creates the PythonFile object with the data necessary to compile the executable
    def compile_executable(self):
        self.executable_info = PythonFile(
            python_filepath=self.get_entrybox_text(
                element=self.program_filepath_textbox),
            name=self.get_entrybox_text(element=self.program_name_textbox),
            favicon_path=self.get_entrybox_text(
                element=self.icon_filepath_textbox),
            build_directory=self.get_entrybox_text(
                element=self.build_directory_textbox),
            data_folder_present=self.get_entrybox_text(
                element=self.data_folder_directory_textbox),
            onefile_radiobtn_selected=self.radiobtn_compile_option.get())
        self.executable_info.make_exe()

    def exit_compiler(self):
        self.root.destroy()
        del self.executable_info
        exit()

    #  Display Tkinter GUI
    def run_autocompiler(self):
        self.root.mainloop()

    def get_radiobutton_value(self, element):
        self.element = element
        element.get()

    #  Return text inside of Tkinter Entry widget
    def get_entrybox_text(self, element):
        self.element = element
        element.configure(state="normal")
        entrybox_text = os.path.join(self.element.get())
        element.configure(state="disabled")
        return entrybox_text

    #  Set text inside of Tkinter Entry widget
    def set_entrybox_text(self,
                          element: Text,
                          text: str,
                          append_text: bool = False):
        self.element = element
        self.text = text
        if (append_text is True):
            if (detected_os == 'windows'):
                seperator = ';'
            else:
                seperator = ':'
            if (self.get_entrybox_text(self.element) != ''):
                self.text = self.text
            else:
                self.text = seperator.join(
                    self.get_entrybox_text(self.element), self.text)
            self.element.insert('end', self.text)
        else:
            self.element.delete(0, 'end')
            self.element.insert(0, self.text)
        return

    #  Return path of directory if it exists
    def get_directory_path(self, title, initialdir):
        #  If file doesn't exist, continue prompting file selection
        self.selected_directory_or_file = filedialog.askdirectory(
            title=title, initialdir=initialdir)
        #  Return filepath
        return self.selected_directory_or_file

    #  Set Tkinter's directory selection dialog box to given directory
    def set_directory_path(self,
                           title,
                           initialdir,
                           element,
                           append_directory=False):
        self.directory_path = self.get_directory_path(title, initialdir)
        element.configure(state="enabled")
        self.set_entrybox_text(element,
                               self.directory_path,
                               append_text=append_directory)
        element.configure(state="disabled")
        return

    #  Return filepath for the file
    def get_filepath_of_file(self, title, initialdir, filetypes):
        #  If file doesn't exist, continue prompting file selection
        self.title = title
        self.initialdir = initialdir
        self.filetypes = filetypes
        self.selected_file = filedialog.askopenfilename(title=title,
                                                        initialdir=initialdir,
                                                        filetypes=filetypes)

        return self.selected_file
示例#8
0
def youtube_dl_launcher_for_ffmpegaudioencoder():
    # Imports----------------------------------------------------------------------------------------------------------
    from tkinter import (filedialog, StringVar, Menu, E, W, N, S, LabelFrame,
                         NORMAL, END, DISABLED, Checkbutton, Label, ttk,
                         scrolledtext, messagebox, OptionMenu, Toplevel, WORD,
                         Entry, Button, HORIZONTAL, SUNKEN, Text)
    import pyperclip, pathlib, threading, yt_dlp
    from re import sub
    from configparser import ConfigParser

    global main

    # --------------------------------------------------------------------------------------------------------- Imports

    # Main Gui & Windows ----------------------------------------------------------------------------------------------
    def main_exit_function():  # Asks if the user is ready to exit
        confirm_exit = messagebox.askyesno(
            title='Prompt',
            message="Are you sure you want to exit the program?\n\n"
            "     Note: This will end all current tasks!",
            parent=main)
        if confirm_exit:  # If user selects Yes - destroy window
            main.destroy()

    # Main UI window --------------------------------------------------------------------------------------------------
    try:  # Checks rather or not the youtube-dl-gui window is already open
        if main is not None or Toplevel.winfo_exists(main):
            main.lift(
            )  # If youtube-dl-gui window exists then bring to top of all other windows

    except:  # If youtube-dl-gui does not exist, create it...
        if not combined_with_ffmpeg_audio_encoder:
            from tkinter import Tk, PhotoImage
            main = Tk()  # Make full tkinter loop if standalone
            main.iconphoto(
                True, PhotoImage(file="Runtime/Images/Youtube-DL-Gui.png"))
        if combined_with_ffmpeg_audio_encoder:
            main = Toplevel()  # Make toplevel loop if NOT standalone
        main.title("Simple-Youtube-DL-Gui v1.21")
        main.configure(background="#434547")
        window_height = 500
        window_width = 610
        screen_width = main.winfo_screenwidth()
        screen_height = main.winfo_screenheight()
        x_coordinate = int((screen_width / 2) - (window_width / 2))
        y_coordinate = int((screen_height / 2) - (window_height / 2))
        main.geometry(
            f"{window_width}x{window_height}+{x_coordinate}+{y_coordinate}")
        main.protocol('WM_DELETE_WINDOW', main_exit_function)

        for n in range(4):  # Loop to specify the needed column/row configures
            main.grid_columnconfigure(n, weight=1)
        for n in range(5):
            main.grid_rowconfigure(n, weight=1)

        # The entire top bar/menu is only present during standalone version -------------------------------------------
        if not combined_with_ffmpeg_audio_encoder:
            my_menu_bar = Menu(main, tearoff=0)
            main.config(menu=my_menu_bar)
            file_menu = Menu(my_menu_bar,
                             tearoff=0,
                             activebackground='dim grey')
            my_menu_bar.add_cascade(label='File', menu=file_menu)
            file_menu.add_command(
                label='Exit', command=main_exit_function)  # Exits the program
            options_menu = Menu(my_menu_bar,
                                tearoff=0,
                                activebackground='dim grey')
            my_menu_bar.add_cascade(label='Options', menu=options_menu)

            def set_ffmpeg_path():
                global ffmpeg
                path = filedialog.askopenfilename(
                    title='Select Location to "ffmpeg.exe"',
                    initialdir='/',
                    filetypes=[('ffmpeg', 'ffmpeg.exe')])
                if path == '':
                    pass
                elif path != '':
                    ffmpeg = str(pathlib.Path(path))
                    config.set('ffmpeg_path', 'path', ffmpeg)
                    with open(config_file, 'w') as configfile:
                        config.write(configfile)

            options_menu.add_command(label='Set path to FFMPEG',
                                     command=set_ffmpeg_path)

            options_menu.add_separator()

            def reset_config():
                msg = messagebox.askyesno(
                    title='Warning',
                    message=
                    'Are you sure you want to reset the config.ini file settings?'
                )
                if not msg:
                    pass
                if msg:
                    try:
                        config.set('ffmpeg_path', 'path', '')
                        with open(config_file, 'w') as configfile:
                            config.write(configfile)
                        messagebox.showinfo(
                            title='Prompt',
                            message='Please restart the program')
                    except:
                        pass
                    main.destroy()

            options_menu.add_command(label='Reset Configuration File',
                                     command=reset_config)

            from Packages.about import openaboutwindow

            def open_browser_for_ffmpeg():
                import webbrowser
                webbrowser.open_new_tab(
                    'https://www.gyan.dev/ffmpeg/builds/ffmpeg-git-essentials.7z'
                )

            help_menu = Menu(my_menu_bar,
                             tearoff=0,
                             activebackground="dim grey")
            my_menu_bar.add_cascade(label="Help", menu=help_menu)
            help_menu.add_command(label="Download FFMPEG",
                                  command=open_browser_for_ffmpeg)
            help_menu.add_separator()
            help_menu.add_command(label="About", command=openaboutwindow)
        # ------------------------------------------- The entire top bar/menu is only present during standalone version

        # Bundled Apps ------------------------------------------------------------------------------------------------
        config_file = 'Runtime/config.ini'  # Defines location of config.ini
        config = ConfigParser()
        config.read(config_file)

        # This creates the config file if on the standalone version ---------------------------------------------------
        if not combined_with_ffmpeg_audio_encoder:
            if not config.has_section(
                    'ffmpeg_path'):  # Create config parameters
                config.add_section('ffmpeg_path')
            if not config.has_option('ffmpeg_path', 'path'):
                config.set('ffmpeg_path', 'path', '')
            try:
                with open(config_file, 'w') as configfile:
                    config.write(configfile)
            except:
                messagebox.showinfo(
                    title='Error',
                    message=
                    'Could Not Write to config.ini file, delete and try again')
        # --------------------------------------------------- This creates the config file if on the standalone version

        # Define location of FFMPEG in a variable ---------------------------------------------------------------------
        ffmpeg = pathlib.Path(config['ffmpeg_path']['path'].replace('"', ''))
        # --------------------------------------------------------------------- Define location of FFMPEG in a variable

        # Code needed to add location of ffmpeg.exe in the event it's missing for standalone version ------------------
        if not combined_with_ffmpeg_audio_encoder:
            if not pathlib.Path(ffmpeg).is_file(
            ):  # Checks config for bundled app paths path ------------------------

                def check_ffmpeg(
                ):  # FFMPEG -------------------------------------------------------------------------
                    global ffmpeg
                    import shutil

                    def write_path_to_ffmpeg(
                    ):  # Writes path to ffmpeg to the config.ini file
                        try:
                            config.set('ffmpeg_path', 'path', ffmpeg)
                            with open(config_file, 'w') as configfile:
                                config.write(configfile)
                        except:
                            pass

                    if shutil.which('ffmpeg') is not None:
                        ffmpeg = str(pathlib.Path(
                            shutil.which('ffmpeg'))).lower()
                        messagebox.showinfo(
                            title='Prompt!',
                            message='ffmpeg.exe found on system PATH, '
                            'automatically setting path to location.\n\n'
                            'Note: This can be changed in the config.ini file'
                            ' or in the Options menu')
                        if pathlib.Path("Apps/ffmpeg/ffmpeg.exe").is_file():
                            rem_ffmpeg = messagebox.askyesno(
                                title='Delete Included ffmpeg?',
                                message=
                                'Would you like to delete the included FFMPEG?'
                            )
                            if rem_ffmpeg:
                                try:
                                    shutil.rmtree(
                                        str(pathlib.Path("Apps/ffmpeg")))
                                except:
                                    pass
                        write_path_to_ffmpeg()
                    elif pathlib.Path("Apps/ffmpeg/ffmpeg.exe").is_file():
                        messagebox.showinfo(
                            title='Info',
                            message='Program will use the included '
                            '"ffmpeg.exe" located in the "Apps" folder')
                        ffmpeg = str(pathlib.Path("Apps/ffmpeg/ffmpeg.exe"))
                        write_path_to_ffmpeg()
                    else:
                        error_prompt = messagebox.askyesno(
                            title='Error!',
                            message='Cannot find ffmpeg, '
                            'please navigate to "ffmpeg.exe"')
                        if not error_prompt:
                            messagebox.showerror(
                                title='Error!',
                                message=
                                'Program requires ffmpeg.exe to work correctly'
                            )
                            main.destroy()
                        if error_prompt:
                            set_ffmpeg_path()
                            if not pathlib.Path(ffmpeg).is_file():
                                messagebox.showerror(
                                    title='Error!',
                                    message=
                                    'Program requires ffmpeg.exe to work correctly'
                                )
                                main.destroy()

                check_ffmpeg(
                )  # FFMPEG ------------------------------------------------------------------------------
        # ------------------------------------------------------------------------------------------------ Bundled Apps
        # ------------------ Code needed to add location of ffmpeg.exe in the event it's missing for standalone version

        # Link Frame --------------------------------------------------------------------------------------------------
        link_frame = LabelFrame(main, text=' Paste Link ')
        link_frame.grid(row=0,
                        columnspan=4,
                        sticky=E + W,
                        padx=20,
                        pady=(10, 10))
        link_frame.configure(fg="white", bg="#434547", bd=3)

        link_frame.rowconfigure(1, weight=1)
        link_frame.columnconfigure(0, weight=1)
        link_frame.columnconfigure(1, weight=1)

        # -------------------------------------------------------------------------------------------------- Link Frame

        # Options Frame -----------------------------------------------------------------------------------------------
        options_frame = LabelFrame(main, text=' Options ')
        options_frame.grid(row=2,
                           columnspan=4,
                           sticky=E + W,
                           padx=20,
                           pady=(10, 10))
        options_frame.configure(fg="white", bg="#434547", bd=3)

        options_frame.rowconfigure(1, weight=1)
        options_frame.columnconfigure(0, weight=1)
        options_frame.columnconfigure(1, weight=1)

        # ----------------------------------------------------------------------------------------------- Options Frame

        # Input Frame -------------------------------------------------------------------------------------------------
        global link_input_label
        input_frame = LabelFrame(main, text=' Input ')
        input_frame.grid(row=1,
                         columnspan=4,
                         sticky=E + W,
                         padx=20,
                         pady=(4, 10))
        input_frame.configure(fg="white", bg="#434547", bd=3)
        input_frame.rowconfigure(1, weight=1)
        input_frame.columnconfigure(0, weight=1)
        input_frame.columnconfigure(1, weight=1)
        link_input_label = Label(
            input_frame,
            text='Please Paste Link Above and Select "Add Link"',
            background="#434547",
            foreground="white",
            height=1,
            font=("Helvetica", 10))
        link_input_label.grid(row=0,
                              column=0,
                              columnspan=4,
                              padx=8,
                              pady=(4, 7),
                              sticky=W + E)

        # ------------------------------------------------------------------------------------------------- Input Frame

        # File Output -------------------------------------------------------------------------------------------------
        def file_save():
            global VideoOutput
            save_entry.config(state=NORMAL)  #
            save_entry.delete(
                0, END
            )  # This function clears entry box in order to add new link to entry box
            save_entry.config(state=DISABLED)  #
            VideoOutput = filedialog.askdirectory(
                parent=main
            )  # Pop up window to choose a save directory location
            if VideoOutput:
                save_for_entry = '"' + VideoOutput + '/"'  # Completes save directory and adds quotes
                save_entry.config(state=NORMAL)  #
                save_entry.insert(
                    0, save_for_entry)  # Adds download_link to entry box
                save_entry.config(state=DISABLED)  #
                start_job_btn.config(state=NORMAL)  # Enables Button

        # ------------------------------------------------------------------------------------------------- File Output

        # Best Video Function -----------------------------------------------------------------------------------------
        def set_video_only():
            if video_only.get(
            ) == 'on':  # If video checkbutton is checked enable video options menu and set audio off
                highest_quality_audio_only.set('')
                video_menu_options_menu.config(state=NORMAL)
                audio_menu_options_menu.config(state=DISABLED)
                audio_menu_options.set('Extract Only')
            if video_only.get(
            ) != 'on':  # If not checked, set video_only to on
                video_only.set(
                    'on'
                )  # This prevents you from being able to de-select the check button

        # ----------------------------------------------------------------------------------------- Audio Only Function
        def highest_quality_audio_only_toggle():
            if highest_quality_audio_only.get(
            ) == 'on':  # If audio checkbutton is checked
                video_only.set(
                    '')  # enables video options menu and set audio to off
                video_menu_options_menu.config(state=DISABLED)
                audio_menu_options_menu.config(state=NORMAL)
            if highest_quality_audio_only.get(
            ) != 'on':  # If not checked, set audio_only to on
                highest_quality_audio_only.set(
                    'on'
                )  # This prevents you from being able to de-select the check button

        # Video Only Checkbutton --------------------------------------------------------------------------------------
        video_only = StringVar()
        video_only_checkbox = Checkbutton(
            options_frame,
            text='Best Video + Audio\nMuxed File',
            variable=video_only,
            onvalue='on',
            offvalue='',
            command=set_video_only,
            takefocus=False)
        video_only_checkbox.grid(row=0,
                                 column=1,
                                 columnspan=1,
                                 rowspan=1,
                                 padx=10,
                                 pady=6,
                                 sticky=N + S + E + W)
        video_only_checkbox.configure(background="#434547",
                                      foreground="white",
                                      activebackground="#434547",
                                      activeforeground="white",
                                      selectcolor="#434547",
                                      font=("Helvetica", 12))
        video_only.set('on')  # Enables Best Video by default

        # -------------------------------------------------------------------------------------- Video Only Checkbutton

        # Highest Quality Audio Only ----------------------------------------------------------------------------------
        highest_quality_audio_only = StringVar()
        highest_quality_audio_only_checkbox = Checkbutton(
            options_frame,
            text='Audio Only',
            variable=highest_quality_audio_only,
            onvalue='on',
            offvalue='',
            command=highest_quality_audio_only_toggle,
            takefocus=False)
        highest_quality_audio_only_checkbox.grid(row=0,
                                                 column=2,
                                                 columnspan=1,
                                                 rowspan=1,
                                                 padx=10,
                                                 pady=3,
                                                 sticky=N + S + E + W)
        highest_quality_audio_only_checkbox.configure(
            background="#434547",
            foreground="white",
            activebackground="#434547",
            activeforeground="white",
            selectcolor="#434547",
            font=("Helvetica", 12))
        highest_quality_audio_only.set('')  # Disables audio only by default

        # ---------------------------------------------------------------------------------- Highest Quality Audio Only

        # Download Rate -----------------------------------------------------------------------------------------------
        def download_rate_menu_hover(e):
            download_rate_menu["bg"] = "grey"
            download_rate_menu["activebackground"] = "grey"

        def download_rate_menu_hover_leave(e):
            download_rate_menu["bg"] = "#23272A"

        download_rate = StringVar(main)
        download_rate_choices = {
            'Unlimited': 131072000000000,
            '10 - KiB      (Slowest)': 1280,
            '50 - KiB': 6400,
            '100 - KiB': 12800,
            '250 - KiB': 32000,
            '500 - KiB': 64000,
            '750 - KiB': 96000,
            '1 - MiB': 131072,
            '5 - MiB': 655360,
            '10 - MiB': 1310720,
            '30 - MiB': 3932160,
            '50 - MiB': 6553600,
            '100 - MiB': 13107200,
            '250 - MiB': 32768000,
            '500 - MiB': 65536000,
            '750 - MiB': 98304000,
            '1000 - MiB  (Fastest)': 13107200000
        }
        download_rate_menu_label = Label(options_frame,
                                         text="Download Rate :",
                                         background="#434547",
                                         foreground="white")
        download_rate_menu_label.grid(row=0,
                                      column=0,
                                      columnspan=1,
                                      padx=10,
                                      pady=(3, 10),
                                      sticky=W + E)
        download_rate_menu = OptionMenu(options_frame, download_rate,
                                        *download_rate_choices.keys())
        download_rate_menu.config(background="#23272A",
                                  foreground="white",
                                  highlightthickness=1,
                                  width=15)
        download_rate_menu.grid(row=1,
                                column=0,
                                columnspan=1,
                                padx=10,
                                pady=(3, 20))
        download_rate.set('Unlimited')
        download_rate_menu["menu"].configure(activebackground="dim grey")
        download_rate_menu.bind("<Enter>", download_rate_menu_hover)
        download_rate_menu.bind("<Leave>", download_rate_menu_hover_leave)

        # ----------------------------------------------------------------------------------------------- Download Rate

        # Video Options -----------------------------------------------------------------------------------------------
        def video_menu_options_menu_hover(e):
            video_menu_options_menu["bg"] = "grey"
            video_menu_options_menu["activebackground"] = "grey"

        def video_menu_options_menu_hover_leave(e):
            video_menu_options_menu["bg"] = "#23272A"

        video_menu_options = StringVar(main)
        video_menu_options_choices = {
            '(bv+ba/b) Best video + audio format '
            'and combine both, or download best combined format':
            'bv+ba/b',
            '(Same as above with video up to 480p)':
            'bv*[height<=480]+ba/b[height<=480] / wv*+ba/w',
            '(Same as above with video up to 720p)':
            'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w',
            '(Same as above with video up to 1080p)':
            'bv*[height<=1080]+ba/b[height<=1080] / wv*+ba/w',
            '(Same as above with video up to 1440p)':
            'bv*[height<=1440]+ba/b[height<=1440] / wv*+ba/w',
            '(Same as above with video up to 2160p)':
            'bv*[height<=2160]+ba/b[height<=2160] / wv*+ba/w',
            '(Default) (bv*+ba/b) Best video and if missing audio, '
            'merge it with best available audio':
            'bv*+ba/b',
            '(bv) Best video only':
            'bv',
            'Download the best h264 video, '
            'or best video if no such codec':
            '(bv * +ba / b)[vcodec ^= avc1] / (bv * +ba / b)'
        }
        video_menu_options_menu = OptionMenu(
            options_frame, video_menu_options,
            *video_menu_options_choices.keys())
        video_menu_options_menu.config(background="#23272A",
                                       foreground="white",
                                       highlightthickness=1,
                                       width=15,
                                       anchor=W)
        video_menu_options_menu.grid(row=1,
                                     column=1,
                                     columnspan=1,
                                     padx=10,
                                     pady=(3, 20))
        video_menu_options.set(
            '(Default) (bv*+ba/b) Best video and if missing audio, '
            'merge it with best available audio')
        video_menu_options_menu["menu"].configure(activebackground="dim grey")
        video_menu_options_menu.bind("<Enter>", video_menu_options_menu_hover)
        video_menu_options_menu.bind("<Leave>",
                                     video_menu_options_menu_hover_leave)

        # ----------------------------------------------------------------------------------------------- Video Options

        # Audio Options -----------------------------------------------------------------------------------------------
        def audio_menu_options_menu_hover(e):
            audio_menu_options_menu["bg"] = "grey"
            audio_menu_options_menu["activebackground"] = "grey"

        def audio_menu_options_menu_hover_leave(e):
            audio_menu_options_menu["bg"] = "#23272A"

        audio_menu_options = StringVar(main)
        audio_menu_options_choices = {
            'Extract Only': '',
            'Encode to mp3': 'mp3',
            'Encode to flac': 'flac',
            'Encode to m4a': 'm4a',
            'Encode to opus': 'opus',
            'Encode to vorbis': 'vorbis',
            'Encode to wav': 'wav'
        }
        audio_menu_options_menu = OptionMenu(
            options_frame, audio_menu_options,
            *audio_menu_options_choices.keys())
        audio_menu_options_menu.config(background="#23272A",
                                       foreground="white",
                                       highlightthickness=1,
                                       width=15,
                                       anchor=W,
                                       state=DISABLED)
        audio_menu_options_menu.grid(row=1,
                                     column=2,
                                     columnspan=1,
                                     padx=10,
                                     pady=(3, 20))
        audio_menu_options.set('Extract Only')
        audio_menu_options_menu["menu"].configure(activebackground="dim grey")
        audio_menu_options_menu.bind("<Enter>", audio_menu_options_menu_hover)
        audio_menu_options_menu.bind("<Leave>",
                                     audio_menu_options_menu_hover_leave)

        # ----------------------------------------------------------------------------------------------- Audio Options

        # Add Link to variable ----------------------------------------------------------------------------------------
        def apply_link():
            global download_link, link_input_label, extracted_title_name
            link_entry.config(state=NORMAL)  #
            link_entry.delete(
                0, END
            )  # This function clears entry box in order to add new link to entry box
            link_entry.config(state=DISABLED)  #
            download_link = text_area.get(1.0, END).rstrip(
                "\n")  # Pasted download link and strips the unneeded newline
            text_area.delete(
                1.0, END
            )  # Deletes entry box where you pasted your link as it stores it into var
            link_entry.config(state=NORMAL)  #
            link_entry.insert(0,
                              download_link)  # Adds download_link to entry box
            link_entry.config(state=DISABLED)  #
            save_btn.config(state=NORMAL)  #
            try:  # The code below checks link input for the title and adds it to a variable for use with the gui
                with yt_dlp.YoutubeDL({'noplaylist': True}) as ydl:
                    dl_link_input = ydl.extract_info(download_link,
                                                     download=False)
                    string_one = sub('[^a-zA-Z0-9 \n]', '',
                                     dl_link_input['title'])
                    string_two = " ".join(string_one.split())
                    extracted_title_name = pathlib.Path(
                        string_two[:128]).with_suffix('')
            except:
                extracted_title_name = download_link
            link_input_label.configure(text=extracted_title_name)

        # ---------------------------------------------------------------------------------------------------- Add Link

        # Start Job ---------------------------------------------------------------------------------------------------
        def start_job(
        ):  # This is the progress window and everything that has to do with actually processing the file
            global download_link

            def close_encode():
                confirm_exit = messagebox.askyesno(
                    title='Prompt',
                    message="Are you sure you want to stop progress?",
                    parent=window)
                if confirm_exit:  # If user selects 'Yes' to the above message prompt, destroy the window in question
                    window.destroy()

            def close_window(
            ):  # This thread is needed in order to close the window while the GUI is processing a file
                thread = threading.Thread(target=close_encode)
                thread.start()

            window = Toplevel(main)  # Programs download window
            window.title(
                extracted_title_name
            )  # Takes extracted_title_name and adds it as the windows title
            window.configure(background='#434547')
            encode_label = Label(window,
                                 text='- ' * 22 + 'Progress ' + '- ' * 22,
                                 font=('Times New Roman', 14),
                                 background='#434547',
                                 foreground='white')
            encode_label.grid(column=0, columnspan=2, row=0)
            window.grid_columnconfigure(0, weight=1)
            window.grid_rowconfigure(0, weight=1)
            window.grid_rowconfigure(1, weight=1)
            window.protocol('WM_DELETE_WINDOW', close_window)
            window.geometry('600x140')
            encode_window_progress = Text(window,
                                          height=2,
                                          relief=SUNKEN,
                                          bd=3)
            encode_window_progress.grid(row=1,
                                        column=0,
                                        columnspan=2,
                                        pady=(10, 6),
                                        padx=10,
                                        sticky=E + W)
            encode_window_progress.insert(END, '')
            app_progress_bar = ttk.Progressbar(window,
                                               orient=HORIZONTAL,
                                               mode='determinate')
            app_progress_bar.grid(row=2,
                                  columnspan=2,
                                  pady=(10, 10),
                                  padx=15,
                                  sticky=E + W)

            def my_hook(
                d
            ):  # This updates the progress bar with the correct percentage
                if d['status'] == 'downloading':
                    p = d['_percent_str']
                    p = p.replace('%', '')
                    app_progress_bar['value'] = float(p)

            class MyLogger:  # ytb-dl logger, allows the program to get all the needed info from the program
                global download_info_string

                def debug(self, msg):
                    # For compatability with youtube-dl, both debug and info are passed into debug
                    # You can distinguish them by the prefix '[debug] '
                    if msg.startswith('[debug] '):
                        pass
                    else:
                        self.info(msg)

                def info(self, msg):
                    encode_window_progress.delete('1.0', END)
                    encode_window_progress.insert(END, msg)

                def warning(self, msg):
                    pass

                def error(self, msg):
                    pass

            if video_only.get(
            ) == 'on':  # If "Best Video..." is selected then use these options for ytb-dl
                ydl_opts = {
                    'ratelimit': download_rate_choices[download_rate.get()],
                    'progress_hooks': [my_hook],
                    'noplaylist': True,
                    'overwrites': True,
                    'merge_output_format': 'mkv',
                    'final_ext': 'mkv',
                    'outtmpl':
                    str(pathlib.Path(VideoOutput)) + '/%(title)s.%(ext)s',
                    'ffmpeg_location': str(pathlib.Path(ffmpeg)),
                    'logger': MyLogger(),
                    "progress_with_newline": True,
                    'format':
                    video_menu_options_choices[video_menu_options.get()],
                    'prefer_ffmpeg': True
                }

            if video_only.get() != 'on' and audio_menu_options.get(
            ) == 'Extract Only':
                # If "Best Video..." is NOT selected and "Audio Menu" is set to Extract Only
                ydl_opts = {
                    'ratelimit': download_rate_choices[download_rate.get()],
                    'progress_hooks': [my_hook],
                    'noplaylist': True,
                    'overwrites': True,
                    'outtmpl':
                    str(pathlib.Path(VideoOutput)) + '/%(title)s.%(ext)s',
                    'ffmpeg_location': str(pathlib.Path(ffmpeg)),
                    'logger': MyLogger(),
                    "progress_with_newline": True,
                    'format': 'bestaudio/best',
                    'extractaudio': True,
                    'prefer_ffmpeg': True
                }

            if video_only.get() != 'on' and audio_menu_options.get(
            ) != 'Extract Only':
                # If "Best Video..." is NOT selected and "Audio Menu" is set to encode to another codec
                ydl_opts = {
                    'ratelimit':
                    download_rate_choices[download_rate.get()],
                    'progress_hooks': [my_hook],
                    'noplaylist':
                    True,
                    'overwrites':
                    True,
                    'outtmpl':
                    str(pathlib.Path(VideoOutput)) + '/%(title)s.%(ext)s',
                    'ffmpeg_location':
                    str(pathlib.Path(ffmpeg)),
                    'logger':
                    MyLogger(),
                    "progress_with_newline":
                    True,
                    'format':
                    'bestaudio/best',
                    'extractaudio':
                    True,
                    'prefer_ffmpeg':
                    True,
                    'postprocessors': [{
                        'key':
                        'FFmpegExtractAudio',
                        'preferredcodec':
                        audio_menu_options_choices[audio_menu_options.get()],
                        'preferredquality':
                        '0'
                    }]
                }

            with yt_dlp.YoutubeDL(
                    ydl_opts
            ) as ydl:  # Block of code needed to process the link/file
                ydl.download([download_link])

            window.destroy(
            )  # Once the job is complete this destroys the download/processing window

        # --------------------------------------------------------------------------------------------------- Start Job

        # Buttons and Entry Box's -------------------------------------------------------------------------------------
        text_area = scrolledtext.ScrolledText(link_frame,
                                              wrap=WORD,
                                              width=69,
                                              height=1,
                                              font=("Times New Roman", 14),
                                              foreground="grey")
        text_area.insert(END, "Right Click or 'Ctrl + V'")
        text_area.grid(row=0,
                       column=0,
                       columnspan=3,
                       pady=(1, 5),
                       padx=10,
                       sticky=W + E)

        # ------------------------------------------------------------------ Right click menu to paste in text_area box
        def paste_clipboard(
        ):  # Allows user to paste what ever is in their clipboard with right click and paste
            text_area.delete(1.0, END)
            text_area.config(foreground="black")
            text_area.insert(END, pyperclip.paste())

        def remove_text(
                e):  # Deletes current text in text box upon 'Left Clicking'
            text_area.config(foreground="black")
            text_area.delete(1.0, END)
            link_input_label.configure(
                text='Please Paste Link Above and Select "Add Link"')
            link_entry.config(state=NORMAL)  #
            link_entry.delete(
                0, END
            )  # This function clears entry box in order to add new link to entry box
            link_entry.config(state=DISABLED)  #

        m = Menu(main, tearoff=0)  # Pop up menu for 'Paste'
        m.add_command(label="Paste", command=paste_clipboard)

        def do_popup(
            event
        ):  # This code allows the program to know where the cursor is upon right clicking
            try:
                m.tk_popup(event.x_root, event.y_root)
            finally:
                m.grab_release()

        text_area.bind("<Button-3>",
                       do_popup)  # Uses right click to make a function
        text_area.bind("<Button-1>",
                       remove_text)  # Uses left click to make a function
        # Right click menu to paste in text_area box ------------------------------------------------------------------

        link_entry = Entry(link_frame,
                           borderwidth=4,
                           background="#CACACA",
                           state=DISABLED,
                           width=70)
        link_entry.grid(row=1,
                        column=1,
                        columnspan=2,
                        padx=10,
                        pady=(0, 0),
                        sticky=W + E)

        def apply_btn_hover(e):
            apply_btn["bg"] = "grey"

        def apply_btn_hover_leave(e):
            apply_btn["bg"] = "#8b0000"

        apply_btn = Button(link_frame,
                           text="Add Link",
                           command=apply_link,
                           foreground="white",
                           background="#8b0000",
                           width=30)
        apply_btn.grid(row=1,
                       column=0,
                       columnspan=1,
                       padx=10,
                       pady=5,
                       sticky=W)
        apply_btn.bind("<Enter>", apply_btn_hover)
        apply_btn.bind("<Leave>", apply_btn_hover_leave)

        def save_btn_hover(e):
            save_btn["bg"] = "grey"

        def save_btn_hover_leave(e):
            save_btn["bg"] = "#8b0000"

        save_btn = Button(main,
                          text="Save Directory",
                          command=file_save,
                          foreground="white",
                          background="#8b0000",
                          state=DISABLED)
        save_btn.grid(row=4,
                      column=0,
                      columnspan=1,
                      padx=10,
                      pady=(15, 0),
                      sticky=W + E)
        save_btn.bind("<Enter>", save_btn_hover)
        save_btn.bind("<Leave>", save_btn_hover_leave)

        save_entry = Entry(main,
                           borderwidth=4,
                           background="#CACACA",
                           state=DISABLED)
        save_entry.grid(row=4,
                        column=1,
                        columnspan=3,
                        padx=10,
                        pady=(15, 0),
                        sticky=W + E)

        def start_job_btn_hover(e):
            start_job_btn["bg"] = "grey"

        def start_job_btn_hover_leave(e):
            start_job_btn["bg"] = "#8b0000"

        start_job_btn = Button(
            main,
            text="Start Job",
            command=lambda: threading.Thread(target=start_job).start(),
            foreground="white",
            background="#8b0000",
            state=DISABLED)
        start_job_btn.grid(row=5,
                           column=3,
                           columnspan=1,
                           padx=10,
                           pady=(15, 15),
                           sticky=N + S + W + E)
        start_job_btn.bind("<Enter>", start_job_btn_hover)
        start_job_btn.bind("<Leave>", start_job_btn_hover_leave)

        # ------------------------------------------------------------------------------------- Buttons and Entry Box's

        # End Loop ----------------------------------------------------------------------------------------------------
        main.mainloop()
示例#9
0
def open_general_settings():  # General Settings Window
    global general_settings_window

    try:  # Check if window is already open, if it's open break from function
        if general_settings_window.winfo_exists():
            return
    except NameError:
        pass

    def general_settings_exit_function(
    ):  # Exit function when hitting the 'X' button
        general_parser = ConfigParser()
        general_parser.read(config_file)
        if general_parser['save_window_locations'][
                'general settings'] == 'yes':  # If auto save position on
            try:
                if general_parser['save_window_locations']['general settings position'] != \
                        general_settings_window.geometry():
                    general_parser.set('save_window_locations',
                                       'general settings position',
                                       general_settings_window.geometry())
                    with open(config_file, 'w') as generalfile:
                        general_parser.write(generalfile)
            except (Exception, ):
                pass
        general_settings_window.grab_release()  # Release grab on window
        general_settings_window.destroy()  # Close window

    # Config Parser
    config_file = 'Runtime/config.ini'
    config_parser = ConfigParser()
    config_parser.read(config_file)
    # Config Parser

    general_settings_window = Toplevel()  # Define toplevel()
    general_settings_window.title('General Settings')
    detect_font = font.nametofont(
        "TkDefaultFont")  # Get default font value into Font object
    set_font = detect_font.actual().get("family")
    color1 = "#434547"
    general_settings_window.configure(background=color1)
    if config_parser['save_window_locations']['general settings position'] == '' or \
            config_parser['save_window_locations']['general settings'] == 'no':
        window_height = 670
        window_width = 640
        screen_width = general_settings_window.winfo_screenwidth()
        screen_height = general_settings_window.winfo_screenheight()
        x_coordinate = int((screen_width / 2) - (window_width / 2))
        y_coordinate = int((screen_height / 2) - (window_height / 2))
        general_settings_window.geometry(
            f"{window_width}x{window_height}+{x_coordinate}+{y_coordinate}")
    elif config_parser['save_window_locations']['general settings position'] != '' and \
            config_parser['save_window_locations']['general settings'] == 'yes':
        general_settings_window.geometry(config_parser['save_window_locations']
                                         ['general settings position'])
    general_settings_window.protocol('WM_DELETE_WINDOW',
                                     general_settings_exit_function)
    general_settings_window.grab_set(
    )  # Focus all of tkinters attention on this window only

    general_settings_window.rowconfigure(0, weight=1)
    general_settings_window.grid_columnconfigure(0, weight=1)

    # Themes ----------------------------------------------------------------------------------------------------------
    # Hover over button theme ---------------------------------------
    class HoverButton(Button):
        def __init__(self, master, **kw):
            Button.__init__(self, master=master, **kw)
            self.defaultBackground = self["background"]
            self.bind("<Enter>", self.on_enter)
            self.bind("<Leave>", self.on_leave)

        def on_enter(self, _):
            self['background'] = self['activebackground']

        def on_leave(self, _):
            self['background'] = self.defaultBackground

    # --------------------------------------- Hover over button theme
    # Settings Notebook Frame -----------------------------------------------------------------------------------------
    tabs = ttk.Notebook(general_settings_window)
    tabs.grid(row=0,
              column=0,
              columnspan=4,
              sticky=E + W + N + S,
              padx=0,
              pady=0)
    settings_tab = Frame(tabs, background="#434547")
    tabs.add(settings_tab, text=' Paths ')

    for n in range(4):
        settings_tab.grid_columnconfigure(n, weight=1)
    for n in range(2):
        settings_tab.grid_rowconfigure(n, weight=1)

    # ----------------------------------------------------------------------------------------  Settings Notebook Frame
    # ---------------------------------------------------------------------------------------------------------- Themes

    path_frame = LabelFrame(settings_tab, text=' Tool Paths ', labelanchor="n")
    path_frame.grid(column=0,
                    row=0,
                    columnspan=4,
                    padx=5,
                    pady=(10, 3),
                    sticky=N + S + E + W)
    path_frame.configure(fg="#3498db",
                         bg="#434547",
                         bd=3,
                         font=(set_font, 10, "bold"))
    for p_f in range(5):
        path_frame.grid_rowconfigure(p_f, weight=1)
    for p_f in range(4):
        path_frame.grid_columnconfigure(p_f, weight=1)

    # FFMPEG Path -----------------------------------------------------------------------------------------------------
    ffmpeg_frame = LabelFrame(path_frame, text=' FFMPEG ', labelanchor="nw")
    ffmpeg_frame.grid(column=0,
                      row=0,
                      columnspan=4,
                      padx=5,
                      pady=(5, 3),
                      sticky=E + W)
    ffmpeg_frame.configure(fg="#3498db",
                           bg="#434547",
                           bd=3,
                           font=(set_font, 9, "italic"))
    ffmpeg_frame.grid_rowconfigure(0, weight=1)
    ffmpeg_frame.grid_columnconfigure(0, weight=1)
    ffmpeg_frame.grid_columnconfigure(1, weight=20)

    def set_ffmpeg_path():
        path = filedialog.askopenfilename(
            title='Select Location to "ffmpeg.exe"',
            initialdir=pathlib.Path(ffmpeg_entry_box.get()).parent,
            filetypes=[('ffmpeg', 'ffmpeg.exe')],
            parent=general_settings_window)
        if path:
            ffmpeg_parser = ConfigParser()
            ffmpeg_parser.read(config_file)
            ffmpeg = f'"{str(pathlib.Path(path))}"'
            ffmpeg_parser.set('ffmpeg_path', 'path', ffmpeg)
            with open(config_file, 'w') as ffmpeg_configfile:
                ffmpeg_parser.write(ffmpeg_configfile)
            ffmpeg_entry_box.config(state=NORMAL)
            ffmpeg_entry_box.delete(0, END)
            ffmpeg_entry_box.insert(
                0,
                str(
                    pathlib.Path(
                        str(ffmpeg_parser['ffmpeg_path']['path']).replace(
                            '"', '')).resolve()))
            ffmpeg_entry_box.config(state=DISABLED)

    set_ffmpeg_path = HoverButton(ffmpeg_frame,
                                  text="Set Path",
                                  command=set_ffmpeg_path,
                                  foreground="white",
                                  background="#23272A",
                                  borderwidth="3",
                                  activebackground='grey')
    set_ffmpeg_path.grid(row=0,
                         column=0,
                         columnspan=1,
                         padx=5,
                         pady=5,
                         sticky=N + S + E + W)

    saved_ffmpeg_path = pathlib.Path(
        str(config_parser['ffmpeg_path']['path']).replace('"', '')).resolve()
    ffmpeg_entry_box = Entry(ffmpeg_frame, borderwidth=4, background="#CACACA")
    ffmpeg_entry_box.grid(row=0,
                          column=1,
                          columnspan=3,
                          padx=5,
                          pady=5,
                          sticky=N + S + E + W)
    ffmpeg_entry_box.insert(0, str(saved_ffmpeg_path))
    ffmpeg_entry_box.config(state=DISABLED)

    # MPV Path --------------------------------------------------------------------------------------------------------
    mpv_frame = LabelFrame(path_frame, text=' MPV ', labelanchor="nw")
    mpv_frame.grid(column=0,
                   row=1,
                   columnspan=4,
                   padx=5,
                   pady=(5, 3),
                   sticky=E + W)
    mpv_frame.configure(fg="#3498db",
                        bg="#434547",
                        bd=3,
                        font=(set_font, 9, "italic"))
    mpv_frame.grid_rowconfigure(0, weight=1)
    mpv_frame.grid_columnconfigure(0, weight=1)
    mpv_frame.grid_columnconfigure(1, weight=20)

    def set_mpv_path():
        path = filedialog.askopenfilename(title='Select Location to "mpv.exe"',
                                          initialdir=pathlib.Path(
                                              mpv_entry_box.get()).parent,
                                          filetypes=[('mpv', 'mpv.exe')],
                                          parent=general_settings_window)
        if path:
            mpv_cfg_parser = ConfigParser()
            mpv_cfg_parser.read(config_file)
            mpv = f'"{str(pathlib.Path(path))}"'
            mpv_cfg_parser.set('mpv_player_path', 'path', mpv)
            with open(config_file, 'w') as mpv_cfg:
                mpv_cfg_parser.write(mpv_cfg)
            mpv_entry_box.config(state=NORMAL)
            mpv_entry_box.delete(0, END)
            mpv_entry_box.insert(
                0,
                str(
                    pathlib.Path(
                        str(mpv_cfg_parser['mpv_player_path']['path']).replace(
                            '"', '')).resolve()))
            mpv_entry_box.config(state=DISABLED)

    set_mpv_path = HoverButton(mpv_frame,
                               text="Set Path",
                               command=set_mpv_path,
                               foreground="white",
                               background="#23272A",
                               borderwidth="3",
                               activebackground='grey')
    set_mpv_path.grid(row=0,
                      column=0,
                      columnspan=1,
                      padx=5,
                      pady=5,
                      sticky=N + S + E + W)

    saved_mpv_path = pathlib.Path(
        str(config_parser['mpv_player_path']['path']).replace('"',
                                                              '')).resolve()
    mpv_entry_box = Entry(mpv_frame, borderwidth=4, background="#CACACA")
    mpv_entry_box.grid(row=0,
                       column=1,
                       columnspan=3,
                       padx=5,
                       pady=5,
                       sticky=N + S + E + W)
    mpv_entry_box.insert(0, str(saved_mpv_path))
    mpv_entry_box.config(state=DISABLED)

    # Media Info Gui Path ---------------------------------------------------------------------------------------------
    mediainfogui_frame = LabelFrame(path_frame,
                                    text=' MediaInfo GUI ',
                                    labelanchor="nw")
    mediainfogui_frame.grid(column=0,
                            row=2,
                            columnspan=4,
                            padx=5,
                            pady=(5, 3),
                            sticky=E + W)
    mediainfogui_frame.configure(fg="#3498db",
                                 bg="#434547",
                                 bd=3,
                                 font=(set_font, 9, "italic"))
    mediainfogui_frame.grid_rowconfigure(0, weight=1)
    mediainfogui_frame.grid_columnconfigure(0, weight=1)
    mediainfogui_frame.grid_columnconfigure(1, weight=20)

    def set_mediainfogui_path():
        path = filedialog.askopenfilename(
            title='Select Location to "mediainfo.exe"',
            initialdir=pathlib.Path(mediainfogui_entry_box.get()).parent,
            filetypes=[('mediainfo', 'mediainfo.exe')],
            parent=general_settings_window)
        if path:
            mediainfo_cfg_parser = ConfigParser()
            mediainfo_cfg_parser.read(config_file)
            mediainfogui = f'"{str(pathlib.Path(path))}"'
            mediainfo_cfg_parser.set('mediainfogui_path', 'path', mediainfogui)
            with open(config_file, 'w') as mediainfo_cfg:
                mediainfo_cfg_parser.write(mediainfo_cfg)
            mediainfogui_entry_box.config(state=NORMAL)
            mediainfogui_entry_box.delete(0, END)
            mediainfogui_entry_box.insert(
                0,
                str(
                    pathlib.Path(
                        str(mediainfo_cfg_parser['mediainfogui_path']
                            ['path']).replace('"', '')).resolve()))
            mediainfogui_entry_box.config(state=DISABLED)

    set_mediainfogui_path = HoverButton(mediainfogui_frame,
                                        text="Set Path",
                                        command=set_mediainfogui_path,
                                        foreground="white",
                                        background="#23272A",
                                        borderwidth="3",
                                        activebackground='grey')
    set_mediainfogui_path.grid(row=0,
                               column=0,
                               columnspan=1,
                               padx=5,
                               pady=5,
                               sticky=N + S + E + W)

    saved_mediainfogui_path = pathlib.Path(
        str(config_parser['mediainfogui_path']['path']).replace('"',
                                                                '')).resolve()
    mediainfogui_entry_box = Entry(mediainfogui_frame,
                                   borderwidth=4,
                                   background="#CACACA")
    mediainfogui_entry_box.grid(row=0,
                                column=1,
                                columnspan=3,
                                padx=5,
                                pady=5,
                                sticky=N + S + E + W)
    mediainfogui_entry_box.insert(0, str(saved_mediainfogui_path))
    mediainfogui_entry_box.config(state=DISABLED)

    # FDK-AAC Path ----------------------------------------------------------------------------------------------------
    fdkaac_frame = LabelFrame(path_frame, text=' FDK-AAC ', labelanchor="nw")
    fdkaac_frame.grid(column=0,
                      row=3,
                      columnspan=4,
                      padx=5,
                      pady=(5, 3),
                      sticky=E + W)
    fdkaac_frame.configure(fg="#3498db",
                           bg="#434547",
                           bd=3,
                           font=(set_font, 9, "italic"))
    fdkaac_frame.grid_rowconfigure(0, weight=1)
    fdkaac_frame.grid_columnconfigure(0, weight=1)
    fdkaac_frame.grid_columnconfigure(1, weight=20)
    saved_fdkaac_path = None

    def set_fdk_aac_path():
        path = filedialog.askopenfilename(
            title='Select Location to "fdkaac.exe"',
            initialdir=pathlib.Path(fdkaac_entry_box.get()).parent,
            filetypes=[('FDK-AAC', 'fdkaac.exe')],
            parent=general_settings_window)
        if path:
            fdk_parser = ConfigParser()
            fdk_parser.read(config_file)
            fdkaac = f'"{str(pathlib.Path(path))}"'
            fdk_parser.set('fdkaac_path', 'path', fdkaac)
            with open(config_file, 'w') as fdk_cfg:
                fdk_parser.write(fdk_cfg)
            fdkaac_entry_box.config(state=NORMAL)
            fdkaac_entry_box.delete(0, END)
            fdkaac_entry_box.insert(
                0,
                str(
                    pathlib.Path(
                        str(fdk_parser['fdkaac_path']['path']).replace(
                            '"', '')).resolve()))
            fdkaac_entry_box.config(state=DISABLED)

    set_fdkaac_path = HoverButton(fdkaac_frame,
                                  text="Set Path",
                                  command=set_fdk_aac_path,
                                  foreground="white",
                                  background="#23272A",
                                  borderwidth="3",
                                  activebackground='grey')
    set_fdkaac_path.grid(row=0,
                         column=0,
                         columnspan=1,
                         padx=5,
                         pady=5,
                         sticky=N + S + E + W)

    if config_parser['fdkaac_path']['path'] == '':
        saved_fdkaac_path = 'not installed'.title()
    elif config_parser['fdkaac_path']['path'] != '':
        if pathlib.Path(
                str(config_parser['fdkaac_path']['path']).replace(
                    '"', '')).exists():
            saved_fdkaac_path = '"' + str(
                pathlib.Path(
                    str(config_parser['fdkaac_path']['path']).replace(
                        '"', '')).resolve()) + '"'
        else:
            saved_fdkaac_path = 'not installed'.title()
            func_parser = ConfigParser()
            func_parser.read(config_file)
            func_parser.set('fdkaac_path', 'path', '')
            with open(config_file, 'w') as configfile:
                func_parser.write(configfile)

    fdkaac_entry_box = Entry(fdkaac_frame, borderwidth=4, background="#CACACA")
    fdkaac_entry_box.grid(row=0,
                          column=1,
                          columnspan=3,
                          padx=5,
                          pady=5,
                          sticky=N + S + E + W)
    fdkaac_entry_box.insert(0, str(saved_fdkaac_path).replace('"', ''))
    fdkaac_entry_box.config(state=DISABLED)

    # QAAC Path -------------------------------------------------------------------------------------------------------
    qaac_frame = LabelFrame(path_frame, text=' QAAC ', labelanchor="nw")
    qaac_frame.grid(column=0,
                    row=4,
                    columnspan=4,
                    padx=5,
                    pady=(5, 3),
                    sticky=E + W)
    qaac_frame.configure(fg="#3498db",
                         bg="#434547",
                         bd=3,
                         font=(set_font, 9, "italic"))
    qaac_frame.grid_rowconfigure(0, weight=1)
    qaac_frame.grid_rowconfigure(1, weight=1)
    for q_f in range(4):
        qaac_frame.grid_columnconfigure(q_f, weight=1)
    saved_qaac_path = None

    def set_qaac_path():
        path = filedialog.askopenfilename(
            title='Select Location to "qaac64.exe"',
            initialdir=pathlib.Path(qaac_entry_box.get()).parent,
            filetypes=[('qaac64', 'qaac64.exe')],
            parent=general_settings_window)
        if path:
            qaac_parser = ConfigParser()
            qaac_parser.read(config_file)
            qaac = f'"{str(pathlib.Path(path))}"'
            qaac_parser.set('qaac_path', 'path', qaac)
            with open(config_file, 'w') as qaac_cfg:
                qaac_parser.write(qaac_cfg)
            qt_folder_path = pathlib.Path(
                pathlib.Path(
                    str(qaac_parser['qaac_path']['path']).replace(
                        '"', '')).resolve().parent / 'QTfiles64')
            qaac_parser.set('qaac_path', 'qt_path', f'"{str(qt_folder_path)}"')
            with open(config_file, 'w') as qaac_cfg:
                qaac_parser.write(qaac_cfg)
            qaac_entry_box.config(state=NORMAL)
            qaac_entry_box.delete(0, END)
            qaac_entry_box.insert(
                0,
                str(
                    pathlib.Path(
                        str(qaac_parser['qaac_path']['path']).replace(
                            '"', '')).resolve()))
            qaac_entry_box.config(state=DISABLED)

            update_qaac_file_paths()

    set_qaac_path = HoverButton(qaac_frame,
                                text="Set Path",
                                command=set_qaac_path,
                                foreground="white",
                                background="#23272A",
                                borderwidth="3",
                                activebackground='grey')
    set_qaac_path.grid(row=0,
                       column=0,
                       columnspan=1,
                       padx=5,
                       pady=5,
                       sticky=N + S + E + W)

    if config_parser['qaac_path']['path'] == '':
        saved_qaac_path = 'not installed'.title()
    elif config_parser['qaac_path']['path'] != '':
        if pathlib.Path(
                str(config_parser['qaac_path']['path']).replace('"',
                                                                '')).exists():
            saved_qaac_path = '"' + str(
                pathlib.Path(
                    str(config_parser['qaac_path']['path']).replace(
                        '"', '')).resolve()) + '"'
        else:
            saved_qaac_path = 'not installed'.title()
            func_parser = ConfigParser()
            func_parser.read(config_file)
            func_parser.set('qaac_path', 'path', '')
            with open(config_file, 'w') as configfile:
                func_parser.write(configfile)

    qaac_entry_box = Entry(qaac_frame, borderwidth=4, background="#CACACA")
    qaac_entry_box.grid(row=0,
                        column=1,
                        columnspan=3,
                        padx=5,
                        pady=5,
                        sticky=N + S + E + W)
    qaac_entry_box.insert(0, str(saved_qaac_path).replace('"', ''))
    qaac_entry_box.config(state=DISABLED)

    def update_qaac_file_paths():
        global qt_folder, list_of_qaac_files
        update_parser = ConfigParser()
        update_parser.read(config_file)

        if update_parser['qaac_path'][
                'path'] == '':  # if path to qaac is empty
            qt_folder = pathlib.Path(pathlib.Path.cwd() / 'Apps' / 'qaac' /
                                     'QTfiles64')
        elif update_parser['qaac_path'][
                'path'] != '':  # if path to qaac is not empty
            qt_folder = pathlib.Path(
                pathlib.Path(
                    str(update_parser['qaac_path']['path']).replace(
                        '"', '')).resolve().parent / 'QTfiles64')

        pathlib.Path(qt_folder).mkdir(parents=True, exist_ok=True)

        list_of_qaac_files = [
            pathlib.Path(qt_folder / 'ASL.dll'),
            pathlib.Path(qt_folder / 'CoreAudioToolbox.dll'),
            pathlib.Path(qt_folder / 'CoreFoundation.dll'),
            pathlib.Path(qt_folder / 'icudt62.dll'),
            pathlib.Path(qt_folder / 'libdispatch.dll'),
            pathlib.Path(qt_folder / 'libicuin.dll'),
            pathlib.Path(qt_folder / 'libicuuc.dll'),
            pathlib.Path(qt_folder / 'objc.dll')
        ]

    update_qaac_file_paths()

    def check_for_qaac_files():
        global list_of_qaac_files
        checked_qaac_files = []
        for files in list_of_qaac_files:
            checked_qaac_files.append(pathlib.Path(files).is_file())

        if all(checked_qaac_files):
            qaac_status_label.config(text='Status: Ready')
        else:
            qaac_status_label.config(text='Status: Missing QTFiles')

        general_settings_window.after(1000, check_for_qaac_files)

    qaac_status_label = Label(qaac_frame,
                              text="",
                              background="#434547",
                              foreground="white",
                              width=10)
    qaac_status_label.grid(row=1,
                           column=0,
                           columnspan=2,
                           padx=(5, 5),
                           pady=(2, 0),
                           sticky=W + E)
    check_for_qaac_files()

    qt_files_download = HoverButton(
        qaac_frame,
        text="Download QTfiles64",
        command=lambda: webbrowser.open(
            'https://github.com/AnimMouse/QTFiles/releases'),
        foreground="white",
        background="#23272A",
        borderwidth="3",
        activebackground='grey')
    qt_files_download.grid(row=1,
                           column=2,
                           columnspan=1,
                           padx=5,
                           pady=(2, 0),
                           sticky=N + S + E + W)

    qt_files_dir = HoverButton(qaac_frame,
                               text="Open QTfiles64 Directory",
                               command=lambda: webbrowser.open(qt_folder),
                               foreground="white",
                               background="#23272A",
                               borderwidth="3",
                               activebackground='grey')
    qt_files_dir.grid(row=1,
                      column=3,
                      columnspan=1,
                      padx=5,
                      pady=(2, 0),
                      sticky=N + S + E + W)

    # save path frame -------------------------------------------------------------------------------------------------
    save_path_frame = LabelFrame(settings_tab,
                                 text=' Save Paths ',
                                 labelanchor="n")
    save_path_frame.grid(column=0,
                         row=1,
                         columnspan=4,
                         padx=5,
                         pady=(10, 3),
                         sticky=N + S + E + W)
    save_path_frame.configure(fg="#3498db",
                              bg="#434547",
                              bd=3,
                              font=(set_font, 10, "bold"))
    save_path_frame.grid_rowconfigure(0, weight=1)
    save_path_frame.grid_rowconfigure(1, weight=1)
    for s_p in range(4):
        save_path_frame.grid_columnconfigure(s_p, weight=1)

    # Manual Auto Path ------------------------------------------------------------------------------------------------
    manual_auto_frame = LabelFrame(save_path_frame,
                                   text=' Manual/Auto Encode Path ',
                                   labelanchor="nw")
    manual_auto_frame.grid(column=0,
                           row=0,
                           columnspan=4,
                           padx=5,
                           pady=(5, 3),
                           sticky=E + W)
    manual_auto_frame.configure(fg="#3498db",
                                bg="#434547",
                                bd=3,
                                font=(set_font, 9, "italic"))
    manual_auto_frame.grid_rowconfigure(0, weight=1)
    manual_auto_frame.grid_columnconfigure(0, weight=2)
    manual_auto_frame.grid_columnconfigure(1, weight=20)
    manual_auto_frame.grid_columnconfigure(3, weight=1)

    def set_manual_auto_path():
        path = filedialog.askdirectory(title='Output Path Manual/Auto',
                                       parent=general_settings_window)
        if path:
            manual_path_parser = ConfigParser()
            manual_path_parser.read(config_file)
            path = str(pathlib.Path(path))
            manual_path_parser.set('output_path', 'path', path)
            with open(config_file, 'w') as manual_path_configfile:
                manual_path_parser.write(manual_path_configfile)
            manual_auto_entry_box.config(state=NORMAL)
            manual_auto_entry_box.delete(0, END)
            manual_auto_entry_box.insert(
                0,
                str(
                    pathlib.Path(str(
                        manual_path_parser['output_path']['path']))))
            manual_auto_entry_box.config(state=DISABLED)

    set_manual_auto_path = HoverButton(manual_auto_frame,
                                       text="Set Path",
                                       command=set_manual_auto_path,
                                       foreground="white",
                                       background="#23272A",
                                       borderwidth="3",
                                       activebackground='grey')
    set_manual_auto_path.grid(row=0,
                              column=0,
                              columnspan=1,
                              padx=5,
                              pady=5,
                              sticky=N + S + E + W)

    saved_manual_auto_path = None
    if config_parser['output_path']['path'] == 'file input directory':
        saved_manual_auto_path = str(
            config_parser['output_path']['path']).title()
    elif config_parser['output_path']['path'] != 'file input directory':
        saved_manual_auto_path = str(
            pathlib.Path(config_parser['output_path']['path']).resolve())
    manual_auto_entry_box = Entry(manual_auto_frame,
                                  borderwidth=4,
                                  background="#CACACA")
    manual_auto_entry_box.grid(row=0,
                               column=1,
                               columnspan=2,
                               padx=5,
                               pady=5,
                               sticky=N + S + E + W)
    manual_auto_entry_box.insert(0, saved_manual_auto_path)
    manual_auto_entry_box.config(state=DISABLED)

    def reset_manual_auto_path():
        msg = messagebox.askyesno(
            title='Prompt',
            message='Reset path to directory of input file?',
            parent=general_settings_window)
        if msg:
            reset_manual_path_parser = ConfigParser()
            reset_manual_path_parser.read(config_file)
            reset_manual_path_parser.set('output_path', 'path',
                                         'file input directory')
            with open(config_file, 'w') as r_mp_cfg:
                reset_manual_path_parser.write(r_mp_cfg)
            manual_auto_entry_box.config(state=NORMAL)
            manual_auto_entry_box.delete(0, END)
            manual_auto_entry_box.insert(
                0,
                str(reset_manual_path_parser['output_path']['path']).title())
            manual_auto_entry_box.config(state=DISABLED)

    reset_manual_auto_path = HoverButton(manual_auto_frame,
                                         text="X",
                                         command=reset_manual_auto_path,
                                         foreground="white",
                                         background="#23272A",
                                         borderwidth="3",
                                         activebackground='grey')
    reset_manual_auto_path.grid(row=0,
                                column=3,
                                columnspan=1,
                                padx=5,
                                pady=5,
                                sticky=N + S + E + W)

    # Batch Path ------------------------------------------------------------------------------------------------------
    batch_frame = LabelFrame(save_path_frame,
                             text=' Batch Processing Path ',
                             labelanchor="nw")
    batch_frame.grid(column=0,
                     row=1,
                     columnspan=4,
                     padx=5,
                     pady=(5, 3),
                     sticky=E + W)
    batch_frame.configure(fg="#3498db",
                          bg="#434547",
                          bd=3,
                          font=(set_font, 9, "italic"))
    batch_frame.grid_rowconfigure(0, weight=1)
    batch_frame.grid_columnconfigure(0, weight=2)
    batch_frame.grid_columnconfigure(1, weight=20)
    batch_frame.grid_columnconfigure(3, weight=1)

    def set_batch_path():
        path = filedialog.askdirectory(title='Output Path Manual/Auto',
                                       parent=general_settings_window)
        if path:
            bath_path_parser = ConfigParser()
            bath_path_parser.read(config_file)
            path = str(pathlib.Path(path))
            bath_path_parser.set('batch_path', 'path', path)
            with open(config_file, 'w') as batch_cfg:
                bath_path_parser.write(batch_cfg)
            batch_entry_box.config(state=NORMAL)
            batch_entry_box.delete(0, END)
            batch_entry_box.insert(
                0,
                str(pathlib.Path(str(bath_path_parser['batch_path']['path']))))
            batch_entry_box.config(state=DISABLED)

    set_batch_path_button = HoverButton(batch_frame,
                                        text="Set Path",
                                        command=set_batch_path,
                                        foreground="white",
                                        background="#23272A",
                                        borderwidth="3",
                                        activebackground='grey')
    set_batch_path_button.grid(row=0,
                               column=0,
                               columnspan=1,
                               padx=5,
                               pady=5,
                               sticky=N + S + E + W)

    saved_batch_path = None
    if config_parser['batch_path']['path'] == 'file input directory':
        saved_batch_path = str(config_parser['batch_path']['path']).title()
    elif config_parser['batch_path']['path'] != 'file input directory':
        saved_batch_path = str(
            pathlib.Path(config_parser['batch_path']['path']).resolve())
    batch_entry_box = Entry(batch_frame, borderwidth=4, background="#CACACA")
    batch_entry_box.grid(row=0,
                         column=1,
                         columnspan=2,
                         padx=5,
                         pady=5,
                         sticky=N + S + E + W)
    batch_entry_box.insert(0, saved_batch_path)
    batch_entry_box.config(state=DISABLED)

    def reset_batch_path():
        msg = messagebox.askyesno(
            title='Prompt',
            message='Reset path to directory of input file?',
            parent=general_settings_window)
        if msg:
            reset_batch_path_parser = ConfigParser()
            reset_batch_path_parser.read(config_file)
            reset_batch_path_parser.set('batch_path', 'path',
                                        'file input directory')
            with open(config_file, 'w') as reset_bp_cfg:
                reset_batch_path_parser.write(reset_bp_cfg)
            batch_entry_box.config(state=NORMAL)
            batch_entry_box.delete(0, END)
            batch_entry_box.insert(
                0,
                str(reset_batch_path_parser['batch_path']['path']).title())
            batch_entry_box.config(state=DISABLED)

    reset_batch_path_button = HoverButton(batch_frame,
                                          text="X",
                                          command=reset_batch_path,
                                          foreground="white",
                                          background="#23272A",
                                          borderwidth="3",
                                          activebackground='grey')
    reset_batch_path_button.grid(row=0,
                                 column=3,
                                 columnspan=1,
                                 padx=5,
                                 pady=5,
                                 sticky=N + S + E + W)
示例#10
0
class Player(Frame):
	def __init__(self,master):
		super().__init__(master)
		self.master =master
		mixer.init()
		self.pack()
		if os.path.exists("tracks.pickle"):
			with open ("tracks.pickle", "rb") as f:
				self.playlist =pickle.load(f)
		else:
			self.playlist =[]

		# player state flags
		self.track_index =0
		self.track_paused =True
		self.track_played =False

		self.model_frame()
		self.track_widget()
		self.tracklist_widget()
		self.controls_widget()

	# frames
	def model_frame(self):
		self.track =LabelFrame(self,
				relief =GROOVE
			)
		self.track.configure(
				width =410,
				height =300
			)
		self.track.grid(row=0, column=0,pady=10,padx=10)

		self.tracklist =LabelFrame(self,
				relief =GROOVE
			)
		self.tracklist.configure(
				width =190,
				height =420
			)
		self.tracklist.grid(row=0, column=1,rowspan=3,pady=10,padx=10)

		self.controls =LabelFrame(self,
				font =("times new roman",15,"bold"),
				bg ="white",
				fg ="white",
				bd =0,
				relief =GROOVE
			)
		self.controls.configure(
				width =410,
				height =100
			)
		self.controls.grid(row=1, column=0,pady=10,padx=10)

	# widgets
	def track_widget(self):
		self.canvas =Label(self.track,font =("times new roman",15,"bold"),bg="white", fg ="dodgerblue")
		self.canvas['text'] ="Hit tracks"; 
		self.canvas.configure(width =33, height =1)
		self.canvas.grid(row =0,column =0)

		self.canvas =Label(self.track,image=track_ico) 
		self.canvas.configure(width =300, height =240)
		self.canvas.grid(row =1,column =0)

		self.playing_tune =Label(self.track,font =("Calibri",13),bg="white", fg ="dodgerblue")
		self.playing_tune['text'] ="Musiflix MP3 Player"; 
		self.playing_tune.configure(width =44, height =1)
		self.playing_tune.grid(row =2,column =0)

	def tracklist_widget(self):
		self.listtitle =Label(self.tracklist,font =("times new roman",15,"bold"),bg="white", fg ="dodgerblue")
		self.listtitle['text'] =f"Playlist:  {len(self.playlist)} "
		self.listtitle.configure(width =10, height =1)
		self.listtitle.grid(row =0,column =0)

		self.scrollbar =Scrollbar(self.tracklist,orient =VERTICAL)
		self.scrollbar.grid(row=0, column=1,rowspan =10, sticky="NS")

		self.list =Listbox(self.tracklist, selectmode =SINGLE,
			yscrollcommand =self.scrollbar.set, selectbackground ="sky blue")
		self.track_listing()
		self.list.config(height =22)
		self.list.bind('<Double-1>', self.play_track)
		self.scrollbar.config(command =self.list.yview)
		self.list.grid(row=2, column=0, rowspan =5)

	def track_listing(self):
		for index, track in enumerate(self.playlist):
			self.list.insert(index,os.path.basename(track))

	def controls_widget(self):
		self.tracklister =Button(self.controls, 
			font =("times new roman",15,"bold"),
			bg="white", fg ="dodgerblue", padx =10,pady =5,
			command =self.select_track
			)
		self.tracklister['text'] ="Load tracks"
		self.tracklister.grid(row =0,column =0,padx=10,pady =5)

		self.prevbutton =Button(self.controls,image =prev_icon, command =self.prev_track)
		self.prevbutton.grid(row =0,column =1,pady =5)

		self.pausebutton =Button(self.controls,image =pauseicon, command =self.pause_track)
		self.pausebutton.grid(row =0,column =2,pady =5)

		self.nextbutton =Button(self.controls,image =next_icon, command =self.next_track)
		self.nextbutton.grid(row =0,column =3,pady =5)

		self.volume =DoubleVar()
		self.slider =Scale(self.controls, from_ =0, to =10, orient =HORIZONTAL)
		self.slider['variable'] =self.volume
		self.slider['command'] =self.change_volume
		self.slider.set(3)
		mixer.music.set_volume(0.3)
		self.slider.grid(row =0, column=4,padx=10,pady =5)

	def change_volume(self, event =None):
		self.v =self.volume.get()
		mixer.music.set_volume(self.v/10)


	def select_track(self):
		self.tunes =[]
		directory =filedialog.askdirectory()
		for rooot, dirs, files in os.walk(directory):
			for file in files:
				if os.path.splitext(file)[1] =='.mp3':
					path =(rooot + '/' + file).replace('\\','/')
					self.tunes.append(path)
		with open("tracks.pickle", "wb") as f:
			pickle.dump(self.tunes, f) 
		self.playlist =self.tunes
		self.listtitle['text'] =f"Playlist:  {len(self.playlist)}"
		self.list.delete(0, END)
		self.track_listing()

	def play_track(self, event =None):
		try:
			if event is not None:
				self.track_index =self.list.curselection()[0]
			for i in range(len(self.playlist)):
				self.list.itemconfigure(i,bg="white",fg="black")
			mixer.music.load(self.playlist[self.track_index])
			self.track_paused =False
			self.track_played =True
			self.pausebutton['image'] =playicon
			self.playing_tune.anchor('w')
			self.playing_tune['text'] =os.path.basename(self.playlist[self.track_index])
			self.list.activate(self.track_index)
			self.list.itemconfigure(self.track_index,bg="teal", fg="white")
			mixer.music.play()
		except  Exception as e:
			pass
	def pause_track(self):
		if not self.track_paused:
			try:
				self.track_paused =True
				self.pausebutton['image'] =pauseicon
				mixer.music.pause()
			except Exception as e:
				pass
		else:
			try:
				if not self.track_played:
					self.play_track()
				self.track_paused =False
				self.pausebutton['image'] =playicon
				mixer.music.unpause()
			except Exception as e:
				pass
	def next_track(self):
		if self.track_index > len(self.playlist) -1:
			self.track_index =0
		self.track_index +=1
		self.play_track()

	def prev_track(self):
		if self.track_index < 0:
			self.track_index =len(self.playlist) -1
		self.track_index -=1
		self.play_track()
示例#11
0
from tkinter import Tk, Label, Entry, Button, LabelFrame, IntVar, Checkbutton
import docx
from docx.shared import Pt

janela = Tk()
janela.title('Words replacer')
janela.geometry('450x145')
janela.resizable(width=False, height=False)

frame_1 = LabelFrame()
frame_1.pack()
janela.configure(bg='lightsteelblue2')
frame_1.configure(bg='slategray1')

textinho_0 = Label(frame_1, text='Word to find', bg='slategray1')
textinho_0.grid(column=1, row=0)
textinho = Label(frame_1, text='Replace', bg='slategray1')
textinho.grid(column=2, row=0)
textinho1 = Label(frame_1, text='paragraph', bg='slategray1')
textinho1.grid(column=0, row=1)
textinho1 = Label(frame_1, text='tables', bg='slategray1')
textinho1.grid(column=0, row=2)
textinho2 = Label(frame_1, text='file name: ', bg='slategray1')
textinho2.grid(column=0, row=3)

word_entry_paragraph = Entry(frame_1)
word_entry_paragraph.grid(column=1, row=1)

word_entry_tables = Entry(frame_1)
word_entry_tables.grid(column=1, row=2)
示例#12
0
def show_info(msg):
    messagebox.showinfo("This is magical!", msg)


titleframe = Frame(root)
titleframe.configure(background=bg_colour)
titleframe.grid(row=0, column=0)

editframeTitle = Label(root, text="Manage Entries", background=bg_alt, pady=5)

editframe = LabelFrame(root,
                       text="Manage Entries",
                       borderwidth=0,
                       labelanchor='n',
                       labelwidget=editframeTitle)
editframe.configure(background=bg_alt)
editframe.grid(row=2, column=0, padx=40, pady=25)

roadtax_tab = ttk.Notebook(root)

bodyframe = Frame(roadtax_tab)
bodyframe.configure(background=bg_colour)
bodyframe.grid()

roadtax_tab.add(bodyframe, text="Roadtax")
roadtax_tab.enable_traversal()
roadtax_tab.grid(row=1, column=0, sticky=S)

title = Label(titleframe,
              font=("Courier", 28),
              text="Road-Tax Renewal Tracker",