Exemple #1
0
def start_dialog():
    left_frame = [[sg.Image(filename='', key='_IMAGE_')]]
    right_frame = [[sg.Image(filename='', key='_PERSON_')],
                   [sg.Text("Who is it?")], [sg.Input()],
                   [sg.Button('Capture')], [sg.Button('Quit')]]

    layout = [[sg.Frame("", left_frame), sg.Frame("", right_frame)]]

    window = sg.Window('Face recognition training centre', layout)

    cap = cv2.VideoCapture(0)
    ret, frame = cap.read()
    mirror = flipHorizontal = cv2.flip(frame, 1)
    while True:
        event, values = window.Read(timeout=20, timeout_key='timeout')
        if event is None or event == 'Quit':
            break
        if event == 'Capture':
            person_name = values[0]
            if person_name is not None and person_name != "":
                process_image(person_name, frame)

        ret, frame = cap.read()
        mirror = flipHorizontal = cv2.flip(frame, 1)

        imgbytes = cv2.imencode('.png', mirror)[1].tobytes()
        window.FindElement('_IMAGE_').Update(data=imgbytes)
        person_img = get_first_face(mirror, 200, 200)
        if person_img is not None:
            imgbytes = cv2.imencode('.png', person_img)[1].tobytes()
            window.FindElement('_PERSON_').Update(data=imgbytes)

    window.close()
    cap.release()
def _layout_(config):
    import PySimpleGUIQt as qt
    struct = [[qt.Menu(_top_menu_())], [qt.Text('Welcome to Test API!')],
              [qt.Combo(['Living Room', 'Playroom'])],
              [qt.Frame('', _sense_frame_(config))],
              [qt.Frame('', list(_button_frame_()))]]

    return struct
Exemple #3
0
    def rearrange_layout_of_tab(self) -> None:
        # Todo: Limit to Toplevel/Add another limit, otherwise the ui will
        # turn crowded
        self.check_boxes = []
        for id_el in self.all_ids:
            new_checkbox = sg.Checkbox(text=self.id_collecion_name_dict[id_el],
                                       key=f"-checkbox-{id_el}-",
                                       default=id_el in self.valid_ids)
            new_checkbox.any = {"collection_id": id_el}
            self.check_boxes.append(new_checkbox)

        self.rows = []

        checkbox_frame = sg.Frame(title="Active Collections:",
                                  layout=[self.check_boxes])

        self.rows.append([checkbox_frame])

        self.rows.append([
            sg.Text(f"Current Exercise: \n {self.current_human_id} ",
                    justification="center")
        ])
        if self.display_solution:
            self.rows.append([self.exercise_image, self.solution_image])
        else:
            self.rows.append([self.exercise_image])
        self.rows.append([self.btn_show_solution])
Exemple #4
0
    def main_layout(self):
        """

        A method that returns a frame layout object for the entire window's frame

        Returns:
            frame layout object

        """
        layout = [[
            Qt.Frame('Sensor Information',
                     layout=self.sense_frame_layout(),
                     size=(450, 450))
        ],
                  [
                      Qt.Button('',
                                enable_events=True,
                                key='quit_button',
                                image_data=self.icons.quit,
                                tooltip='Quit',
                                button_color=(Qt.theme_text_color(),
                                              Qt.theme_background_color()),
                                border_width=0),
                      Qt.Button('',
                                enable_events=True,
                                key='refresh_all_button',
                                tooltip='Refresh All',
                                image_data=self.icons.refresh,
                                border_width=0,
                                button_color=(Qt.theme_text_color(),
                                              Qt.theme_background_color()))
                  ]]

        return layout
def run_themes_window():
    """Let the user preview and pick a theme from a list of themes.

    :return: the name of the selected theme, or None if no theme selected
    """
    window_bg = 'lightblue'

    def sample_layout(key):
        return [[sg.Text('Text element', tooltip="I am a tooltip!")],
                [sg.Button('Select', key=key, tooltip="This is a tooltip")]]

    layout = [[
        sg.Text(
            'Select a theme. Program must be restarted for changes to take effect',
            auto_size_text=True)
    ]]

    names = sg.list_of_look_and_feel_values()
    names.sort()
    row = []
    for count, theme in enumerate(names):
        sg.change_look_and_feel(theme)
        if not count % 9:
            layout += [row]
            row = []
        row += [sg.Frame(theme, sample_layout(key=theme))]
    if row:
        layout += [row]

    theme_window = sg.Window('All themes', layout, background_color=window_bg)
    event, vals = theme_window.read()

    theme_window.close()
    del theme_window
    return event
    def redraw_visible_ui(self) -> List:
        self.rearrange_layout_of_tab()

        default_frame: sg.Frame = sg.Frame(title="", layout=self.rows, element_justification="center",
                                           size=(200, 200), key=f"-framekey-f{self.title}")
        visible_tab = sg.Tab(title=self.title, layout=[[default_frame]])
        return [visible_tab]
Exemple #7
0
def init_gui():
    global window
    global adapters
    global values

    sg.theme("Reddit")

    layout_frame = [
        [sg.Checkbox("DHCP", key="DHCP", enable_events=True)],
        [sg.Text("")],
        [sg.Text("IP: ", size=(15, 1)),
         sg.Input(size=(15, 1), key="IP")],
        [sg.Text("Sub: ", size=(15, 1)),
         sg.Input(size=(15, 1), key="SUB")],
        [
            sg.Text("Gateway: ", size=(15, 1)),
            sg.Input(size=(15, 1), key="GATE")
        ],
    ]

    layout = [[
        sg.Combo(adapters, enable_events=True, key="DROP", readonly=True),
    ], [
        sg.Frame(
            "Network",
            layout_frame,
        ),
    ], [sg.Button("Update", size=(15, 1), key="UPDATE")]]

    window = sg.Window("IP", layout, icon="favicon.png")

    window.read(1)
    update_text(window, 0)
def SendTC(file_name, instrument_type, note):

    flights = [
        'FLOATS_51', 'FLOATS_52', 'FLOATS_53', 'RACHuTS_51', 'RACHuTS_52',
        'RACHuTS_53', 'LPC_51', 'LPC_52', 'LPC_53'
    ]

    flight_layout = [[
        sg.Listbox(values=flights,
                   key='_param_',
                   tooltip='Select balloon/instrument to send TC to',
                   size=(20, 6),
                   font=Font)
    ]]
    layout_config_TC = [
        [sg.Frame('Select Instrument/Flight: ', flight_layout, font=Font)],
        #[sg.Frame('Input new value: ', value_layout, font = Font)],
        [
            sg.Submit(font=Font, pad=(10, 10)),
            sg.Cancel(font=Font, pad=(10, 10))
        ]
    ]
    param_window = sg.Window('Select Flight', layout_config_TC)
    event, values = param_window.Read()
    param_window.Close()
    instrument = values['_param_'][0]
    print(instrument)
    print(event)

    if event == 'Submit':
        curl_cmnd(instrument, file_name, note)
Exemple #9
0
def continue_anyway(issue):

    # Set-up the logger
    log = getLogger(f'{PROG}.{__name__}')
    log.debug('Received request to produce a "continue?" popup window.')

    # Provide a layout for our window
    logo_frame = [[Qt.Image('/home/taylor/Pictures/logo.png', key='img_elm')]]

    button_frame = [
            [Qt.Button('Yes')]
            ]

    main_layout = [
            [Qt.Frame('', layout=logo_frame, element_justification='center', size=(40, 40))],
            []
            ]

    window = Qt.Window('Continue Anyway?', layout=main_layout)


    while True:
        event, vals = window.read(timeout=100)



        if event is None or vals == 'exit':
            log.debug('User leaving window by click')
Exemple #10
0
 def form_frame():
     _layout = [[
         qt.Text('Look & Feel: '),
         qt.Combo(qt.theme_list(),
                  enable_events=True,
                  key='look_and_feel_combo')
     ]]
     _frame = qt.Frame('Settings', _layout)
     return _frame
    def main_layout(self):
        """
        The main layout structure logic for the preferences window

        :return:
        """
        import PySimpleGUIQt as qt
        # noinspection SpellCheckingInspection
        layout = [[
            qt.Frame('',
                     self._localization_frame_(),
                     background_color='#00c2c7'),
            qt.Frame('',
                     self._weather_api_frame_(),
                     background_color='#97ebdb')
        ], [qt.Frame('', self.geolocale_frame(), background_color='#005582')],
                  [
                      qt.Button('Cancel', key='opts_win_cancel'),
                      qt.Button('OK', key='opts_win_ok')
                  ]]

        return layout
Exemple #12
0
 def button_frame():
     _layout = [[
         qt.Button('OK',
                   enable_events=True,
                   key='settings_win_ok_bttn',
                   bind_return_key=True),
         qt.Button('Apply',
                   enable_events=True,
                   key='settings_win_apply_bttn',
                   visible=False),
         qt.Button('Cancel',
                   enable_events=True,
                   key='settings_win_cancel_bttn',
                   visible=False)
     ]]
     _frame = qt.Frame('', _layout)
     return _frame
Exemple #13
0
def pick_an_instrument():
    ''' Select the instrument to generate TC files for'''

    instruments = ['LPC', 'RACHuTS', 'FLOATS']

    instrument_layout = [[
        sg.InputCombo(values=instruments, key='_inst_', font=Font)
    ]]
    layout_pick_instrument = [[
        sg.Frame('Select Instrument: ', instrument_layout, font=Font)
    ], [sg.Submit(font=Font), sg.Cancel(font=Font)]]

    instrument_window = sg.Window('Select Instrument', layout_pick_instrument)
    event, values = instrument_window.Read()
    instrument_window.Close()

    if event is None or event == 'Cancel':
        return None
    if event == 'Submit':
        print(values['_inst_'])
        return values['_inst_']
    def __init__(self, config):
        from monopolpy_companion.lib.common.run import opts_win_active
        import PySimpleGUIQt as qt
        # First we pull in the environment variables
        from monopolpy_companion.conf import conf as defaults
        import logging

        self.name = 'MonopolPyCompanion.GUI.OptionsWindow'
        log = logging.getLogger(self.name)
        log.debug(f'Logger started for {self.name}')
        self.log = log

        log.debug(f'Current active state: {opts_win_active}')
        opts_win_active = True
        log.debug(f'New active state: {opts_win_active}')
        self.active = opts_win_active

        conf = config
        self.conf = conf

        self.opts_playman_frame = [
            [qt.Button('Player Management', key='opts_playman_button')],
        ]

        self.opts_frame = [[
            qt.Checkbox('Grab anywhere',
                        default=self.is_grabby(),
                        key='grab_anywhere_box')
        ]]

        self.opts_main_frame = [[
            qt.Frame('Player Management:', self.opts_playman_frame)
        ], [qt.Frame('GUI Options', self.opts_frame)]]

        self.layout = [[
            qt.Frame('Monopolpy Companion Options:',
                     self.opts_main_frame,
                     background_color='#40bfdbae',
                     title_color='#ff000000',
                     title_location='TITLE_LOCATION_TOP',
                     relief='RELIEF_SUNKEN')
        ],
                       [
                           qt.Button('OK', key='opts_ok'),
                           qt.Cancel(key='opts_cancel'),
                           qt.Button('Apply', key='opts_apply')
                       ]]

        self.opts_win = qt.Window(
            'Monopolpy Companion Options',
            self.layout,
            grab_anywhere=self.conf['gui_settings']['grab_anywhere'],
            background_image='thing.png',
            size=(400, 200))
        from monopolpy_companion.lib.common.run import pm_active

        log.debug(
            f'Imported active state of the Player Manager window which is: {pm_active}'
        )

        while self.active:

            event, values = self.opts_win.read(timeout=100)

            if event == 'opts_ok' or event == 'opts_apply':
                log.debug('User is attempting to save config to file')
                from monopolpy_companion.lib.helpers.popup_man import nyi

                nyi('Save Config')

            if event == 'opts_ok':
                log.debug('User pressed OK in the options window')
                log.debug('Leaving window.')
                self.leave()

            if event == 'opts_playman_button' and not pm_active:
                from monopolpy_companion.lib.gui.models.windows.player_man import PlayerManagerWindow
                log.debug('User pressed the Player Manager button')
                play_man_win = PlayerManagerWindow()
                log.debug(
                    f'Player Manager active state was {play_man_win.active}')
                play_man_win.active = True

            if event is None or event == 'opts_cancel':
                log.debug('User pressed cancel in the options window')
                self.leave()
Exemple #15
0
settings = [
    ['Выдано БГ', '91315', 'oitgp'],
    ['Погашено БГ', '91315', 'oitga'],
    ['Портфель БГ', '91315', 'iitg'],
    ['Комиссия БГ', '47502', 'oitga'],
    ['Выдачи в рамках лимита', '91319', 'oitga'],
    ['Неис лимиты БГ на дату', '91319', 'iitg'],
    ['Выплачено по требованию БГ', '60315', 'oitga'],
    ['Дефолтность портфеля', '60315', 'oitga', '91315', 'iitg'],
    ['Доходность выдач', '47502', 'oitga', '91315', 'oitgp']
]

layout1 = [
    [
        sg.Frame('Номера банков', [[
            sg.Text('№, №'), sg.InputText('1481', key='-REGNUMS-'),
            ]]
        )

    ],
    [sg.Button('Настройки парсинга')],
    [
        sg.Frame('Список банков', [[
            sg.Listbox(values=[], select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE, key='-LISTBOX-')
            ]]
        )
    ],
    [sg.Button('Взять данные'), sg.Text(' ' * 79), sg.Button('Удалить')],
    [
        sg.Frame('Cохранение', [[
                sg.FolderBrowse('Выберете папку', target='-PATH-'),
                sg.InputText(f'{dirname(__file__)}', key='-PATH-'),
Exemple #16
0
    sg.Text("  CVV", justification='left'),
    sg.Text("  Card Number", justification='left'),
    sg.Text("  Password", justification='left')
],
                 [
                     sg.Input(key='-CVV-', justification='left'),
                     sg.Input(key='-CARD-', justification='left'),
                     sg.Input(key='-PASSWORD-', justification='left')
                 ]]

layout = [[
    sg.Text("Bestbuy.ca Bot",
            justification='center',
            background_color=0,
            font=("Helvetica", 15))
], [sg.Frame("", frame_layout1)], [sg.Frame("", frame_layout2)],
          [sg.Frame("", frame_layout3)], [sg.Frame("", frame_layout4)],
          [sg.Frame("", frame_layout5)],
          [
              sg.Text(key='-OUTPUT1-',
                      background_color=0,
                      text_color="black",
                      font=("Helvetica", 13))
          ],
          [
              sg.Button('Start', size=(70, 30)),
              sg.Button('Pause', size=(70, 30)),
              sg.Button('Ready!', size=(70, 30))
          ]]

checkuser = getpass.getuser()
Exemple #17
0
def main():
    sg.ChangeLookAndFeel('GreenTan')
    # sg.SetOptions(element_padding=(0,0))
    # ------ Menu Definition ------ #
    menu_def = [
        ['&File', ['&Open', '&Save', '&Properties', 'E&xit']],
        [
            '&Edit',
            ['&Paste', [
                'Special',
                'Normal',
            ], 'Undo'],
        ],
        ['&Toolbar', ['Command &1', 'Command &2', 'Command &3', 'Command &4']],
        ['&Help', '&About...'],
    ]

    treedata = sg.TreeData()

    treedata.Insert(
        "",
        '_A_',
        'Tree Item 1',
        [1, 2, 3],
    )
    treedata.Insert(
        "",
        '_B_',
        'B',
        [4, 5, 6],
    )
    treedata.Insert(
        "_A_",
        '_A1_',
        'Sub Item 1',
        ['can', 'be', 'anything'],
    )
    treedata.Insert(
        "",
        '_C_',
        'C',
        [],
    )
    treedata.Insert(
        "_C_",
        '_C1_',
        'C1',
        ['or'],
    )
    treedata.Insert("_A_", '_A2_', 'Sub Item 2', [None, None])
    treedata.Insert("_A1_", '_A3_', 'A30', ['getting deep'])
    treedata.Insert("_C_", '_C2_', 'C2', ['nothing', 'at', 'all'])

    for i in range(100):
        treedata.Insert('_C_', i, i, [])

    frame1 = [
        [sg.Input('Input Text', size=(250, 35)),
         sg.Stretch()],
        [
            sg.Multiline(size=(250, 75), default_text='Multiline Input'),
            sg.MultilineOutput(size=(250, 75), default_text='Multiline Output')
        ],
    ]

    frame2 = [
        [sg.Listbox(['Listbox 1', 'Listbox 2', 'Listbox 3'], size=(200, 85))],
        [
            sg.Combo(['Combo item 1', 'Combo item 2', 'Combo item 3'],
                     size=(200, 35))
        ],
        [sg.Spin([1, 2, 3], size=(40, 30))],
    ]

    frame3 = [
        [sg.Checkbox('Checkbox1', True),
         sg.Checkbox('Checkbox1')],
        [
            sg.Radio('Radio Button1', 1),
            sg.Radio('Radio Button2', 1, default=True),
            sg.Stretch()
        ],
    ]

    frame4 = [
        [
            sg.Slider(range=(0, 100),
                      orientation='v',
                      size=(3, 30),
                      default_value=40),
            sg.Dial(range=(0, 100),
                    tick_interval=50,
                    size=(150, 150),
                    default_value=40),
            sg.Stretch()
        ],
    ]
    matrix = [[str(x * y) for x in range(4)] for y in range(3)]

    frame5 = [
        [
            sg.Table(values=matrix,
                     max_col_width=25,
                     auto_size_columns=True,
                     display_row_numbers=True,
                     change_submits=False,
                     bind_return_key=True,
                     justification='right',
                     num_rows=8,
                     alternating_row_color='lightblue',
                     key='_table_',
                     text_color='black'),
            sg.Tree(data=treedata,
                    headings=['col1', 'col2', 'col3'],
                    change_submits=True,
                    auto_size_columns=True,
                    num_rows=10,
                    col0_width=10,
                    key='_TREE_',
                    show_expanded=True,
                    size=(200, 150)),
            sg.Stretch()
        ],
    ]

    graph_elem = sg.Graph((880, 150), (0, 0), (600, 300), key='+GRAPH+')

    frame6 = [
        [graph_elem, sg.Stretch()],
    ]

    tab1 = sg.Tab('Graph Number 1', frame6)
    tab2 = sg.Tab('Graph Number 2', [[]])

    layout = [
        [sg.Menu(menu_def)],
        [
            sg.Image(data_base64=logo),
            sg.Frame('Input Text Group', frame1, title_color='red'),
            sg.Stretch()
        ],
        [
            sg.Frame('Multiple Choice Group', frame2, title_color='green'),
            sg.Frame('Binary Choice Group', frame3, title_color='purple'),
            sg.Frame('Variable Choice Group', frame4, title_color='blue'),
            sg.Stretch()
        ],
        [
            sg.Frame('Structured Data Group', frame5, title_color='red'),
        ],
        # [sg.Frame('Graphing Group', frame6)],
        [sg.TabGroup([[tab1, tab2]])],
        [
            sg.ProgressBar(max_value=600,
                           start_value=400,
                           size=(600, 25),
                           key='+PROGRESS+'),
            sg.Stretch(),
            sg.ButtonMenu('&Menu', ['Menu', ['&Pause Graph', 'Menu item']],
                          key='_MENU_'),
            sg.Button('Button'),
            sg.Button('Exit')
        ],
    ]

    window = sg.Window('Window Title',
                       font=('Helvetica', 13),
                       default_button_element_size=(100, 30),
                       auto_size_buttons=False,
                       default_element_size=(200,
                                             22)).Layout(layout).Finalize()
    graph_elem.DrawCircle((200, 200), 50, 'blue')
    i = 0
    graph_paused = False
    while True:  # Event Loop
        # sg.TimerStart()
        event, values = window.Read(timeout=0)
        if event is None or event == 'Exit':
            break
        if event == 'Button':
            print(event, values)
        if values['_MENU_'] == 'Pause Graph':
            graph_paused = not graph_paused
        if not graph_paused:
            i += 1

            if i >= 600:
                graph_elem.Move(-1, 0)
            graph_elem.DrawLine((i, 0), (i, randint(0, 300)),
                                width=1,
                                color='#{:06x}'.format(randint(0, 0xffffff)))
        window.FindElement('+PROGRESS+').UpdateBar(i % 600)

        # sg.TimerStop()
    window.Close()
 [sg.InputText('This is my text', size=(400, 22))],
 [
     sg.Frame(
         layout=[[
             sg.Checkbox('Checkbox', size=(185, 22)),
             sg.Checkbox('My second checkbox!', default=True)
         ],
                 [
                     sg.Radio(
                         'My first Radio!',
                         "RADIO1",
                         default=True,
                         size=(180, 22),
                     ),
                     sg.Radio('My second Radio!', "RADIO1")
                 ],
                 [
                     sg.Radio(
                         'Third Radio!',
                         "RADIO2",
                         default=True,
                         size=(180, 22),
                     ),
                     sg.Radio('Fourth Radio!', "RADIO2")
                 ]],
         title='Options',
         title_color='red',
         relief=sg.RELIEF_SUNKEN,
         tooltip='Use these to set flags',
     ),
     sg.Stretch()
 ],
Exemple #19
0
import PySimpleGUIQt as sg
from aud import Dir

sg.change_look_and_feel("DarkAmber")  # Add a little color

frm_dir = sg.Frame(
    title="Working Directory:",
    layout=[
        [
            sg.InputText(key="_selected_dir_", size=(44, 1), disabled=True),
            sg.Button("Browse", size=(5, 1)),
        ]
    ],
)

frm_output_dir = sg.Frame(
    title="Output Directory:",
    layout=[
        [
            sg.InputText(key="_output_dir_", size=(44, 1), disabled=True),
            sg.Button("Browse", size=(5, 1)),
        ]
    ],
)

frm_config = sg.Frame(
    title="Config:",
    layout=[
        [sg.Text("Directory:", size=(15, 1)), sg.InputText(key="_dir_", size=(37, 1))],
        [sg.Text("Extensions:", size=(15, 1)), sg.InputText(key="_ext_", size=(37, 1))],
        [sg.Text("Blacklist:", size=(15, 1)), sg.InputText(key="_bl_", size=(37, 1))],
Exemple #20
0
def welcome_layout():
    frame_1 = [
        [sg.Text('Balança: ')], [sg.Combo(['Nenhuma', 'Toledo', 'Filizola', 'Urano'],
                                          font=("verdana", 11), key="balance_name", enable_events=True, size=(13, 0.8))],
        [sg.Text('Porta Serial: ')], [sg.Combo(get_serial_names(), font=("verdana", 13),
                                               key="serial_port", size=(13, 0.8))],
        [sg.Text('Baud Rate: ')], [sg.Combo([2400, 4800, 9600, 14400, 19200, 38400,
                                             56000, 57600], font=("verdana", 11), key="baudrate", size=(13, 0.8))],
        [sg.Text('Data Bits: ')], [sg.Combo([5, 6, 7, 8], font=("verdana", 11), key="data_bits", size=(13, 0.8))],
        [sg.Text('Parity: ')], [sg.Combo(['none', 'odd', 'even', 'mark', 'space'],
                                         font=("verdana", 11), key="parity", size=(13, 0.8))],
        [sg.Text('Stop Bits:')], [sg.Combo([1, 1.5, 2], font=("verdana", 11), key="stop_bits", pad=[1, 0], size=(13, 0.8))],
        [sg.Text('Handshaking: ')], [sg.Combo(['Nenhum', 'XON/XOFF', 'RTS/CTS', 'DTR/DSR'],
                                              font=("verdana", 11), key="handshaking", pad=[1, 0], size=(13, 0.8))]
    ]

    frame_2 = [
        [sg.Text('')],
        [sg.Input(get_last_weight(), do_not_clear=True, size=(25, 0.8), tooltip='Último Peso Lido', disabled=True, key='last_weight'),
         sg.Text(' '), sg.Input('1', do_not_clear=True, size=(15, 0.8), tooltip='Timeout', key='timeout'), sg.Stretch()],
        [sg.Text('')],
        [sg.Text('Última Resposta: ')], [sg.Multiline(size=(41.5, 8.6), key='Textbox', disabled=True)],
        [sg.Text('Pesagem Apurada: ')], [sg.Multiline(size=(41.5, 4.6),
                                                      default_text=get_last_weight() + ' KG', font=('Helvetica Bold', 48), key='Textbox2', disabled=True)],
        [sg.Text('')],
        [sg.Text('')],
        [sg.Text('')],
    ]

    frame_3 = [
        [sg.Text('')],
        [sg.Text(''), sg.Text(' ' * 2), sg.Button('Ativar', size=[14, 0.8],
                                                  button_color=('white', '#082567'), key="activate"), sg.Text(''), sg.Text('')],
        [sg.Text('')],
        [sg.Text(''), sg.Text(' ' * 2), sg.Button('Desativar', size=[14, 0.8],
                                                  button_color=('white', '#082567'),
                                                  key="deactivate", disabled=True), sg.Text(''), sg.Text('')],
        [sg.Text('')],
        [sg.Text(''), sg.Text(' ' * 2), sg.Button('Ler Peso', size=[14, 0.8],
                                                  button_color=('white', '#082567'), key="weight_read"), sg.Text(''), sg.Text('')],
        [sg.Text('')],
        [sg.Text(''), sg.Text(' ' * 2), sg.Button('Localizar Portas', size=[14, 0.8],
                                                  button_color=('white', '#082567'), key="find_ports"), sg.Text(''), sg.Text('')],
        [sg.Text('')],
        [sg.Text(''), sg.Text(' ' * 2), sg.Button('Limpar', size=[14, 0.8],
                                                  button_color=('white', '#082567'), key="clean"), sg.Text(''), sg.Text('')],
        [sg.Text('')],
        [sg.Text(''), sg.Text(' ' * 2), sg.Button('Sair', size=[14, 0.8],
                                                  button_color=('white', '#082567'), key="exit"), sg.Text(''), sg.Text('')],
        [sg.Text('')],
    ]

    layout_1 = [
        [sg.Text('')],
        [sg.Text(' '), sg.Frame('Ajustes Técnicos', frame_1, title_color='black', element_justification="l", key='frame_1'), sg.Text(' '),
         sg.Frame('Visualização de dados', frame_2, title_color='black', element_justification="c", key='frame_2'), sg.Text(' '),
         sg.Frame('Serviços', frame_3, title_color='black', element_justification="r", key='frame_3'), sg.Stretch()],
        [sg.Text(f'Versão: {__version__} by {__author__}', text_color="black", font=("verdana", 8)),
         sg.Text(get_current_date(), justification="right", text_color="black", key="clock", font=("verdana", 8))
         ],
    ]

    return layout_1
gui.ChangeLookAndFeel('DarkGreen1')

button_frame = [
    [gui.Button('', key='start_new_main_button',
                image_data=start_new_button_img)],
    [gui.Button('', key='load_saved_main_button',
                image_data=load_saved_button_img)],
    [gui.Button('Options', key='options_main_button', font=('Monopoly, Bold', 16))],
    [gui.Button('Manage Players', key='play_man_main_button', font=('Monopoly, Bold', 16))]
    ]

frame = [
    [gui.Text('Welcome to Monopolpy Companion!', justification='center', background_color='#C70000',
              font=('Monopoly, Bold', 18))],
    [gui.Frame('What would you like to do', button_frame, title_location='center-top', background_color='#99FFFFFF',
               title_color='#000000')],
    [gui.Button('Exit', key='exit_button_main_application')]
    ]

main_layout = [
    [gui.Frame('', frame, background_color=('#408FBC72'))]
    ]

menu_def = ['My Menu Def',
            ['&Restore', '&Open', '---', '&Message', '&Save', ['1', '2', ['a', 'b']], '&Properties', 'E&xit']]
tray = gui.SystemTray(menu=menu_def, data_base64=app_icon)

win = gui.Window('Monopolpy Companion', main_layout,
                 background_image='monopolpy.png',
                 grab_anywhere=conf['gui_settings']['grab_anywhere'],
                 icon=app_icon,
Exemple #22
0
 sg.Frame(
     'HTTP Parameters',
     layout=[[
         sg.Text('URL :', size=(15, 1)),
         sg.InputText(enable_events=True, key='url')
     ],
             [
                 sg.Text('Request type: ', size=(15, 1)),
                 sg.Combo(values=['GET', 'POST'],
                          default_value='GET',
                          readonly=True,
                          auto_size_text=True,
                          enable_events=True,
                          key='http_request')
             ],
             [
                 sg.Frame(
                     'Data',
                     layout=[[
                         sg.Text('Cover data', size=(8, 1)),
                         sg.Input(key='http_cover'),
                         sg.FileBrowse()
                     ],
                             [
                                 sg.Text('Secret data', size=(8, 1)),
                                 sg.Input(key='http_secret'),
                                 sg.FileBrowse()
                             ],
                             [
                                 sg.Checkbox('RSTEG',
                                             key='rsteg',
                                             enable_events=True),
                                 sg.Text('Retransmission probability'),
                                 sg.InputText(default_text='0.07',
                                              enable_events=True,
                                              key='rprob')
                             ]],
                     visible=False,
                     key='post_details')
             ]],
     visible=False,
     key='http_frame')
Exemple #23
0
        sg.InputText(key="_copy_location_", visible=False, enable_events=True),
        sg.FolderBrowse("Copy", key="_main_copy_"),
        sg.InputText(key="_zip_location_", visible=False, enable_events=True),
        sg.FolderBrowse("Zip", key="_main_zip_"),
    ],
]
frm_layout_config = [[
    sg.Button("Set Extensions", key="_config_set_extensions_"),
    sg.Button("Set Blacklist", key="_config_set_blacklist_"),
    sg.Button("Set Whitelist", key="_config_set_whitelist_"),
    sg.Button("Set Logfile", key="_config_set_logfile_"),
]]

### FRAMES ###
frm_main = sg.Frame(title="Main",
                    layout=frm_layout_main,
                    key="_frm_main_",
                    visible=True)

frm_config = sg.Frame(title="Config",
                      layout=frm_layout_config,
                      key="_frm_config_",
                      visible=True)

frm_tools_name = sg.Frame(
    title="Change Filenames",
    layout=[[sg.T("Tools_Name")]],
    key="_frm_tools_name_",
    visible=False,
)
frm_tools_afx = sg.Frame(
    title="Apply Audio FX",
               sg.Text('Path to output sound tracks'),
               sg.In(o_sound, size=(40, 1), key='outputSound'),
               sg.FileSaveAs(size=(75, 30))
           ], [sg.Button('Extract Sound', size=(100, 30))]]

layout = [[
    sg.Column(layout1, key='-COLYOLO-'),
    sg.Column(layout2, visible=False, key='-COLSound-')
],
          [
              sg.Frame(layout=[
                  [
                      sg.Button('YOLO', size=(50, 30)),
                      sg.Button('Sound', size=(60, 30)),
                      sg.Button('YOLO Saved Frames', size=(200, 30)),
                      sg.Button('Exit', size=(50, 30))
                  ],
              ],
                       title='Options',
                       title_color='red',
                       relief=sg.RELIEF_SUNKEN)
          ]]

win = sg.Window('Psychic CCTV',
                default_element_size=(21, 1),
                text_justification='right',
                auto_size_text=False).Layout(layout)

layoutVis = 'YOLO'
while True:
    event, values = win.Read()
Exemple #25
0
    ], [sg.Text('Spinner', size=(200, 35)),
        sg.Spin([1, 2, 3], size=(40, 30))],
    [
        sg.Text('Checkbox', size=(200, 35)),
        sg.Checkbox('Checkbox', change_submits=True)
    ], [sg.Text('RadioButton', size=(200, 35)),
        sg.Radio('Radio Button', 1)],
    [sg.Text('Slider', size=(200, 35)),
     sg.Slider(orientation='h')],
    [sg.Text('Button', size=(200, 35)),
     sg.Button('Button')],
    [sg.Text('Table', size=(200, 35)),
     sg.Table([[0, 1, 3, 4]])],
    [
        sg.Text('Frame', size=(200, 35)),
        sg.Frame('Frame', [[sg.T('')], [sg.T('')]])
    ], [sg.Text('Stdout Output', size=(200, 35)),
        sg.Output(size=(200, 75))],
    [sg.Text('Dial', size=(200, 35)),
     sg.Dial(size=(150, 75)),
     sg.Stretch()], [sg.Button('Blank'), sg.Button('Exit')]
]

window = sg.Window('Window Title', font=('Helvetica', 13)).Layout(layout)

while True:  # Event Loop
    event, values = window.Read()
    print(event, values)
    if event is None or event == 'Exit':
        break
def pick_a_TC(instrument):
    ''' Graphical User interface - prompts the user for instrument, command and value
        then calls MakeTCfile to assemble the TC file based on the users choices '''
    params, enums, defaults, num_vals, val_max, val_min, notes = read_parameter_file(
        tc_filename, instrument)
    param_layout = [[
        sg.Listbox(values=params,
                   key='_param_',
                   tooltip='Select command to send',
                   size=(20, 6),
                   font=Font)
    ]]
    #param_layout = [[sg.InputCombo(values=params, key = '_param_',  font = Font)]]

    layout_pick_parameter = [
        [sg.Frame('Select Parameter to Update: ', param_layout, font=Font)],
        #[sg.Frame('Input new value: ', value_layout, font = Font)],
        [
            sg.Submit(font=Font, pad=(10, 10)),
            sg.Cancel(font=Font, pad=(10, 10))
        ]
    ]

    param_window = sg.Window('Select Parameter', layout_pick_parameter)
    event, values = param_window.Read()
    param_window.Close()

    tcString = values['_param_'][0]
    print(tcString)

    indx = 0
    enumeration = 999
    for words in params:
        if words == tcString:
            enumeration = enums[indx]
            break
        else:
            indx += 1

    if num_vals[indx] == 0:
        confirm_layout = [[sg.Text('Confirm: ' + notes[indx], font=Font)],
                          [
                              sg.Submit(pad=(10, 10), font=Font),
                              sg.Cancel(pad=(10, 10), font=Font)
                          ]]
        confirm_window = sg.Window('Confirm Command', confirm_layout)

        event, values = confirm_window.Read()
        confirm_window.Close()

        if event is None or event == 'Cancel':
            return None, None
        if event == 'Submit':
            filename = instrument + time.strftime("%Y%m%d-%H%M%S") + '.tc'
            cmnd = str(enumeration) + ';'
            MakeTCFile(filename, cmnd)

            send_layout = [[
                sg.Text('Command is valid: ' + cmnd + '. Save or send now',
                        font=Font)
            ],
                           [
                               sg.Button(button_text='Save TC File',
                                         pad=(10, 10),
                                         font=Font),
                               sg.Button(button_text='Send TC to CCMz',
                                         pad=(10, 10),
                                         font=Font)
                           ]]
            send_window = sg.Window('Send TC', send_layout)
            event, values = send_window.Read()
            send_window.Close()
            if event == 'Send TC to CCMz':
                desc = notes[indx].split(':')[0]
                SendTC(filename, instrument, desc)
            else:
                sg.Popup('Values within range \nWriting ' + cmnd + '\nTo: ' +
                         instrument + ' TC file: ' + filename,
                         font=Font)
        return True, 0, filename

    if num_vals[indx] == 1:
        value_layout = [
            [sg.Text(notes[indx], font=Font)],
            [sg.Text('Default Value ' + str(defaults[indx]), font=Font)],
            [sg.Text('Value:', font=Font),
             sg.InputText(key='_val_')]
        ]
        layout_enter_value = [[
            sg.Frame('Input new value: ', value_layout, font=Font)
        ],
                              [
                                  sg.Submit(font=Font, pad=(10, 10)),
                                  sg.Cancel(font=Font, pad=(10, 10))
                              ]]

        value_window = sg.Window('Enter Value', layout_enter_value)
        event, values = value_window.Read()
        value_window.Close()

        new_param_value = float(values['_val_'])
        print(new_param_value)

        if new_param_value < float(val_max[indx]) and new_param_value > float(
                val_min[indx]):
            print('New value is within range')
        else:
            sg.Popup('Value(s) out of Range!\nNo TC File Created', font=Font)
            print('New Value out of Range!')
            return 'error', 0

        filename = instrument + time.strftime("%Y%m%d-%H%M%S") + '.tc'
        cmnd = str(enumeration) + ',' + str(new_param_value) + ';'
        MakeTCFile(filename, cmnd)

        send_layout = [[
            sg.Text('Command is valid: ' + cmnd + '. Save or send now',
                    font=Font)
        ],
                       [
                           sg.Button(button_text='Save TC File',
                                     pad=(10, 10),
                                     font=Font),
                           sg.Button(button_text='Send TC to CCMz',
                                     pad=(10, 10),
                                     font=Font)
                       ]]
        send_window = sg.Window('Send TC', send_layout)
        event, values = send_window.Read()
        send_window.Close()
        if event == 'Send TC to CCMz':
            desc = notes[indx].split(':')[0] + ': ' + str(new_param_value)
            SendTC(filename, instrument, desc)
        else:
            sg.Popup('Values within range \nWriting ' + cmnd + '\nTo: ' +
                     instrument + ' TC file: ' + filename,
                     font=Font)
        return True, 1, filename

    if num_vals[indx] == 2:
        value_layout = [
            [sg.Text(notes[indx], font=Font)],
            [
                sg.Text('Default Value ' + str(defaults[indx]) +
                        'No Limit Checking for values!',
                        font=Font)
            ], [sg.Text('Value 1:', font=Font),
                sg.InputText(key='_val1_')],
            [sg.Text('Value 2:', font=Font),
             sg.InputText(key='_val2_')]
        ]

        layout_enter_value = [[
            sg.Frame('Input new value: ', value_layout, font=Font)
        ],
                              [
                                  sg.Submit(font=Font, pad=(10, 10)),
                                  sg.Cancel(font=Font, pad=(10, 10))
                              ]]

        value_window = sg.Window('Enter Value', layout_enter_value)
        event, values = value_window.Read()
        value_window.Close()

        new_param_value_1 = float(values['_val1_'])
        new_param_value_2 = float(values['_val2_'])

        if new_param_value_1 < int(val_max[indx]) and new_param_value_1 > int(
                val_min[indx]):
            print('Value one is within range')
        if new_param_value_2 < int(val_max[indx]) and new_param_value_2 > int(
                val_min[indx]):
            print('Value two is within range')
        else:
            sg.Popup('Value(s) out of Range!\nNo TC File Created', font=Font)
            print('Value out of Range!')
            return 'error', 0

        filename = instrument + time.strftime("%Y%m%d-%H%M%S") + '.tc'
        cmnd = str(enumeration) + ',' + str(new_param_value_1) + ',' + str(
            new_param_value_2) + ';'
        MakeTCFile(filename, cmnd)

        send_layout = [[
            sg.Text('Command is valid: ' + cmnd + 'save or send now',
                    font=Font)
        ],
                       [
                           sg.Button(button_text='Save TC File',
                                     pad=(10, 10),
                                     font=Font),
                           sg.Button(button_text='Send TC to CCMz',
                                     pad=(10, 10),
                                     font=Font)
                       ]]
        send_window = sg.Window('Send TC', send_layout)
        event, values = send_window.Read()
        send_window.Close()
        if event == 'Send TC to CCMz':
            desc = notes[indx].split(':')[0] + ': ' + str(
                new_param_value_1) + ',' + str(new_param_value_2)
            SendTC(filename, instrument, desc)
        else:
            sg.Popup('Values within range \nWriting ' + cmnd + '\nTo: ' +
                     instrument + ' TC file: ' + filename,
                     font=Font)
        return True, 2, filename

    if num_vals[indx] == 3:
        value_layout = [
            [sg.Text(notes[indx], font=Font)],
            [
                sg.Text('Default Value ' + str(defaults[indx]) +
                        'No Limit Checking for values!',
                        font=Font)
            ], [sg.Text('Value 1:', font=Font),
                sg.InputText(key='_val1_')],
            [sg.Text('Value 2:', font=Font),
             sg.InputText(key='_val2_')],
            [sg.Text('Value 3:', font=Font),
             sg.InputText(key='_val3_')]
        ]

        layout_enter_value = [[
            sg.Frame('Input new value: ', value_layout, font=Font)
        ],
                              [
                                  sg.Submit(font=Font, pad=(10, 10)),
                                  sg.Cancel(font=Font, pad=(10, 10))
                              ]]

        value_window = sg.Window('Enter Value', layout_enter_value)
        event, values = value_window.Read()
        value_window.Close()

        new_param_value_1 = int(values['_val1_'])
        new_param_value_2 = int(values['_val2_'])
        new_param_value_3 = int(values['_val3_'])

        if new_param_value_1 < int(val_max[indx]) and new_param_value_1 > int(
                val_min[indx]):
            print('Value one is within range')
        if new_param_value_2 < int(val_max[indx]) and new_param_value_2 > int(
                val_min[indx]):
            print('Value two is within range')
        if new_param_value_3 < int(val_max[indx]) and new_param_value_3 > int(
                val_min[indx]):
            print('Value three is within range')
        else:
            sg.Popup('Value(s) out of Range!\nNo TC File Created', font=Font)
            print('Value out of Range!')
            return 'error', 0

        filename = instrument + time.strftime("%Y%m%d-%H%M%S") + '.tc'
        cmnd = str(enumeration) + ',' + str(new_param_value_1) + ',' + str(
            new_param_value_2) + ',' + str(new_param_value_3) + ';'
        MakeTCFile(filename, cmnd)
        send_layout = [[
            sg.Text('Command is valid: ' + cmnd + '. Save or send now',
                    font=Font)
        ],
                       [
                           sg.Button(button_text='Save TC File',
                                     pad=(10, 10),
                                     font=Font),
                           sg.Button(button_text='Send TC to CCMz',
                                     pad=(10, 10),
                                     font=Font)
                       ]]
        send_window = sg.Window('Send TC', send_layout)
        event, values = send_window.Read()
        send_window.Close()
        if event == 'Send TC to CCMz':
            desc = notes[indx].split(':')[0] + ': ' + str(
                new_param_value_1) + ',' + str(new_param_value_2) + ',' + str(
                    new_param_value_3)
            SendTC(filename, instrument, desc)
        else:
            sg.Popup('Values within range \nWriting ' + cmnd + '\nTo: ' +
                     instrument + ' TC file: ' + filename,
                     font=Font)
        return True, 3, filename

    if num_vals[indx] == 4:
        value_layout = [
            [sg.Text(notes[indx], font=Font)],
            [
                sg.Text('Default Value ' + str(defaults[indx]) +
                        'No Limit Checking for values!',
                        font=Font)
            ], [sg.Text('Value 1:', font=Font),
                sg.InputText(key='_val1_')],
            [sg.Text('Value 2:', font=Font),
             sg.InputText(key='_val2_')],
            [sg.Text('Value 3:', font=Font),
             sg.InputText(key='_val3_')],
            [sg.Text('Value 4:', font=Font),
             sg.InputText(key='_val4_')]
        ]

        layout_enter_value = [[
            sg.Frame('Input new value: ', value_layout, font=Font)
        ],
                              [
                                  sg.Submit(font=Font, pad=(10, 10)),
                                  sg.Cancel(font=Font, pad=(10, 10))
                              ]]

        value_window = sg.Window('Enter Value', layout_enter_value)
        event, values = value_window.Read()
        value_window.Close()

        new_param_value_1 = int(values['_val1_'])
        new_param_value_2 = int(values['_val2_'])
        new_param_value_3 = int(values['_val3_'])
        new_param_value_4 = int(values['_val4_'])

        if new_param_value_1 < int(val_max[indx]) and new_param_value_1 > int(
                val_min[indx]):
            print('Value one is within range')
        if new_param_value_2 < int(val_max[indx]) and new_param_value_2 > int(
                val_min[indx]):
            print('Value two is within range')
        if new_param_value_3 < int(val_max[indx]) and new_param_value_4 > int(
                val_min[indx]):
            print('Value three is within range')
        if new_param_value_4 < int(val_max[indx]) and new_param_value_3 > int(
                val_min[indx]):
            print('Value four is within range')
        else:
            sg.Popup('Value(s) out of Range!\nNo TC File Created', font=Font)
            print('Value out of Range!')
            return False, 0

        filename = instrument + time.strftime("%Y%m%d-%H%M%S") + '.tc'
        cmnd = str(enumeration) + ',' + str(new_param_value_1) + ',' + str(
            new_param_value_2) + ',' + str(new_param_value_3) + ',' + str(
                new_param_value_4) + ';'
        MakeTCFile(filename, cmnd)
        send_layout = [[
            sg.Text('Command is valid: ' + cmnd + 'save or send now',
                    font=Font)
        ],
                       [
                           sg.Button(button_text='Save TC File',
                                     pad=(10, 10),
                                     font=Font),
                           sg.Button(button_text='Send TC to CCMz',
                                     pad=(10, 10),
                                     font=Font)
                       ]]
        send_window = sg.Window('Send TC', send_layout)
        event, values = send_window.Read()
        send_window.Close()
        if event == 'Send TC to CCMz':
            desc = notes[indx].split(':')[0] + ': ' + str(
                new_param_value_1) + ',' + str(new_param_value_2) + ',' + str(
                    new_param_value_3) + ',' + str(new_param_value_4)
            SendTC(filename, instrument, desc)

        else:
            sg.Popup('Values within range \nWriting ' + cmnd + '\nTo: ' +
                     instrument + ' TC file: ' + filename,
                     font=Font)
        return True, 4, filename

    if num_vals[indx] == 5:
        value_layout = [
            [sg.Text(notes[indx], font=Font)],
            [
                sg.Text('Default Value ' + str(defaults[indx]) +
                        'No Limit Checking for values!',
                        font=Font)
            ], [sg.Text('Value 1:', font=Font),
                sg.InputText(key='_val1_')],
            [sg.Text('Value 2:', font=Font),
             sg.InputText(key='_val2_')],
            [sg.Text('Value 3:', font=Font),
             sg.InputText(key='_val3_')],
            [sg.Text('Value 4:', font=Font),
             sg.InputText(key='_val4_')],
            [sg.Text('Value 5:', font=Font),
             sg.InputText(key='_val5_')]
        ]

        layout_enter_value = [[
            sg.Frame('Input new value: ', value_layout, font=Font)
        ],
                              [
                                  sg.Submit(font=Font, pad=(10, 10)),
                                  sg.Cancel(font=Font, pad=(10, 10))
                              ]]

        value_window = sg.Window('Enter Value', layout_enter_value)
        event, values = value_window.Read()
        value_window.Close()

        new_param_value_1 = int(values['_val1_'])
        new_param_value_2 = int(values['_val2_'])
        new_param_value_3 = int(values['_val3_'])
        new_param_value_4 = int(values['_val4_'])
        new_param_value_5 = int(values['_val5_'])

        if new_param_value_1 < int(val_max[indx]) and new_param_value_1 > int(
                val_min[indx]):
            print('Value one is within range')
        if new_param_value_2 < int(val_max[indx]) and new_param_value_2 > int(
                val_min[indx]):
            print('Value two is within range')
        if new_param_value_3 < int(val_max[indx]) and new_param_value_3 > int(
                val_min[indx]):
            print('Value three is within range')
        if new_param_value_4 < int(val_max[indx]) and new_param_value_4 > int(
                val_min[indx]):
            print('Value four is within range')
        if new_param_value_5 < int(val_max[indx]) and new_param_value_5 > int(
                val_min[indx]):
            print('Value four is within range')
        else:
            sg.Popup('Value(s) out of Range!\nNo TC File Created', font=Font)
            print('Value out of Range!')
            return False, 0

        filename = instrument + time.strftime("%Y%m%d-%H%M%S") + '.tc'
        cmnd = str(enumeration) + ',' + str(new_param_value_1) + ',' + str(
            new_param_value_2) + ',' + str(new_param_value_3) + ',' + str(
                new_param_value_4) + ',' + str(new_param_value_5) + ';'
        MakeTCFile(filename, cmnd)
        send_layout = [[
            sg.Text('Command is valid: ' + cmnd + '. Save or send now',
                    font=Font)
        ],
                       [
                           sg.Button(button_text='Save TC File',
                                     pad=(10, 10),
                                     font=Font),
                           sg.Button(button_text='Send TC to CCMz',
                                     pad=(10, 10),
                                     font=Font)
                       ]]
        send_window = sg.Window('Send TC', send_layout)
        event, values = send_window.Read()
        send_window.Close()
        if event == 'Send TC to CCMz':
            desc = notes[indx].split(':')[0] + ': ' + str(
                new_param_value_1) + ',' + str(new_param_value_2) + ',' + str(
                    new_param_value_3) + ',' + str(
                        new_param_value_4) + ',' + str(new_param_value_5)
            SendTC(filename, instrument, desc)
        else:
            sg.Popup('Values within range \nWriting ' + cmnd + '\nTo: ' +
                     instrument + ' TC file: ' + filename,
                     font=Font)
        return True, 5, filename
def the_gui():
    """Starts and executes the GUI

    Returns when the user exits / closes the window
    """
    ffmpeg_path = Path('ffmpeg_hevc.exe')
    settings_path = Path("settings.json")
    presets = {
        0: "placebo",
        1: "placebo",
        2: "placebo",
        3: "placebo",
        4: "veryslow",
        5: "slower",
        6: "slow",
        7: "medium",
        8: "fast",
        9: "faster",
        10: "veryfast",
        11: "superfast",
        12: "ultrafast"
    }

    # queue used to communicate between the gui and the threads
    gui_queue = queue.Queue()

    encode_queue = queue.Queue()
    encode_list = []

    encode_event = queue.Queue(
    )  # queue for handling when encodes finish and start

    # Define default settings to make it possible to generate settings.json
    settings = {"settings": {"theme": "Default1"}}

    status_deque = deque(maxlen=1)  # deque for handling the status bar element

    check_paths(ffmpeg_path, gui_queue)

    # Load settings from json if it exist
    if settings_path.exists():
        with settings_path.open() as file:
            settings = json.load(file)
            sg.change_look_and_feel(settings["settings"]["theme"])
    else:
        print("Could not find settings.json")
        write_settings(settings_path, settings)

    tooltips = {
        # ENCODE
        "tune":
        "0 = visual quality, 1 = psnr/ssim, 2 = vmaf",
        "preset":
        "Trades speed for quality and compression.\n'Veryfast' and up only works for 1080p or higher, while 'ultrafast' and 'superfast' is 4k and higher only.\nYou might have a file that is just a few pixels away fitting 1080p, and you will be limited to the 'faster' preset or slower\nBest to stay around medium unless you have a godly pc/trash pc",
        "drc":
        "Enables variable bitrate. Lets the encoder vary the targeted quality. \nIf you are unsure, leave it off",
        "qmin":
        "Minimum quality level in DRC mode. Must be lower than qmax",
        "qmax":
        "Maximum quality level in DRC mode. Must be higher than qmin",
        "qp":
        "The quality the encoder will target. Lower values result in higher quality, but much larger filesize. \nUsually stay around 20 for h.264 content, but can often go lower for mpeg2 content. Recommend 22 or 23 for 1080p with high bitrate. \nExperiment with quality by enabling test encode!",
        # FILTERS
        "sharpen":
        "How much to sharpen the image with unsharp, with a moderate impact to encode speed. \nIt is usually a good idea to sharpen the image a bit when transcoding. I recommend about 0.2 to 0.3",
        # AUDIO
        "skip_audio":
        "Enable to skip all audio tracks. Disable to passthrough audio",
        # BUTTONS
        "pause_queue":
        "Once the queue is paused the current job will finish, but the next job will not be started.",
        "start_encode":
        "Add job to queue, start it if no encode is currently running.",
        # MISC
        "test_encode":
        "Only encode part of the video. Lets you compare quality of encode to source, and estimate filesize. \nSpecify how many frames, usually 1000 is enough"
    }

    params = {
        "input": "",
        "output": "",
        "skip_audio": "",
        "qp": 20,
        "subtitles": False,
        "enable_filters": "-vf",
        "drc": 0,
        "qmin": 19,
        "qmax": 21,
        "sharpen_mode": "",
        "crop": "",
        "tune": 0,
        "preset": 7,
        "test_encode": "",
        "n_frames": "1000",
        "start_time": "00:00:00.000",
        "end_time": "",
    }

    old_params = params.copy()

    video_metadata = {
        "contains_video": False,
        "frame_count": None,
        "size": None,
        "fps": None,
        "duration": None,
        "width": None,
        "height": None,
    }

    menu_def = [['&Settings', ['&Themes', '!&Preferences', '---', 'E&xit']],
                ['&Presets', ['!&Save preset', '---', '!Preset1']]]

    drc_col = [
        [
            sg.Checkbox("Dynamic rate control",
                        key="-DRC-",
                        enable_events=True,
                        tooltip=tooltips["drc"])
        ],
        [
            sg.Text("minQP", size=(5, 1), tooltip=tooltips["qmin"]),
            sg.Spin([i for i in range(1, 51)],
                    initial_value=params["qmin"],
                    key="-QMIN-",
                    size=(5, 1),
                    enable_events=True,
                    disabled=True,
                    tooltip=tooltips["qmin"]),
            sg.Text("maxQP", size=(5, 1), tooltip=tooltips["qmax"]),
            sg.Spin([i for i in range(1, 51)],
                    initial_value=params["qmax"],
                    key="-QMAX-",
                    size=(5, 1),
                    enable_events=True,
                    disabled=True,
                    tooltip=tooltips["qmax"]),
        ],
    ]

    encoding_col = [
        [
            sg.Column([
                [sg.Text("Quality", tooltip=tooltips["qp"])],
                [
                    sg.Text("QP", size=(2, 1)),
                    sg.Spin([i for i in range(1, 51)],
                            initial_value=params["qp"],
                            key="-QP-",
                            size=(5, 1),
                            enable_events=True,
                            tooltip=tooltips["qp"])
                ],
            ]),
            sg.VerticalSeparator(),
            sg.Column(drc_col),
            sg.VerticalSeparator(),
            sg.Column([[
                sg.Text("Preset (medium)",
                        size=(10, 1),
                        key="-PRESET_TEXT-",
                        tooltip=tooltips["preset"])
            ],
                       [
                           sg.Slider(range=(0, 12),
                                     default_value=7,
                                     orientation="horizontal",
                                     key="-PRESET-",
                                     enable_events=True,
                                     tooltip=tooltips["preset"])
                       ]]),
            # sg.Column([[sg.Text("Tune", size=(5, 1), tooltip=tooltips["tune"])], [sg.DropDown([0, 1, 2], default_value=0, key="-TUNE-", enable_events=True, tooltip=tooltips["tune"])]])  # Tune is no longer an option
        ],
    ]

    audio_col = [[
        sg.Checkbox("Skip audio",
                    key="-AUDIO-",
                    enable_events=True,
                    default=False,
                    tooltip=tooltips["skip_audio"])
    ]]

    def range_with_floats(start, stop, step):
        """Func for generating a range of decimals"""
        while stop > start:
            yield round(
                start,
                2)  # adding round() to our function and rounding to 2 digits
            start += step

    filter_col = [[
        sg.Checkbox("Sharpen",
                    key="-SHARP_CONTROL-",
                    size=(8, 1),
                    enable_events=True,
                    tooltip=tooltips["sharpen"]),
        sg.Spin([i for i in range_with_floats(-1.50, 1.50, 0.05)],
                key="-SHARPEN-",
                initial_value=0.25,
                size=(6, 1),
                enable_events=True,
                disabled=True,
                tooltip=tooltips["sharpen"])
    ]]

    video_col = [[
        sg.T("Resolution"),
        sg.Input(default_text="WDxHG", disabled=True, key="-RESOLUTION-"),
        sg.T("Crop"),
        sg.Input(key="-CROP-", enable_events=True),
        sg.Button("Autocrop")
    ]]

    layout = [
        [sg.Menu(menu_def)],
        [sg.Text("Browse or drag n drop video file")],
        [
            sg.Text("Input"),
            sg.Input(key="-INPUT-", enable_events=True),
            sg.FileBrowse(enable_events=True)
        ],  #
        [
            sg.Text("Output"),
            sg.Input(key="-OUTPUT-", enable_events=True),
            sg.SaveAs(enable_events=True)
        ],
        [sg.Frame("Encode options", encoding_col)],
        [
            sg.Frame("Audio options", audio_col),
            sg.Frame("Filters", filter_col)
        ],
        [sg.Frame("Video", video_col)],
        [
            sg.Frame("Misc", [[
                sg.Checkbox("Test encode (n frames)",
                            size=(16, 1),
                            key="-TEST_ENCODE-",
                            enable_events=True,
                            tooltip=tooltips["test_encode"]),
                sg.Input(default_text=params["n_frames"],
                         size=(5, 1),
                         enable_events=True,
                         key="-TEST_FRAMES-",
                         disabled=True,
                         tooltip=tooltips["test_encode"])
            ],
                              [
                                  sg.T("Start time", size=(7, 1)),
                                  sg.Input(default_text=params["start_time"],
                                           enable_events=True,
                                           key="-START_TIME-",
                                           size=(9, 1),
                                           tooltip="Start timestamp"),
                                  sg.T("End time", size=(6, 1)),
                                  sg.Input(default_text="00:00:00.000",
                                           enable_events=True,
                                           key="-END_TIME-",
                                           size=(9, 1),
                                           tooltip="End timestamp")
                              ]])
        ],
        # [sg.Frame("Command", [[sg.Column([[sg.Multiline(key="-COMMAND-", size=(60, 3))]])]])],
        [
            sg.Frame("Queue", [[
                sg.Column([[sg.Listbox(values=[], key="-QUEUE_DISPLAY-")],
                           [
                               sg.Button("Remove task", size=(15, 1)),
                               sg.Button("UP", size=(7, 1)),
                               sg.Button("DOWN", size=(7, 1))
                           ]])
            ]])
        ],
        [
            sg.Button("Start encode / add to queue",
                      key="Start encode",
                      size=(20, 1),
                      tooltip=tooltips["start_encode"]),
            sg.Button("Stop encode", size=(20, 1)),
            sg.Button("Pause queue",
                      key="Pause queue",
                      size=(20, 1),
                      tooltip=tooltips["pause_queue"])
        ],
        [sg.T("", key="-STATUS_BOX-")],
        [sg.Output()],  # Disable this line to get output to the console
        # [sg.ProgressBar(100, key="-PROGRESSBAR-")],
        [sg.Button('Exit')],
    ]

    window = sg.Window('SVT_GUI', layout)

    encoder = threading.Thread(target=encode_thread,
                               args=(encode_queue, gui_queue, status_deque,
                                     encode_event),
                               daemon=True)
    try:
        encoder.start()
    except Exception as e:
        print('Error starting work thread. Bad input?\n ' + str(e))

    encode_queue_active.set()  # Start active

    # progressbar = window["-PROGRESSBAR-"]

    def update_command():
        window["-COMMAND-"].update(' '.join(format_command()))

    def format_command():
        input_text = ""
        output_text = ""

        if params["input"] != "":
            input_path = Path(params["input"])
            input_text = str(input_path)

        if params["output"] != "":
            output_path = Path(params["output"])
            output_text = str(output_path)

        enable_filters = params[
            "enable_filters"] if params["sharpen_mode"] != "" or params[
                "crop"] else ""  # todo: Add check for each filter here

        filters = ",".join(
            filter(None, [params["sharpen_mode"], params["crop"]]))
        print("filters: " + (filters if filters else "None"))

        n_frames = params["n_frames"] if params[
            "test_encode"] != "" else ""  # Disable vframes number if we dont want to do test encode

        # Filter list before return to remove empty strings
        return list(
            filter(None, [
                "-i", input_text, "-y", "-ss", params["start_time"],
                ("-to" if params["end_time"] else ""), params["end_time"],
                "-sn", params["skip_audio"], "-map", "0", enable_filters,
                filters, "-c:v", "libsvt_hevc", params["test_encode"],
                n_frames, "-rc",
                str(params["drc"]), "-qmin",
                str(params["qmin"]), "-qmax",
                str(params["qmax"]), "-qp",
                str(params["qp"]), "-preset",
                str(params["preset"]), output_text
            ]))

    def toggle_queue():
        if encode_queue_active.is_set():
            encode_queue_active.clear()
            window.Element("Pause queue").update("Unpause Queue")
        else:
            encode_queue_active.set()
            window.Element("Pause queue").update("Pause Queue")

    def pause_queue():
        if encode_queue_active.is_set():
            encode_queue_active.clear()
            window.Element("Pause queue").update("Unpause Queue")

    def autocrop():
        try:
            # TODO: If the video is shorter than around 16 seconds we might not get any crop values because of the low framerate and start time
            start_time = int(
                (video_metadata["duration"] / 4) /
                1000)  # Start detecting crop at 1/4 of the video duration
            command = [
                ffmpeg_path.absolute().as_posix(), "-ss",
                str(start_time), "-i",
                str(Path(params["input"])), "-t", "01:20", "-vsync", "vfr",
                "-vf", "fps=0.2,cropdetect", "-f", "null", "-"
            ]
            process = subprocess.Popen(command,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.STDOUT,
                                       universal_newlines=True,
                                       close_fds=True)
            # out, err = process.communicate()
            crop_values = []
            for line in process.stdout:
                # print(line)
                if "crop=" in line:
                    crop_values.append(line.split("crop=")[1])

            if len(crop_values) > 0:
                most_common = max(set(crop_values), key=crop_values.count)
                print("CROP: " + most_common)
                if most_common:
                    return most_common
                else:
                    print("Could not generate a crop :(")
                    return ""

        except Exception as ex:
            print(ex.args)
        print("Could not generate a crop :(")
        return ""

    def update_queue_display():
        window.Element("-QUEUE_DISPLAY-").update(values=[
            i["status"] + " | " + i["title"] + " - " + i["uuid"]
            for i in encode_list
        ])

    def build_encode_queue():
        clear_queue(encode_queue)
        for i in encode_list:
            if i["status"] == "⏱ waiting":
                encode_queue.put(i)

    #                                                        #
    # --------------------- EVENT LOOP --------------------- #
    while True:
        event, values = window.read(timeout=100)
        if event in (None, 'Exit'):
            break

        elif event == "-INPUT-":
            window.Element("-INPUT-").update(
                background_color="white")  # Reset background color
            file_string = values["-INPUT-"].replace("file:///", "")
            input_file = Path(file_string)
            if input_file.exists() and input_file.is_file():
                params["input"] = input_file.absolute()  # Update params

                # Fill in output based on folder and filename of input
                new_file = input_file
                while new_file.exists():
                    new_file = Path(
                        new_file.with_name(new_file.stem + "_new.mkv"))
                params["output"] = str(new_file.absolute())
                window.Element("-OUTPUT-").update(str(new_file.absolute()))

                print("** Analyzing input using mediainfo... **")
                media_info = MediaInfo.parse(str(input_file.absolute()))

                for track in media_info.tracks:
                    if track:
                        if track.track_type == "General":
                            video_metadata["name"] = track.file_name_extension
                        elif track.track_type == 'Video':
                            video_metadata["contains_video"] = True
                            video_metadata["frame_count"] = track.frame_count
                            video_metadata["size"] = int(
                                track.stream_size
                            ) / 1048576 if track.stream_size else None  # in MiB
                            video_metadata["fps"] = track.frame_rate
                            video_metadata["width"] = track.width
                            video_metadata["height"] = track.height

                            # Reset the start and end time params
                            params["end_time"] = ""
                            params["start_time"] = "00:00:00.000"

                            if track.height and track.width:
                                window.Element("-RESOLUTION-").update(
                                    "%ix%i" % (track.width, track.height))

                            if track.duration:
                                video_metadata["duration"] = float(
                                    track.duration)

                                # hours, rem = divmod(float(track.duration), 3600)
                                # minutes, seconds = divmod(rem, 60)
                                milliseconds = float(track.duration)
                                seconds = (milliseconds / 1000) % 60
                                minutes = int(
                                    (milliseconds / (1000 * 60)) % 60)
                                hours = int(
                                    (milliseconds / (1000 * 60 * 60)) % 24)
                                formatted_duration = "{:0>2}:{:0>2}:{:06.3f}".format(
                                    hours, minutes, seconds)
                                print("Duration:", formatted_duration)
                                window.Element("-END_TIME-").update(
                                    disabled=False)
                                window.Element("-END_TIME-").update(
                                    formatted_duration)
                            else:
                                window.Element("-END_TIME-").update(
                                    disabled=True)

                if video_metadata["frame_count"] is None and video_metadata[
                        "contains_video"]:
                    print(
                        "Could not extract frame count, will not be able to report progress %"
                    )
                if not video_metadata["contains_video"]:
                    print(
                        "This file is either not a video file or does not contain a video stream."
                    )
                    window.Element("-INPUT-").update(background_color="red")

                print('** Analyze done **')

            else:
                print("Can't find file: " + str(input_file.absolute()))

        elif event == "-OUTPUT-":
            if values[
                    "-OUTPUT-"] == "":  # If the user clicks the saveAs button and cancels, the output string will be empty. Better to keep the old value in that case
                window.Element("-OUTPUT-").update(params["output"])
            else:
                file_string = values["-OUTPUT-"].replace("file:///", "")
                params["output"] = file_string

        ##################
        # ENCODE SETTINGS
        elif event == "-QP-":
            params["qp"] = values["-QP-"]

        elif event == "-DRC-":
            val = values["-DRC-"]
            if val:
                params["drc"] = 1
                window.Element("-QMIN-").update(disabled=False)
                window.Element("-QMAX-").update(disabled=False)
                window.Element("-QP-").update(disabled=True)
            else:
                params["drc"] = 0
                window.Element("-QMIN-").update(disabled=True)
                window.Element("-QMAX-").update(disabled=True)
                window.Element("-QP-").update(disabled=False)

        elif event == "-PRESET-":  # TODO: handle limiting preset by resolution as per https://github.com/OpenVisualCloud/SVT-HEVC/blob/master/Docs/svt-hevc_encoder_user_guide.md#encoding-presets-table
            window.Element("-PRESET_TEXT-").update("Preset ({})".format(
                presets[values["-PRESET-"]]))
            params["preset"] = values["-PRESET-"]

        elif event == "-TEST_ENCODE-":
            val = values["-TEST_ENCODE-"]
            if val:
                window.Element("-TEST_FRAMES-").update(disabled=False)
                params["test_encode"] = "-vframes"
            else:
                window.Element("-TEST_FRAMES-").update(disabled=True)
                params["test_encode"] = ""

        elif event == "-TEST_FRAMES-":
            val = ''.join(
                i for i in values["-TEST_FRAMES-"]
                if i.isdigit())  # Remove any non numbers from the input
            window.Element("-TEST_FRAMES-").update(val)
            params["n_frames"] = val

        elif event == "-START_TIME-":
            params["start_time"] = values["-START_TIME-"]

        elif event == "-END_TIME-":
            params["end_time"] = values["-END_TIME-"]

        ##################
        # AUDIO SETTINGS
        elif event == "-AUDIO-":
            if values["-AUDIO-"]:
                params["skip_audio"] = "-an"
            else:
                params["skip_audio"] = ""

        ##################
        # FILTER SETTINGS
        elif event == "-SHARPEN-":
            params["sharpen_mode"] = "unsharp=5:5:{}:5:5:{}".format(
                values["-SHARPEN-"], values["-SHARPEN-"])

        elif event == "-CROP-":
            if values["-CROP-"]:
                params["crop"] = "crop=" + values["-CROP-"]
            else:
                params["crop"] = ""

        elif event == "-SHARP_CONTROL-":
            if values["-SHARP_CONTROL-"]:
                window.Element("-SHARPEN-").update(disabled=False)
                params["sharpen_mode"] = "unsharp=5:5:{}:5:5:{}".format(
                    values["-SHARPEN-"], values["-SHARPEN-"])
            else:
                window.Element("-SHARPEN-").update(disabled=True)
                params["sharpen_mode"] = ""

        ##################
        # QUEUE BUTTONS
        elif event == "Remove task":
            if values["-QUEUE_DISPLAY-"]:
                for queue_item in values[
                        "-QUEUE_DISPLAY-"]:  # TODO: make alternative to nesting loops
                    job_id = queue_item.split()[-1]
                    for i, job in enumerate(encode_list):
                        if job["uuid"] == job_id and job[
                                "status"] != "▶ started":
                            encode_list.pop(i)

            build_encode_queue()
            update_queue_display()

        elif event == "UP":
            if values["-QUEUE_DISPLAY-"] and len(
                    values["-QUEUE_DISPLAY-"]) == 1 and len(encode_list) > 1:
                job_id = values["-QUEUE_DISPLAY-"][0].split()[-1]
                for i, job in enumerate(encode_list):
                    if job["uuid"] == job_id and i != 0:
                        encode_list.insert(i - 1, encode_list.pop(i))

                build_encode_queue()
                update_queue_display()

        elif event == "DOWN":
            if values["-QUEUE_DISPLAY-"] and len(
                    values["-QUEUE_DISPLAY-"]) == 1 and len(encode_list) > 1:
                job_id = values["-QUEUE_DISPLAY-"][0].split()[-1]
                for i, job in enumerate(encode_list):
                    if job["uuid"] == job_id and i != len(encode_list) - 1:
                        encode_list.insert(i + 1, encode_list.pop(i))

                build_encode_queue()
                update_queue_display()

        ##################
        # OTHER INTERACTS
        elif event == "Start encode":
            if not params["input"] or params["input"] == "":
                print("Missing input")
            elif not params["output"] or params["output"] == "":
                print("Missing output")
            elif not video_metadata["contains_video"]:
                print(
                    "Cannot start encode because input file does not have a video track"
                )
            else:
                finished_command = [ffmpeg_path.absolute().as_posix()
                                    ] + format_command()

                try:
                    job_id = uuid.uuid4().hex
                    encode_list.append({
                        "title":
                        video_metadata["name"],
                        "uuid":
                        job_id,
                        "status":
                        "⏱ waiting",
                        "output_file":
                        Path(params["output"]),
                        "command":
                        finished_command,
                        "metadata":
                        video_metadata,
                        "test_encode":
                        int(params["n_frames"])
                        if params["test_encode"] != "" else False
                    })
                    build_encode_queue()
                    update_queue_display()
                except Exception as e:  # TODO: make this better. Is it even needed?
                    print('Error adding job. Bad input?:\n "%s"' %
                          finished_command)

        elif event == "Stop encode":
            if encoder is not None:
                stoprequest.set()
                pause_queue()

        elif event == "Pause queue":
            toggle_queue()
            encode_queue.put(_skip)

        elif event == "Autocrop":
            crop = autocrop()
            params["crop"] = "crop=" + crop
            window.Element("-CROP-").update(crop)

        elif event == "Themes":
            theme = run_themes_window()
            # Save theme
            if theme and settings_path.exists():
                settings["settings"]["theme"] = theme
                write_settings(settings_path, settings)
                print("Changed theme to {}. Restart the program to apply.".
                      format(theme))

        try:
            window.Element("-STATUS_BOX-").update(status_deque.popleft())
        except IndexError:
            pass

        # --------------- Check for incoming messages from threads  ---------------
        try:
            message = gui_queue.get_nowait()
        except queue.Empty:  # get_nowait() will get exception when Queue is empty
            message = None  # break from the loop if no more messages are queued up

        try:
            # Check for job events
            event = encode_event.get_nowait()
            print(event)
            for i, job in enumerate(encode_list):
                if job["uuid"] == event["uuid"]:
                    item = encode_list[i]
                    item["status"] = event["event"]
                    encode_list[i] = item
                    update_queue_display()
        except queue.Empty:
            pass

        # if message received from queue, display the message in the Window
        if message:
            print("#> " + message)

        # Update display of the encode command
        # if params.items() != old_params.items():
        #     update_command()
        #     old_params = params.copy()

    # We have reached the end of the program, so lets clean up.
    window.disable()
    window.refresh()  # have to refresh window manually outside of event loop
    if encoder is not None:
        stoprequest.set()
        # Clear queue then add sentinel to make thread stop waiting
        clear_queue(encode_queue)
        encode_queue.put(_sentinel)
        encode_queue_active.set(
        )  # We have to make sure the encode queue is active for it to finish, if not it will keep waiting

        print("\n** Taking a sec to shut everything down... **\n")
        window.refresh()

        encoder.join()
        if encoder.is_alive():
            print("Thread still alive! wtf")
            window.refresh()

    window.close()
Exemple #28
0
def create_frame(title: str, layout: list):
    return sg.Frame(title, [layout])
Exemple #29
0
    def system_tray(self, card_present):
        logger.debug('In system_tray')
        self.menu_def = [
            'BLANK',
            [
                '&Setup new Satochip', '&Change PIN', '&Reset seed',
                '&Enable 2FA', '&About', '&Quit'
            ]
        ]

        if card_present:
            self.tray = sg.SystemTray(menu=self.menu_def,
                                      filename=self.satochip_icon)
        else:
            self.tray = sg.SystemTray(menu=self.menu_def,
                                      filename=self.satochip_unpaired_icon)

        while True:
            menu_item = self.tray.Read(timeout=1)
            if menu_item != '__TIMEOUT__':
                logger.debug('Menu item: ' + menu_item)

            ## Setup new Satochip ##
            if menu_item == 'Setup new Satochip':
                self.client.card_init_connect()

            ## Change PIN ##
            elif menu_item == 'Change PIN':
                msg_oldpin = ("Enter the current PIN for your Satochip:")
                msg_newpin = ("Enter a new PIN for your Satochip:")
                msg_confirm = ("Please confirm the new PIN for your Satochip:")
                msg_error = (
                    "The PIN values do not match! Please type PIN again!")
                msg_cancel = ("PIN change cancelled!")
                (is_PIN, oldpin, newpin) = self.client.PIN_change_dialog(
                    msg_oldpin, msg_newpin, msg_confirm, msg_error, msg_cancel)
                if not is_PIN:
                    continue
                else:
                    oldpin = list(oldpin)
                    newpin = list(newpin)
                    (response, sw1,
                     sw2) = self.client.cc.card_change_PIN(0, oldpin, newpin)
                    if (sw1 == 0x90 and sw2 == 0x00):
                        msg = ("PIN changed successfully!")
                        self.show_success(msg)
                    else:
                        msg = (
                            f"Failed to change PIN with error code: {hex(sw1)}{hex(sw2)}"
                        )
                        self.show_error(msg)

            ## Reset seed ##
            elif menu_item == 'Reset seed':
                msg = ''.join([
                    ("WARNING!\n"),
                    ("You are about to reset the seed of your Satochip. This process is irreversible!\n"
                     ),
                    ("Please be sure that your wallet is empty and that you have a backup of the seed as a precaution.\n\n"
                     ), ("To proceed, enter the PIN for your Satochip:")
                ])
                (event, values) = self.reset_seed_dialog(msg)
                if event == 'Cancel':
                    msg = ("Seed reset cancelled!")
                    self.show_message(msg)
                    continue

                pin = values['pin']
                reset_2FA = values['reset_2FA']
                pin = list(pin.encode('utf8'))

                # if 2FA is enabled, get challenge-response
                hmac = []
                try:  # todo: check if is_seeded
                    self.client.cc.card_bip32_get_authentikey()
                    self.client.cc.is_seeded = True
                except UninitializedSeedError:
                    self.client.cc.is_seeded = False
                if self.client.cc.needs_2FA and self.client.cc.is_seeded:
                    # challenge based on authentikey
                    authentikeyx = bytearray(
                        self.client.cc.parser.authentikey_coordx).hex()

                    # format & encrypt msg
                    import json
                    msg = {
                        'action': "reset_seed",
                        'authentikeyx': authentikeyx
                    }
                    msg = json.dumps(msg)
                    (id_2FA,
                     msg_out) = self.client.cc.card_crypt_transaction_2FA(
                         msg, True)
                    d = {}
                    d['msg_encrypt'] = msg_out
                    d['id_2FA'] = id_2FA
                    # logger.debug("encrypted message: "+msg_out)

                    #do challenge-response with 2FA device...
                    self.show_message(
                        '2FA request sent! Approve or reject request on your second device.'
                    )
                    Satochip2FA.do_challenge_response(d)
                    # decrypt and parse reply to extract challenge response
                    try:
                        reply_encrypt = d['reply_encrypt']
                    except Exception as e:
                        self.show_error("No response received from 2FA...")
                        continue
                    reply_decrypt = self.client.cc.card_crypt_transaction_2FA(
                        reply_encrypt, False)
                    logger.debug("challenge:response= " + reply_decrypt)
                    reply_decrypt = reply_decrypt.split(":")
                    chalresponse = reply_decrypt[1]
                    hmac = list(bytes.fromhex(chalresponse))

                # send request
                (response, sw1,
                 sw2) = self.client.cc.card_reset_seed(pin, hmac)
                if (sw1 == 0x90 and sw2 == 0x00):
                    msg = (
                        "Seed reset successfully!\nYou can launch the wizard to setup your Satochip"
                    )
                    self.show_success(msg)
                else:
                    msg = (
                        f"Failed to reset seed with error code: {hex(sw1)}{hex(sw2)}"
                    )
                    self.show_error(msg)

                # reset 2FA
                if reset_2FA and self.client.cc.needs_2FA:
                    # challenge based on ID_2FA
                    # format & encrypt msg
                    import json
                    msg = {'action': "reset_2FA"}
                    msg = json.dumps(msg)
                    (id_2FA,
                     msg_out) = self.client.cc.card_crypt_transaction_2FA(
                         msg, True)
                    d = {}
                    d['msg_encrypt'] = msg_out
                    d['id_2FA'] = id_2FA
                    # _logger.info("encrypted message: "+msg_out)

                    #do challenge-response with 2FA device...
                    self.client.handler.show_message(
                        '2FA request sent! Approve or reject request on your second device.'
                    )
                    Satochip2FA.do_challenge_response(d)
                    # decrypt and parse reply to extract challenge response
                    try:
                        reply_encrypt = d['reply_encrypt']
                    except Exception as e:
                        self.show_error("No response received from 2FA...")
                    reply_decrypt = self.client.cc.card_crypt_transaction_2FA(
                        reply_encrypt, False)
                    logger.debug("challenge:response= " + reply_decrypt)
                    reply_decrypt = reply_decrypt.split(":")
                    chalresponse = reply_decrypt[1]
                    hmac = list(bytes.fromhex(chalresponse))

                    # send request
                    (response, sw1,
                     sw2) = self.client.cc.card_reset_2FA_key(hmac)
                    if (sw1 == 0x90 and sw2 == 0x00):
                        self.client.cc.needs_2FA = False
                        msg = ("2FA reset successfully!")
                        self.show_success(msg)
                    else:
                        msg = (
                            f"Failed to reset 2FA with error code: {hex(sw1)}{hex(sw2)}"
                        )
                        self.show_error(msg)

            ## Enable 2FA ##
            elif menu_item == 'Enable 2FA':
                self.client.init_2FA()
                continue

            ## About ##
            elif menu_item == 'About':
                #copyright
                msg_copyright = ''.join([
                    '(c)2020 - Satochip by Toporin - https://github.com/Toporin/ \n',
                    "This program is licensed under the GNU Lesser General Public License v3.0 \n",
                    "This software is provided 'as-is', without any express or implied warranty.\n",
                    "In no event will the authors be held liable for any damages arising from \n"
                    "the use of this software."
                ])
                #sw version
                # v_supported= (CardConnector.SATOCHIP_PROTOCOL_MAJOR_VERSION<<8)+CardConnector.SATOCHIP_PROTOCOL_MINOR_VERSION
                # sw_rel= str(CardConnector.SATOCHIP_PROTOCOL_MAJOR_VERSION) +'.'+ str(CardConnector.SATOCHIP_PROTOCOL_MINOR_VERSION)
                v_supported = (SATOCHIP_PROTOCOL_MAJOR_VERSION <<
                               8) + SATOCHIP_PROTOCOL_MINOR_VERSION
                sw_rel = str(SATOCHIP_PROTOCOL_MAJOR_VERSION) + '.' + str(
                    SATOCHIP_PROTOCOL_MINOR_VERSION)
                fw_rel = "N/A"
                is_seeded = "N/A"
                needs_2FA = "N/A"
                needs_SC = "N/A"
                msg_status = (
                    "Card is not initialized! \nClick on 'Setup new Satochip' in the menu to start configuration."
                )

                (response, sw1, sw2, status) = self.client.cc.card_get_status()
                if (sw1 == 0x90 and sw2 == 0x00):
                    #hw version
                    v_applet = (status["protocol_major_version"] <<
                                8) + status["protocol_minor_version"]
                    fw_rel = str(status["protocol_major_version"]) + '.' + str(
                        status["protocol_minor_version"])
                    # status
                    if (v_supported < v_applet):
                        msg_status = (
                            'The version of your Satochip is higher than supported. \nYou should update Satochip-Bridge!'
                        )
                    else:
                        msg_status = 'Satochip-Bridge is up-to-date'
                    # needs2FA?
                    if len(response) >= 9 and response[8] == 0X01:
                        needs_2FA = "yes"
                    elif len(response) >= 9 and response[8] == 0X00:
                        needs_2FA = "no"
                    else:
                        needs_2FA = "unknown"
                    #is_seeded?
                    if len(response) >= 10:
                        is_seeded = "yes" if status["is_seeded"] else "no"
                    else:  #for earlier versions
                        try:
                            self.client.cc.card_bip32_get_authentikey()
                            is_seeded = "yes"
                        except UninitializedSeedError:
                            is_seeded = "no"
                        except Exception:
                            is_seeded = "unknown"
                    # secure channel
                    if status["needs_secure_channel"]:
                        needs_SC = "yes"
                    else:
                        needs_SC = "no"
                else:
                    msg_status = 'No card found! please insert card!'

                frame_layout1 = [[
                    sg.Text('Supported Version: ', size=(20, 1)),
                    sg.Text(sw_rel)
                ],
                                 [
                                     sg.Text('Firmware Version: ',
                                             size=(20, 1)),
                                     sg.Text(fw_rel)
                                 ],
                                 [
                                     sg.Text('Wallet is seeded: ',
                                             size=(20, 1)),
                                     sg.Text(is_seeded)
                                 ],
                                 [
                                     sg.Text('Requires 2FA: ', size=(20, 1)),
                                     sg.Text(needs_2FA)
                                 ],
                                 [
                                     sg.Text('Uses Secure Channel: ',
                                             size=(20, 1)),
                                     sg.Text(needs_SC)
                                 ]]
                frame_layout2 = [[
                    sg.Text(msg_status,
                            justification='center',
                            relief=sg.RELIEF_SUNKEN)
                ]]
                frame_layout3 = [[
                    sg.Text(msg_copyright,
                            justification='center',
                            relief=sg.RELIEF_SUNKEN)
                ]]
                layout = [[
                    sg.Frame('Satochip',
                             frame_layout1,
                             font='Any 12',
                             title_color='blue')
                ],
                          [
                              sg.Frame('Satochip status',
                                       frame_layout2,
                                       font='Any 12',
                                       title_color='blue')
                          ],
                          [
                              sg.Frame('About Satochip-Bridge',
                                       frame_layout3,
                                       font='Any 12',
                                       title_color='blue')
                          ], [sg.Button('Ok')]]

                window = sg.Window('Satochip-Bridge: About',
                                   layout,
                                   icon=self.satochip_icon)
                event, value = window.read()
                window.close()
                del window
                continue

            ## Quit ##
            elif menu_item in (None, 'Quit'):
                break

            # check for handle requests from client through the queue
            self.reply()

        # exit after leaving the loop
        #sys.exit() # does not finish background thread
        os._exit(
            0
        )  # kill background thread but doesn't let the interpreter do any cleanup before the process dies
Exemple #30
0
]

mod_layout = [
    [sg.Listbox(key="pwads", values=pwadList, size=(50, 5))],
    [sg.FilesBrowse("Add", key="Add", target=(
        "Add"), enable_events=True, file_types=(("PWAD Files", "*.wad;*.pk3"),)), sg.Button("Remove"), sg.Button("Clear"), sg.Text("", visible=False), sg.Button("▲"), sg.Button("▼")]
]

sessions_layout = [
    [sg.Listbox(key="session_list", values=sessionsListBox, size=(50, 5))],
    [sg.Button("Select"), sg.InputText(
        default_text="", key="session_name", do_not_clear=True), sg.Button("Rename"), sg.Button("Delete")]
]

layout = [
    [sg.Frame("Game", game_layout)],
    [sg.Frame("PWADs", mod_layout)],
    [sg.Text("Arguments"), sg.InputText(
        default_text=configList[4], key="arguments", do_not_clear=True)],
    [sg.Button("Create"), sg.FileSaveAs("Save Config", key="SaveConfig", target=("SaveConfigStore"), enable_events=True, file_types=(("XML Files", "*.xml"),)),
     sg.FileBrowse("Load Config", key="LoadConfig", target=(
         "LoadConfigStore"), enable_events=True, file_types=(("XML Files", "*.xml"),)),
     sg.Button("Oblige")],
    [sg.Text("Oblige Map: "), sg.InputText(default_text=configList[5],
                                           key="output", do_not_clear=True, disabled=True)],
    [sg.InputText("SaveConfigStore", key="SaveConfigStore", visible=False, enable_events=True), sg.InputText(
        "LoadConfigStore", key="LoadConfigStore", visible=False, enable_events=True)],
    [sg.Frame("Sessions", sessions_layout)],
    [sg.Button("Play")]
]