def main_window(): layout = \ [ # text title [sg.Text('wikipedia', justification='center', font=('Helvetica', '16'))], # Multiline the Output details [sg.ML("", size=(40, 100), key='-text_ml1-', disabled=False), sg.Col( [ # Label [sg.Text('Search', background_color=sg.DEFAULT_BACKGROUND_COLOR, size=(10, 1))], # Input for search [sg.In(key="-input1-", text_color="grey20")], # Button Submit and exit [sg.Submit('OK'), sg.Exit()], # List Boxs for ==> like Did you mean these are wholesale [sg.Listbox([], size=(20, 50), key='-listbox1-', no_scrollbar=True)] ] )], ] # window main window = sg.Window('wikipedia', layout=layout, font=('Helvetica', '13'), size=(700, 700)) return window
def make_tab(word): return [[ sg.Column(layout=[ [sg.T('debug', font=my_font, text_color='blue')], [sg.ML(size=(70 - 15, 15), key=f'-{word}-debug-')], [sg.T('error', font=my_font, text_color='red')], [sg.ML(size=(70 - 15, 15), key=f'-{word}-error-')], ]), sg.T(' '), sg.Column(layout=[ [sg.T('warning', font=my_font2)], [sg.ML(size=(70 - 12, 15), key=f'-{word}-warning-')], [sg.T('info', font=my_font2)], [sg.ML(size=(70 - 12, 15), key=f'-{word}-info-')], ]), sg.Column(layout=[ [sg.T('warning_info', font=my_font3)], [sg.ML(size=(110, 42 - 8), key=f'-{word}-warning_info-')], ]), ]]
def ChatBotWithHistory(): # ------- Make a new Window ------- # # give our form a spiffy set of colors sg.theme('GreenTan') layout = [[sg.Text('Your output will go here', size=(40, 1))], [sg.Output(size=(127, 30), font=('Helvetica 10'))], [sg.Text('Command History'), sg.Text('', size=(20, 3), key='history')], [sg.ML(size=(85, 5), enter_submits=True, key='query', do_not_clear=False), sg.Button('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True), sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]] window = sg.Window('Chat window with history', layout, default_element_size=(30, 2), font=('Helvetica', ' 13'), default_button_element_size=(8, 2), return_keyboard_events=True) # ---===--- Loop taking in user input and using it --- # command_history = [] history_offset = 0 while True: event, value = window.read() if event == 'SEND': query = value['query'].rstrip() # EXECUTE YOUR COMMAND HERE print('The command you entered was {}'.format(query)) command_history.append(query) history_offset = len(command_history)-1 # manually clear input because keyboard events blocks clear window['query'].update('') window['history'].update('\n'.join(command_history[-3:])) elif event in (sg.WIN_CLOSED, 'EXIT'): # quit if exit event or X break elif 'Up' in event and len(command_history): command = command_history[history_offset] # decrement is not zero history_offset -= 1 * (history_offset > 0) window['query'].update(command) elif 'Down' in event and len(command_history): # increment up to end of list history_offset += 1 * (history_offset < len(command_history)-1) command = command_history[history_offset] window['query'].update(command) elif 'Escape' in event: window['query'].update('')
def make_window(loc): text_font = sg.user_settings_get_entry('-font-', '_ 20') text = sg.user_settings_get_entry('-text-', '') alpha = sg.user_settings_get_entry('-alpha-', 1.0) title = sg.user_settings_get_entry('-title-', 'Postit') layout = [[ sg.T(title, text_color='black', background_color='#FFFF88', k='-TITLE-') ], [ sg.ML(text, size=(30, 5), background_color='#FFFF88', no_scrollbar=True, k='-ML-', border_width=0, expand_y=True, expand_x=True, font=text_font), sg.Sizegrip(background_color='#FFFF88') ]] window = sg.Window('Postit', layout, no_titlebar=True, grab_anywhere=True, margins=(0, 0), background_color='#FFFF88', element_padding=(0, 0), location=loc, right_click_menu=[[''], [ 'Edit Me', 'Change Font', 'Alpha', [str(x) for x in range(1, 11)], 'Choose Title', 'Exit', ]], keep_on_top=True, font='_ 20', right_click_menu_font=text_font, resizable=True, finalize=True, alpha_channel=alpha) window.set_min_size(window.size) return window
def ui(): ''' return a PySimpleGUI layout ''' global GLOBAL_my_name T_css = dict(font=("Helvetica", 12)) users = sg.Listbox([], size=(30 - 5, 16), enable_events=True, key='users') message_board = sg.ML(size=(50 - 5, 15), key='messages_board') pm_board = sg.ML(size=(30 - 5, 16), key='pm_board') users_column = sg.Col([[sg.T('Users:', **T_css)], [users]]) message_board_column = sg.Col([[sg.T('Message board', **T_css)], [message_board], [ sg.I(key='message', size=(15, 1)), sg.B('▲ Public', key='public-msg'), sg.B('▲ User', disabled=True, key='private-msg') ]]) pm_column = sg.Col([[sg.T('PM messages', **T_css)], [pm_board]]) layout = [[ sg.T('Your name'), sg.Input(GLOBAL_my_name, **T_css, disabled=True, use_readonly_for_disable=True, size=(30, 1), key='my_name'), sg.B('Change my name...', key='change-my-name') ], [users_column, message_board_column, pm_column]] return layout
def make_tab(word): def tabs(*layouts): return sg.TabGroup([[ sg.Tab(title, lay, key=f'-tab-{word_}-{index}-') for index, (title, word_, lay) in enumerate(layouts) ]]) return [[ sg.Column(layout=[ [sg.T('debug', font=my_font, text_color='grey')], [sg.ML(size=(50 - 15, 15), key=f'-{word}-debug-')], [sg.T('error', font=my_font, text_color='red')], [sg.ML(size=(50 - 15, 15), key=f'-{word}-error-')], ], pad=(0, 0)), sg.T(' '), sg.Column(layout=[ [sg.T('warning', font=my_font2)], [sg.ML(size=(70 - 12, 15), key=f'-{word}-warning-')], [sg.T('info', font=my_font2)], [sg.ML(size=(70 - 12, 15), key=f'-{word}-info-')], ], pad=(0, 0)), tabs(('Text', word, [[ sg.T('warning info', font=my_font3) ], [sg.ML(size=(110, 30), key=f'-{word}-warning_info-')]]), ('Listbox', word, [[sg.T('warning info listbox', font=my_font3)], [ sg.Listbox([], size=(110, 30 - 1), key=f'-{word}-listbox-', enable_events=True, background_color='#ffccaa') ]])) ]]
def TFTGUI(): sg.change_look_and_feel('Reddit') layout = [[sg.Text('TFT Bot', size=(40, 1))], [sg.Output(size=(127, 25), font=('Helvetica 10'))], [sg.Text('Enter the champion that you purchased: '), sg.Text('', size=(20, 3), key='history')], [sg.ML(size=(85, 5), enter_submits=True, key='query', do_not_clear=True), sg.Button('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True), sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]] window = sg.Window('TFT Plugin', layout, default_element_size=(30, 1), no_titlebar=False, resizable=True, grab_anywhere=True, font=('Helvetica', ' 13'), default_button_element_size=(8, 2), return_keyboard_events=True) # ---===--- Loop taking in user input and using it --- # command_history = [] history_offset = 0 while True: event, value = window.read() if event == 'SEND': query = value['query'].rstrip() # EXECUTE YOUR COMMAND HERE print('You entered {}'.format(query)) command_history.append(query) history_offset = len(command_history)-1 # manually clear input because keyboard events blocks clear window['query'].update('') window['history'].update('\n'.join(command_history[-3:])) elif event in (None, 'EXIT'): # quit if exit event or X break
def run_gui(): settings_path = os.path.join(cd, 'setting.json') def clear_empty_top_widget(ui): ''' clear ui to easyily for coping functionality (ctrl+c) ''' ''' # case1 sg.Frame('', key='gridLayout', layout = [ [sg.RButton('PushButton', key='pushButton'), sg.RButton('PushButton', key='pushButton_2')] ]) ''' first_line = ui.split('\n')[0] regex_matched = make_regex( r"^sg.Frame\('',\s?key='.*',\slayout\s=\s\[").match(first_line) if regex_matched and ui[-2:] == '])': new_ui = '[\n' + '\n'.join(ui.split('\n')[1:]).strip() return new_ui[:-1] return ui def update_clear_btn(my_window, my_values, real_value=''): objname = my_values['objname'] if real_value == '' else real_value all_object_names_in_combo = my_window['objs'].Values if my_values[ 'xmlfile'] and objname and objname in all_object_names_in_combo: my_window['convert_btn'].update(disabled=False) my_window['convert_all_events'].update(disabled=False) my_window['convert_btns_events'].update(disabled=False) else: my_window['convert_btn'].update(disabled=True) my_window['convert_all_events'].update(disabled=True) my_window['convert_btns_events'].update(disabled=True) def update_app_settings(): with open(settings_path, 'w', encoding='utf-8') as f: json.dump(_settings, f, ensure_ascii=False, indent=2) def send_board_message(text='*** Done ***', window=None): curr_title = window['message_board'].metadata new_title = '{} | {} '.format(curr_title, text) window['message_board'].TKFrame.config(text=new_title) # counter end -> execute this: def clear_frame(): new_board_message = window['message_board'].metadata window['message_board'].TKFrame.config(text=new_board_message) return {'count': 1, 'finished': clear_frame} def parse_n_load_possible_widgets(myxml_file='', window=None, values={}): ''' возвращает найденые object_names все виджетов ''' if os.path.exists(myxml_file) and os.path.isfile(myxml_file): # get xml with open(myxml_file, 'r', encoding='utf-8') as ff: xml_code = ff.read() # filter object names widgets_regexpattern = make_regex( r"^[ \s]{1,}<(widget)\s?.*?\s?name=\"(.+)\"\/?>", MULTILINE) layouts_regexpattern = make_regex( r"^[ \s]{1,}<(layout)\s?.*?\s?name=\"(.+)\"\/?>", MULTILINE) widgets = [ i.group(2) for i in finditer(widgets_regexpattern, xml_code) ] layouts = [ i.group(2) for i in finditer(layouts_regexpattern, xml_code) ] widgets.sort() layouts.sort() # ##################### # обработка id виджетов # ##################### for i in widgets: if '"' in i: i = i[:i.index('"')] for i in layouts: if '"' in i: i = i[:i.index('"')] # ###### # insert # ###### combo_items = [ '# pick LAYOUTS widgets #', *layouts, '# pick WIDGETS widgets #', *widgets ] window['objs'].update(values=combo_items) update_clear_btn(window, values) el = combo_items[1] if ' ' not in el: window['objname'].update(el) update_clear_btn(window, values, real_value=el) return combo_items else: window['objs'](values=[]) window['objname']('') return [] if os.path.exists(settings_path): try: with open(settings_path, 'r', encoding='utf-8') as f: _settings = json.load(f) except Exception as e: _settings = {'-memento-file-cb-': False, 'xmlfile': ''} update_app_settings() else: _settings = {'-memento-file-cb-': False, 'xmlfile': ''} update_app_settings() ############### ### GUI ### ############### ralign = {'size': (16, 1), "justification": 'r'} main_layout = [ [ sg.T('xml file', **ralign), sg.I(key='xmlfile', size=(35, 2), change_submits=True), sg.FileBrowse(target='xmlfile') ], [ sg.T('target object name', **ralign), sg.I(key='objname', size=(35, 2), change_submits=True) ], [ sg.T('all object names', **ralign), sg.Drop(values=[''], key='objs', size=(34, 1), change_submits=True) ], [ sg.T('', **ralign), sg.B('convert', key='convert_btn', disabled=True), sg.B('convert++\nall events', size=(-1, 2), key='convert_all_events', disabled=True), sg.B('convert++\nbtns events', size=(-1, 2), key='convert_btns_events', disabled=True) ], [ sg.T('options:', **ralign), sg.CB('try convert unknows widgets', True, key='no_bad_widgets') ], ] settings_layout = [ [ sg.CB('Remember path to previous file', False, change_submits=True, key='-memento-file-cb-') ], [ sg.T('Indent size', key='indent_size '), sg.I('1', size=(5, 1), key='indent_size') ], [ sg.T('Indent char', key='indent_char '), sg.I(' ', size=(5, 1), key='indent_char') ], ############ # autoupdate ############ [ sg.Frame('Auto updater', layout=[ [ sg.CB('Enable', False, key='enable_autocompiler', change_submits=True, pad=(0, 0), size=(20, 1)), sg.T('interval(ms)'), sg.Spin(list(range(500, 1000)), initial_value=500, key='autocompile_interval_ms', size=(10, 1), change_submits=True, pad=(0, 0)) ], [sg.T('===========================')], [ sg.T('output folder: ', pad=(0, 0)), sg.I('', key='autotarget_file'), sg.B('copy folder\nfrom input-file', key='copy_xmlfile_btn', size=(10, 2), pad=(0, 0), button_color=('black', 'orange')), sg.FolderBrowse('browse folder...', target='autotarget_file', pad=(0, 0), key='browse_input_file_key') ], [ sg.T('output file name:', pad=(0, 0)), sg.I('untitled_psg.py', key='PSG_OUTPUT_FNAME'), ], ]) ], ] layout = [ [ sg.TabGroup([[ sg.Tab('transpiler', main_layout), sg.Tab('settings', settings_layout) ]]), sg.Frame('Output data', layout=[[ sg.B('Clear output', key='clear_btn'), sg.B('Execute output (used after convert++)', size=(35, 1), disabled=True, key='Try') ], [sg.ML(key='psg_ui_output', size=(70, 20))]], key='message_board', metadata='Output data') ], ] window = sg.Window('Transpiler', layout, auto_size_buttons=False, default_button_element_size=(10, 1), finalize=True, location=(100, 100)) # ##### # setup # ##### if _settings['-memento-file-cb-']: window['-memento-file-cb-'].update(True) window['xmlfile'].update(_settings['xmlfile']) update_app_settings() psg_vals = window(timeout=0)[1] parse_n_load_possible_widgets(psg_vals['xmlfile'].strip(), window, psg_vals) # ######### # variables # ######### timers = [] # ############ # variables: for auto-compile # ############ is_autocompiler_working = False autocompile_interval_ms = psg_vals['autocompile_interval_ms'] p_input_xml_hash = None curr_file_hash = file_hash(psg_vals['xmlfile']) if os.path.exists( psg_vals['xmlfile']) else b'' current_obj_names = [] status = True window['autocompile_interval_ms'](disabled=status) window['autotarget_file'](disabled=status) window['copy_xmlfile_btn'](disabled=status) window['browse_input_file_key'](disabled=status) window['PSG_OUTPUT_FNAME'](disabled=status) while True: if is_autocompiler_working: event, values = window(timeout=autocompile_interval_ms) else: event, values = window(timeout=500) if event in (None, 'Exit'): break # сдежка за таймерами и их работами for a_timer in timers: if a_timer['count'] > 0: a_timer['count'] -= 1 elif a_timer['count'] == 0: a_timer['finished']() timers.remove(a_timer) ################################ # _ _ # # | | (_) # # | | ___ __ _ _ ___ # # | |/ _ \ / _` | |/ __| # # | | (_) | (_| | | (__ # # |_|\___/ \__, |_|\___| # # __/ | # # |___/ # ################################ # ############ # auto compile # ############ is_autocompiler_working = values['enable_autocompiler'] if is_autocompiler_working: autotarget_file_dir = os.path.dirname(values['autotarget_file']) if values['objname'] not in current_obj_names: window['psg_ui_output']( '(autocompiler) Error :\nBad target object name.') elif not os.path.exists(autotarget_file_dir): window['psg_ui_output']( '(autocompiler) Error :\nBad output folder.') elif not os.path.exists(values['xmlfile']): window['psg_ui_output']( '(autocompiler) Error :\nBad input xml file.') else: file_hash_val = file_hash(values['xmlfile']) if not curr_file_hash: # first time output_file = os.path.join(autotarget_file_dir, values['PSG_OUTPUT_FNAME']) psg_ui_code = just_compile(values) writefile(output_file, psg_ui_code) window['psg_ui_output']('compiled!') else: # as usual if curr_file_hash != file_hash_val or event == 'objname': # long output_file = os.path.join(autotarget_file_dir, values['PSG_OUTPUT_FNAME']) psg_ui_code = just_compile(values) writefile(output_file, psg_ui_code) window['psg_ui_output']('compiled!') curr_file_hash = file_hash_val # ########### # sg.I events # ########### # update ms update interval sg.Spin if event == 'autocompile_interval_ms': autocompile_interval_ms = values['autocompile_interval_ms'] if event == 'enable_autocompiler': status = not values['enable_autocompiler'] window['autocompile_interval_ms'](disabled=status) window['autotarget_file'](disabled=status) window['copy_xmlfile_btn'](disabled=status) window['browse_input_file_key'](disabled=status) window['PSG_OUTPUT_FNAME'](disabled=status) if event == 'xmlfile': # remember this file if _settings['-memento-file-cb-']: _settings['xmlfile'] = values['xmlfile'].strip() update_app_settings() obj_names = parse_n_load_possible_widgets( values['xmlfile'].strip(), window, values) current_obj_names = obj_names elif event == 'objs': # add only REAL object names -> those, who not contain ' ' if ' ' not in values['objs']: window['objname'].update(values['objs']) update_clear_btn(window, values, real_value=values['objs']) elif event == 'objname': update_clear_btn(window, values) # ######## # checkbox # ######## if event == '-memento-file-cb-': _settings['-memento-file-cb-'] = values['-memento-file-cb-'] _settings['xmlfile'] = '' if values[ '-memento-file-cb-'] else values['xmlfile'] update_app_settings() # ####### # buttons # ####### elif event == 'clear_btn': window['psg_ui_output'].update('') elif event == 'copy_xmlfile_btn': window['autotarget_file'](os.path.dirname(values['xmlfile']) + '/') elif event == 'convert_btn': ui = just_compile(values) window['psg_ui_output'].update(ui) if ui.startswith('Error:'): # fail timers.append( send_board_message(text='***!!!*** Fail ***!!!***', window=window)) else: # success timers.append( send_board_message(text='*** Done ***', window=window)) elif event == 'convert_all_events': ui = just_compile(values) psg_ui = build_boilerplate(layout=ui, btns_event=False, all_events=True) if ui.startswith('Error:'): # fail window['psg_ui_output'].update(ui) timers.append( send_board_message(text='***!!!*** Fail ***!!!***', window=window)) else: # success window['psg_ui_output'].update(psg_ui) timers.append( send_board_message(text='*** Done ***', window=window)) elif event == 'convert_btns_events': ui = just_compile(values) psg_ui = build_boilerplate(layout=ui, btns_event=True, all_events=False) if ui.startswith('Error:'): # fail window['psg_ui_output'].update(ui) timers.append( send_board_message(text='***!!!*** Fail ***!!!***', window=window)) else: # success window['psg_ui_output'].update(psg_ui) timers.append( send_board_message(text='*** Done ***', window=window)) elif event == 'Try': try: psg_ui = values['psg_ui_output'].strip() psg_ui_lines = psg_ui.split('\n') ''' case 1: import PySimpleGUI as sg ... case 2: sg.Frame('', layout = [ [...], [...], [...], ]) case 3: [ [...], [...], [...], ] ''' if psg_ui.startswith('import PySimpleGUI as sg'): exec(psg_ui) if psg_ui_lines[0].startswith( """sg.Frame('""") and psg_ui_lines[0].endswith( """', layout = ["""): window2 = sg.Window('test', eval(psg_ui)) window2.read() window2.close() if psg_ui_lines[0].startswith( """[""") and psg_ui_lines[-1].endswith("""]"""): possible_ui = eval(psg_ui) possible_ui if type(possible_ui) is list and type( possible_ui[0]) is not list: raise Exception( f"bad ui given. It's not a list of LISTS.") window2 = sg.Window('test', possible_ui) window2.read() window2.close() except Exception as e: sg.popup(str(e)) window.close()
def make_window(): right_click_menu_def = [[], ['Open Github Repo', 'Exit']] pagelayout = [ [sg.Text("Enter the name of the page you would like to scrape.")], [ sg.InputText(size=(40, 1), key='pagename', font="Courier", justification="center") ], [sg.Button("Get Content"), sg.Button("Get HTML", k="PAGE-HTML")], [sg.Text(size=(40, 1))], [sg.Text(size=(65, 1), key="PAGE-STAT", justification="center")], [sg.ML(size=(65, 12), key="PAGE-OUT", font=("Courier", 10))], [sg.Text(size=(40, 1))] ] catlayout = [ [sg.Text("Enter the name of the category you would like to scrape.")], [ sg.Text("Category:", font="Courier"), sg.InputText(size=(30, 1), key='catname', font="Courier") ], [ sg.Button("Get HTML", k="CAT-HTML"), sg.Button("Scrape Subcategories"), sg.Button("Scrape Pages in Category") ], [sg.Text(size=(40, 1))], [sg.Text(size=(65, 1), key="CAT-STAT", justification="center")], [sg.ML(size=(65, 12), key="CAT-OUT", font=("Courier", 10))], [sg.Text(size=(40, 1))] ] searchlayout = [[sg.Text("Search for specific page names here.")], [ sg.InputText(size=(40, 1), key='searchbar', font="Courier", justification="center") ], [sg.Button("Search!")], [sg.Text(size=(40, 1))], [ sg.Text(size=(65, 1), key="SEARCH-STAT", justification="center") ], [ sg.ML(size=(65, 12), key="SEARCH-OUT", font=("Courier", 10), justification="center") ]] settingslayout = [ [sg.Text("Change the theme of the GUI here!")], [ sg.Listbox(values=sg.theme_list(), size=(30, 12), key='THEME_LISTBOX', enable_events=True), sg.Frame('Options (WIP)', font='Courier 15', element_justification='center', layout=[[sg.Text('Output Options', font='Courier')], [ sg.Radio('1 output file', 'RadioOutput', k='1OUT', enable_events=True), sg.Radio('New file for each output', 'RadioOutput', k='MULTIOUT', enable_events=True) ]]) ], [sg.Button("Set Theme")], [sg.Button("Set to Default")] ] aboutlayout = [[sg.Text("")], [ sg.Text("WikiScrapeGui by TetrisKid48", justification='center', font="Courier", size=(40, 1)) ], [ sg.Text("Developed in 2021", justification='center', font="Courier", size=(40, 1)) ], [sg.Text("")], [ sg.Text("Special Thanks to:", justification='center', font="Courier", size=(40, 1)) ], [ sg.Text("PySimpleGui", justification='center', font="Courier", size=(40, 1)) ], [ sg.Text("jgoldsmith", justification='center', font="Courier", size=(40, 1)) ]] mainlayout = [ [ sg.Image('wikiscrapegui.png', pad=((0, 0), (15, 15)), key='LOGO', size=(400, 50)) ], [ sg.TabGroup([[ sg.Tab('Page', pagelayout, element_justification='c'), sg.Tab('Category', catlayout, element_justification='c'), sg.Tab('Search', searchlayout, element_justification='c'), sg.Tab('Settings', settingslayout), sg.Tab('About', aboutlayout, element_justification='c') ]], key='TAB-GROUP', tab_location='top', border_width=10, pad=((10, 10), (10, 10))) ] ] return sg.Window('WikiScrapeGui', size=(600, 500), element_justification='c', icon=iconcode, right_click_menu=right_click_menu_def).Layout(mainlayout)
,sg.Frame('Raw Text', [ [sg.Button('render', key='render4'), sg.Button('render transpose', key='render4 T')] ,[sg.Text('* cols')] ]) ,sg.Frame('QTableWidget', [ [sg.Button('render', key='render2'), sg.Button('render transpose', key='render2 T')] ,[sg.Text('* rows cols')] ]) ] ,[sg.Text('cols:', size=(10, 1)), sg.Input('name city job', key='cols')] ,[sg.Text('rows:', size=(10, 1)), sg.Input('guy1 guy2 guy3', key='rows')] ,[sg.Text('delim', size=(10, 1)), sg.Input('~', key='delim', size=(1, 5))] ,[sg.Column([ [sg.Text('vals:'), sg.ML('Alice~Kiev~Singer\nBob~New-York~Programmer\nFrank~London~Driver', key='vals', size=(40, 10)) ,sg.Text('<==>') ,sg.ML('', key='out', size=(40, 10)), sg.Text(':out')] ])] ,[sg.T(' '*100), sg.Button('Copy to buffer', key='copy buffer')] ]) out = window['out'] while True: event, values = window() if event in ('Exit', None): break print(event) #======
def mini_GUI(): my_font = ("Helvetica", 12) my_font2 = ("Helvetica", 12, "bold") my_font3 = ("Helvetica", 15, "bold") my_font4 = ("Mono", 18, "bold") def make_tab(word): def tabs(*layouts): return sg.TabGroup([[ sg.Tab(title, lay, key=f'-tab-{word_}-{index}-') for index, (title, word_, lay) in enumerate(layouts) ]]) return [[ sg.Column(layout=[ [sg.T('debug', font=my_font, text_color='grey')], [sg.ML(size=(50 - 15, 15), key=f'-{word}-debug-')], [sg.T('error', font=my_font, text_color='red')], [sg.ML(size=(50 - 15, 15), key=f'-{word}-error-')], ], pad=(0, 0)), sg.T(' '), sg.Column(layout=[ [sg.T('warning', font=my_font2)], [sg.ML(size=(70 - 12, 15), key=f'-{word}-warning-')], [sg.T('info', font=my_font2)], [sg.ML(size=(70 - 12, 15), key=f'-{word}-info-')], ], pad=(0, 0)), tabs(('Text', word, [[ sg.T('warning info', font=my_font3) ], [sg.ML(size=(110, 30), key=f'-{word}-warning_info-')]]), ('Listbox', word, [[sg.T('warning info listbox', font=my_font3)], [ sg.Listbox([], size=(110, 30 - 1), key=f'-{word}-listbox-', enable_events=True, background_color='#ffccaa') ]])) ]] settings_layout = [ [ sg.CB('Toggle progressbar', False, enable_events=True, key='toggle_progressbar') ], [ sg.Frame('Text editor', [[ sg.Combo(['pycharm', 'subl'], default_value='subl', enable_events=True, key='_text_editor_combo_') ]]), sg.Frame('Pycharm path:', [[ sg.I( '', size=(40, 1), enable_events=True, key='_PyCharm_path_') ]]) ], [ sg.Frame('⅀∉ Filter "empty tables"', [ [sg.T('''This is for filtering stirng, like:''')], [ sg. T('''Warning ======= We got empty md_table for "EasyPrintClose"''', font='Mono 8') ], [ sg.CB('enable', True, key='checkbox_enable_empty_tables_filter', enable_events=True) ], [ sg.ML('PrintClose\nEasyPrintClose\nmain\ntheme\nRead', size=(30, 10), enable_events=True, key='_filter_empty_tables_ml_') ] ]), sg.Frame('⅀∉ Filter "tkinter class methods"', [ [sg.T('''This is for filtering stirng, like:''')], [ sg. T('''Please, fix ':return:' in 'SetFocus' IF you want to see 'return' row in 'signature table' ''', font='Mono 8') ], [ sg.CB('enable', True, enable_events=True, key='checkbox_enable_filter_tkinter_class_methods') ], [ sg. ML('SetFocus\nSetTooltip\nUpdate\n__init__\nbind\nexpand\nset_cursor\nset_size', size=(30, 10), enable_events=True, key='_filter_tkinter_class_methods_') ] ], visible=not True) ] ] layout = [[ sg.TabGroup([[ sg.Tab('readme logs', make_tab('README')), sg.Tab('Call reference logs', make_tab('CALL_REF')), sg.Tab('General settings', settings_layout) ]]) ]] # ░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░ # ░▒▒▓▓▓ progress bar ▓▓▓▒▒░ # ░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░ from time import sleep from math import pi, sin from itertools import count def next_star(): middle = 100 / 2 for i in (int(sin(i * pi / middle) * middle + middle) for i in count()): yield i psg_module_path = str(sg).split("' from '")[1][:-2] star_bar = sg.Col([ [ sg.ProgressBar(max_value=100, orientation='h', key='_star_bar1_', size=(50, 5), bar_color=('blue', 'yellow')) ], [ sg.ProgressBar(max_value=100, orientation='h', key='_star_bar2_', size=(50, 5), bar_color=('yellow', 'blue')) ], ]) # guia def empty_line(fontsize=12): return [sg.T('', font=('Mono ' + str(fontsize)))] window = sg.Window( 'We are live! Again! --- ' + 'Completed making {}, {}'.format( os.path.basename(README_OFILENAME), os.path.basename(CALL_REFERENCE_OFILENAME)), [ [sg.T(size=(30, 1), key='-compile-time-'), star_bar], empty_line(), [ *md2psg( f'The *Bmagenta*PySimpleGUI** module being processed is *Imagenta*"{psg_module_path}"**' ), sg.B('< open (__init__.py)', key='open_init_file'), sg.B('< open (psg.py)', key='open_psg_file') ], # [sg.T(f'The **PySimpleGUI** module being processed is *"{psg_module_path}"*')], empty_line(), [ sg.B('Run again (F1)', key='-run-'), sg.Col([ [ sg.CB('show time in logs (F2)', False, enable_events=True, key='show_time') ], [ sg.CB('Logs with Color (F3)', True, enable_events=True, key='use_psg_color') ], ]), sg.Col([ empty_line(5), [sg.B('open "db folder"', key='-open_db_folder-')], ]), sg.Frame('', [[ sg.Col([[ *md2psg( 'markdown outputFileName *I*FOR** *B*readme **: ' ), sg.I(README_OFILENAME, key='README_OFILE', size=(25, 1)), sg.B('open in explorer', key='open in explorer_readme'), sg.B('open in text editor', key='open file - readme') ], [ *md2psg( 'markdown outputFileName *I*FOR** *B*call ref**: ' ), sg.I(CALL_REFERENCE_OFILENAME, key='CALL_REF_OFILE', size=(25, 1)), sg.B('open in explorer', key='open in explorer_calref'), sg.B('open in text editor', key='open file - calref') ]]) ]], relief=sg.RELIEF_SUNKEN, border_width=4) ], *layout ], resizable=True, finalize=True, location=(0, 0), return_keyboard_events=True) def update_time_in_GUI(): window['-compile-time-']( datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S.%f')) def update_compilation_in_psg(values): # # ░▒▒▓▓▓▓▓◘ compile ◘▓▓▓▓▓▒▒░ # result_readme__for_txt_n_listbox, result_call_ref__for_txt_n_listbox = compile_all_stuff( use_psg_color=values['use_psg_color'], show_time=values['show_time']) result_readme_txt, result_readme_listbox_items = result_readme__for_txt_n_listbox result_call_ref_txt, result_call_ref_listbox_items = result_call_ref__for_txt_n_listbox # # ░▒▒▓▓▓▓▓◘ define FILTER functions ◘▓▓▓▓▓▒▒░ # badNames = [ i.strip() for i in values['_filter_tkinter_class_methods_'].split('\n') if i.strip() ] badNames = '|'.join(badNames) regex_str1 = rf"fix .:return:. in .({badNames})." badNames = [ i for i in values['_filter_empty_tables_ml_'].split('\n') if i.strip() ] badNames = '|'.join(badNames) regex_str2 = rf'empty md_table for .({badNames}).' def is_valid_regex_LogMessage(msg: str): nonlocal regex_str1, regex_str2 # test 1 - filter tkinter class methods error1_found = False if values[ 'checkbox_enable_filter_tkinter_class_methods'] and ':return:' in msg: error1_found = bool( re.search(regex_str1, msg, flags=re.M | re.DOTALL)) # test 2 - filter "special empty tables" error2_found = False if values[ 'checkbox_enable_empty_tables_filter'] and 'empty md_table for' in msg: error2_found = bool( re.search(regex_str2, msg, flags=re.M | re.DOTALL)) return not error1_found and not error2_found def filter_log_messages(messages): if type(messages) is str: return '\n'.join([ msg for msg in messages.split('\n') if is_valid_regex_LogMessage(msg) ]) raise TypeError # # ▓▓▓ Update GUI ▓▓▓ # # =========== listbox's class ParsingError(object): def __init__(self, log_obj): self.log_obj = log_obj self.text = log_obj['message_text'] def __str__(self): return self.__repr__() def __repr__(self): '''qwe''' # { # 'message_type': 'info', # 'message_text': 'STARTING', # 'message_time': 2, # 'message_metadata': {} # } text = self.log_obj['message_text'] metadata = self.log_obj['message_metadata'] lineno = '' if 'lineno' in metadata.keys(): lineno = "(line:" + str(metadata['lineno']) + ') ' return f'{lineno} {text}' items1 = [ i for i in result_readme_listbox_items if is_valid_regex_LogMessage(i['message_text']) ] items2 = [ i for i in result_call_ref_listbox_items if is_valid_regex_LogMessage(i['message_text']) ] window['-README-listbox-']([ParsingError(i) for i in items1]) window['-CALL_REF-listbox-']([ParsingError(i) for i in items2]) # =========== multitext's def set_it(prefix='CALL_REF', messages_obj=result_call_ref_txt): t_error, t_warning, t_info, t_debug = [ '\n'.join(i) for i in messages_obj[:4] ] t_error = filter_log_messages(t_error) t_warning = filter_log_messages(t_warning) t_info = filter_log_messages(t_info) t_debug = filter_log_messages(t_debug) window[f'-{prefix}-error-'](t_error) window[f'-{prefix}-warning-'](t_warning) window[f'-{prefix}-info-'](t_info) window[f'-{prefix}-debug-'](t_debug) # /// colors warning_info window[f'-{prefix}-warning_info-'].update('') t_warning_info_obj = messages_obj[-1] if values['use_psg_color']: for text, color in t_warning_info_obj: if not is_valid_regex_LogMessage(text): continue window[f'-{prefix}-warning_info-'].print(text, text_color=color) else: window[f'-{prefix}-warning_info-'](t_warning_info_obj) # two calls set_it('README', result_readme_txt) set_it('CALL_REF', result_call_ref_txt) # ~~~~~~~~~~~~ # GUI updating # ~~~~~~~~~~~~ update_time_in_GUI() values = window.read(timeout=0)[1] update_compilation_in_psg(values) p_values = values window['_PyCharm_path_'](APP_CONFIGS['_PyCharm_path_']) window['_text_editor_combo_'].update( set_to_index=APP_CONFIGS['_text_editor_combo_']) # index window['toggle_progressbar'](APP_CONFIGS['toggle_progressbar']) window['checkbox_enable_empty_tables_filter']( APP_CONFIGS['checkbox_enable_empty_tables_filter']) window['_filter_empty_tables_ml_'](APP_CONFIGS['_filter_empty_tables_ml_']) window['checkbox_enable_filter_tkinter_class_methods']( APP_CONFIGS['checkbox_enable_filter_tkinter_class_methods']) window['_filter_tkinter_class_methods_']( APP_CONFIGS['_filter_tkinter_class_methods_']) window['show_time'](APP_CONFIGS['show_time']) window['use_psg_color'](APP_CONFIGS['use_psg_color']) window['README_OFILE'](APP_CONFIGS['README_OFILE']) window['CALL_REF_OFILE'](APP_CONFIGS['CALL_REF_OFILE']) next_val_gen = next_star() my_timeout = None while True: event, values = window(timeout=my_timeout) if event in ('Exit', None): # save to disk # APP_CONFIGS['_PyCharm_path_'] = p_values['_PyCharm_path_'] APP_CONFIGS['_text_editor_combo_'] = 1 if window[ '_text_editor_combo_'].get() == 'subl' else 0 APP_CONFIGS['toggle_progressbar'] = p_values['toggle_progressbar'] APP_CONFIGS['checkbox_enable_empty_tables_filter'] = p_values[ 'checkbox_enable_empty_tables_filter'] APP_CONFIGS['_filter_empty_tables_ml_'] = p_values[ '_filter_empty_tables_ml_'] APP_CONFIGS[ 'checkbox_enable_filter_tkinter_class_methods'] = p_values[ 'checkbox_enable_filter_tkinter_class_methods'] APP_CONFIGS['_filter_tkinter_class_methods_'] = p_values[ '_filter_tkinter_class_methods_'] APP_CONFIGS['show_time'] = p_values['show_time'] APP_CONFIGS['use_psg_color'] = p_values['use_psg_color'] APP_CONFIGS['README_OFILE'] = p_values['README_OFILE'] APP_CONFIGS['CALL_REF_OFILE'] = p_values['CALL_REF_OFILE'] save_configs(APP_CONFIGS) break p_values = values if '__TIMEOUT__' in event: if values['toggle_progressbar']: window['_star_bar1_'].UpdateBar(next(next_val_gen)) window['_star_bar2_'].UpdateBar(next(next_val_gen)) if '__TIMEOUT__' not in event: print('PSG event>', event) if event == 'toggle_progressbar': my_timeout = None if not values['toggle_progressbar'] else 100 if event == '-README-listbox-': metadata = values['-README-listbox-'][0].log_obj[ 'message_metadata'] print(f'metadata = {metadata}') if event == '-CALL_REF-listbox-': ParsingError_obj = values['-CALL_REF-listbox-'][0] metadata = ParsingError_obj.log_obj['message_metadata'] if 'lineno' in metadata.keys(): lineno = metadata['lineno'] texteditor = values['_text_editor_combo_'] psg_module_path_SDK = psg_module_path.replace( '__init__.py', 'PySimpleGUI.py') if 'pycharm' == texteditor: texteditor = values['_PyCharm_path_'] subprocess.Popen( f'"{texteditor}" --line {lineno} "{psg_module_path_SDK}"', shell=True) elif 'subl' == texteditor: subprocess.Popen( f'{texteditor} "{psg_module_path_SDK}:{lineno}"', shell=True) # if event == '-CALL_REF-listbox-': # res = values['-CALL_REF-listbox-'][0] # print(f'res = {res}') if event == '-run-' or 'F1' in event: update_compilation_in_psg(values) # folder if event == '-open_db_folder-': opendir(cd) # folder if event == 'open in explorer_readme': opendir(os.path.dirname(os.path.join(cd, values['README_OFILE']))) if event == 'open in explorer_calref': opendir(os.path.dirname(os.path.join(cd, values['CALL_REF_OFILE']))) # file if event == 'open file - readme': openfile(os.path.join(cd, values['README_OFILE'])) if event == 'open file - calref': openfile(os.path.join(cd, values['CALL_REF_OFILE'])) # file if event == 'open_init_file': openfile(psg_module_path) if event == 'open_psg_file': openfile(psg_module_path.replace('__init__.py', 'PySimpleGUI.py')) # hotkeys if 'F2' in event: window['show_time'](not values['show_time']) if 'F3' in event: window['use_psg_color'](not values['use_psg_color']) window.close()
def ui(): ''' return a PySimpleGUI layout ''' global GLOBAL_my_name T_css = dict(font=("Helvetica", 12)) users = sg.Listbox([], size=(30 - 5, 16), enable_events=True, key='users') message_board = sg.ML(size=(50 - 5, 15), key='messages_board') pm_board = sg.ML(size=(30 - 5, 16), key='pm_board') users_column = sg.Col([[sg.T('Users:', **T_css)], [users]]) message_board_column = sg.Col([[sg.T('Message board', **T_css)], [message_board], [ sg.I(key='message', size=(15, 1)), sg.B('▲ Public', key='public-msg'), sg.B('▲ User', disabled=True, key='private-msg'), sg.B('View cam', key='view_webcam_btn_tab1'), ]]) pm_column = sg.Col([[sg.T('PM messages', **T_css)], [pm_board]]) main_tab = [[ sg.T('Your name'), sg.Input(GLOBAL_my_name, **T_css, disabled=True, use_readonly_for_disable=True, size=(30, 1), key='my_name'), sg.B('Change my name...', key='change-my-name') ], [users_column, message_board_column, pm_column]] # ================= # |=|=|=|=|=|=|=|=| drawing on canvas colors = 'red green blue orange brown'.split() drawing_btns = [ sg.B('', button_color=(color_name, color_name), key=f'color_{color_name}', size=(3, 1)) for color_name in colors ] + [ sg.B('eraser', button_color=('white', 'grey'), key='color_grey', size=(5, 1)), sg.B('X', key='clear_canvas', size=(3, 1)) ] drawing_tab = [ [ sg.Graph(key='public_canvas_element', canvas_size=(400, 400), graph_bottom_left=(0, 0), graph_top_right=(400, 400), background_color='grey', change_submits=True, drag_submits=True, metadata={ 'bg': 'grey', 'pen_color': 'red', 'pen_size': 5 }) ], drawing_btns, ] NUM_LINES = 32 font_size = 6 ml_params = dict(size=(115, NUM_LINES + 5), font=('Courier', font_size), pad=(0, 0), background_color='black', text_color='white') webcam_tab = [[ sg.ML(**ml_params, key='-client-ascii-image-'), sg.ML(**ml_params, key='-my-ascii-image-') ], [ sg.B('X toggle camera', key='send_webcam_btn'), sg.B('X see picked friend', key='view_webcam_btn'), ]] return [[ sg.TabGroup([[ sg.Tab(title, tab_ui, key=f'tab_{title}') for title, tab_ui in zip('chat canvas webcam'.split(' '), [main_tab, drawing_tab, webcam_tab]) ]], key='tabs') ]]
def create_widget(self): # sg.theme('Reddit') # sg.theme('GreenTan') sg.theme('lightgreen1') # define menu menu_def = [['&Help', 'version']] host_layout = [ sg.Radio(k, group_id='hosts', key=k, tooltip=v) for k, v in GDG_MACHINES.items() ] host_layout.insert(0, sg.Radio('None', group_id='hosts', key='host_none')) server_layout = sg.Frame(layout=[ host_layout, [ sg.Text('Others: input hostname or IP'), sg.Input('', key='inp_host', size=(20, 1)), sg.Button('Connect', key='connect'), sg.Text('not connected...', background_color='gray', text_color='blue', key='connected', size=(20, 1)), sg.Button('Disconnect', key='disconnect') ] ], title='GDG connection)') channel_read_layout = sg.Frame( layout=[[ sg.Text('Current delay and width'), sg.Text('00000000.0, 00000000.0, 00000000.0, 00000000.0', key='output_val', text_color='red', size=(56, 1), background_color='gray'), sg.Button('Read', key='read'), ]], title='Channel (delay_A, width_A, delay_B, width_B)') gdg_set_layout = sg.Frame(layout=[[ sg.Frame(layout=[[ sg.Radio('A', 'out_ch', key=key_ch[0], default=True), sg.Radio('B', 'out_ch', key=key_ch[1]) ]], title='Output Channel'), sg.Frame(layout=[[ sg.Radio('None', 'out_type', key=key_type[0], default=True), sg.Radio('Delay', 'out_type', key=key_type[1]), sg.Radio('Width', 'out_type', key=key_type[2]), sg.Input( '000', key='inp_val', tooltip= 'delay value is between 0.1 ~ 15999999.9 us, pulse width is 0.1 us ~ 10 s' ) ]], title='Output Type') ], [ sg.Frame( layout=[[ sg.Radio('None', 'out_mode', key=key_mode[0], default=True), sg.Radio( 'First', 'out_mode', key=key_mode[1]), sg.Radio('Last', 'out_mode', key=key_mode[2]) ]], title='Trigger Mode', tooltip= 'Do not select multi options!' ), sg.Frame( layout=[[ sg.Radio('None', 'out_ctrl', key=key_ctrl[0], default=True), sg.Radio( 'enable', 'out_ctrl', key=key_ctrl[1]), sg.Radio('disable', 'out_ctrl', key=key_ctrl[2]) ]], title='Output Control', tooltip= 'Do not select multi options!' ), sg.Button('Write', button_color=('white', 'blue'), border_width=5, size=(8, 2), font=("Helvetica", 8), key='write') ], [ sg.Frame(layout=[[ sg.Text('Step (us)'), sg.Input('', key='inp_step', size=(10, 1)), sg.Text('duration (sec)'), sg.Input('', key='inp_duration', size=(10, 1)), sg.Button( 'Autorun', button_color=('white', 'blue'), border_width=4, size=(8, 1), font=("Helvetica", 8), key='autorun') ]], title='Auto Run') ]], title='GDG Delay Setting') layout = [[sg.Menu(menu_def, background_color='white')], [server_layout], [channel_read_layout], [gdg_set_layout], [ sg.Frame(title='Log', layout=[[ sg.ML(key='out_log', size=(120, 7), text_color='red') ]]) ], [sg.Button('Exit')]] return sg.Window(self.title, layout=layout)
def run_gui(): settings_path = os.path.join(cd, 'setting.json') def clear_empty_top_widget(ui): ''' clear ui to easyily for coping functionality (ctrl+c) ''' ''' # case1 sg.Frame('', key='gridLayout', layout = [ [sg.RButton('PushButton', key='pushButton'), sg.RButton('PushButton', key='pushButton_2')] ]) ''' first_line = ui.split('\n')[0] regex_matched = make_regex( r"^sg.Frame\('',\s?key='.*',\slayout\s=\s\[").match(first_line) if regex_matched and ui[-2:] == '])': new_ui = '[\n' + '\n'.join(ui.split('\n')[1:]).strip() return new_ui[:-1] return ui def update_clear_btn(my_window, my_values, real_value=''): objname = my_values['objname'] if real_value == '' else real_value all_object_names_in_combo = my_window['objs'].Values if my_values['xmlfile'] and objname and objname in all_object_names_in_combo: my_window['convert_btn'].update(disabled=False) my_window['convert_all_events'].update(disabled=False) my_window['convert_btns_events'].update(disabled=False) else: my_window['convert_btn'].update(disabled=True) my_window['convert_all_events'].update(disabled=True) my_window['convert_btns_events'].update(disabled=True) def update_app_settings(): with open(settings_path, 'w', encoding='utf-8') as f: json.dump(_settings, f, ensure_ascii=False, indent=2) if os.path.exists(settings_path): try: with open(settings_path, 'r', encoding='utf-8') as f: _settings = json.load(f) except Exception as e: _settings = { '-memento-file-cb-': False, 'xmlfile': '' } update_app_settings() else: _settings = { '-memento-file-cb-': False, 'xmlfile': '' } update_app_settings() ############### ### GUI ### ############### ralign = {'size': (16, 1), "justification": 'r'} main_layout = [ [sg.T('xml file', **ralign), sg.I(key='xmlfile', size=(35, 2), change_submits=True), sg.FileBrowse(target='xmlfile')], [sg.T('target object name', **ralign), sg.I(key='objname', size=(35, 2), change_submits=True)], [sg.T('all object names', **ralign), sg.Drop(values=[''], key='objs', size=(34, 1), change_submits=True) ], [ sg.T('', **ralign), sg.B('convert', key='convert_btn', disabled=True), sg.B('convert++\nall events', size=(-1, 2), key='convert_all_events', disabled=True), sg.B('convert++\nbtns events', size=(-1, 2), key='convert_btns_events', disabled=True) ], [ sg.T('options:', **ralign), sg.CB('try convert unknows widgets', True, key='no_bad_widgets') ], ] settings_layout = [ [sg.CB('Remember path to previous file', False, change_submits=True, key='-memento-file-cb-')], [sg.T('Indent size', key='indent_size '), sg.I('1', size=(5, 1), key='indent_size')], [sg.T('Indent char', key='indent_char '), sg.I(' ', size=(5, 1), key='indent_char')], ] layout = [ [ sg.TabGroup([[ sg.Tab('transpiler', main_layout), sg.Tab('settings', settings_layout) ]]), sg.Frame('Output data', layout=[ [sg.B('Clear output', key='clear_btn'), sg.B('Execute output (used after convert++)', size=(35, 1), disabled=True, key='Try')], [sg.ML(key='psg_ui_output', size=(60, 15))] ], key='message_board', metadata='Output data')], ] window = sg.Window('Transpiler', layout, auto_size_buttons=False, default_button_element_size=(10, 1), finalize=True, location=(100, 100)) # setup if _settings['-memento-file-cb-']: window['-memento-file-cb-'].update(True) window['xmlfile'].update(_settings['xmlfile']) timers = [] def send_board_message(text='*** Done ***', window=None): curr_title = window['message_board'].metadata new_title = '{} | {} '.format(curr_title, text) window['message_board'].TKFrame.config(text=new_title) # counter end -> execute this: def clear_frame(): new_board_message = window['message_board'].metadata window['message_board'].TKFrame.config(text=new_board_message) return {'count': 1, 'finished' : clear_frame} # loop prev_values = None first_time_running = True while True: # первый запуск -> подгружка имен из xmlfile, если он есть if first_time_running: event, values = window.read(timeout=0) event = 'xmlfile' first_time_running = False else: event, values = window.read(timeout=500) if event in (None, 'Exit'): break # сдежка за таймерами и их работами for a_timer in timers: if a_timer['count'] > 0: a_timer['count'] -= 1 elif a_timer['count'] == 0: a_timer['finished']() timers.remove(a_timer) ################################ # _ _ # # | | (_) # # | | ___ __ _ _ ___ # # | |/ _ \ / _` | |/ __| # # | | (_) | (_| | | (__ # # |_|\___/ \__, |_|\___| # # __/ | # # |___/ # ################################ indend_size_n_char = int(values['indent_size']), values['indent_char'] prev_values = values if event == '-memento-file-cb-': _settings['-memento-file-cb-'] = values['-memento-file-cb-'] _settings['xmlfile'] = '' if values['-memento-file-cb-'] else values['xmlfile'] update_app_settings() elif event == 'xmlfile': myxml_file = values['xmlfile'].strip() # remember this file if _settings['-memento-file-cb-']: _settings['xmlfile'] = myxml_file update_app_settings() if os.path.exists(myxml_file) and os.path.isfile(myxml_file): # get xml with open(myxml_file, 'r', encoding='utf-8') as ff: xml_code = ff.read() # filter object names widgets_regexpattern = make_regex( r"^[ \s]{1,}<(widget)\s?.*?\s?name=\"(.+)\"\/?>", MULTILINE) layouts_regexpattern = make_regex( r"^[ \s]{1,}<(layout)\s?.*?\s?name=\"(.+)\"\/?>", MULTILINE) widgets = [i.group(2) for i in finditer( widgets_regexpattern, xml_code)] layouts = [i.group(2) for i in finditer( layouts_regexpattern, xml_code)] widgets.sort() layouts.sort() combo_items = ['# pick LAYOUTS widgets #', *layouts, '# pick WIDGETS widgets #', *widgets] # set it window['objs'].update(values=combo_items) update_clear_btn(window, values) el = combo_items[1] if ' ' not in el: window['objname'].update(el) update_clear_btn(window, values, real_value=el) else: window['objs'].update(values=[]) window['objname'].update('') elif event == 'objs': # add only REAL object names -> those, who not contain ' ' if ' ' not in values['objs']: window['objname'].update(values['objs']) update_clear_btn(window, values, real_value=values['objs']) elif event == 'objname': update_clear_btn(window, values) elif event == 'clear_btn': window['psg_ui_output'].update('') elif event == 'convert_btn': ui = just_compile(values, *indend_size_n_char) window['psg_ui_output'].update(ui) if ui.startswith('Error:'): # fail timers.append(send_board_message(text='*** Fail ***', window=window)) else: # success timers.append(send_board_message(text='*** Done ***', window=window)) elif event == 'convert_all_events': ui = just_compile(values, *indend_size_n_char) psg_ui = build_boilerplate(layout=ui, btns_event=False, all_events=True) if ui.startswith('Error:'): # fail window['psg_ui_output'].update(ui) timers.append(send_board_message(text='*** Fail ***', window=window)) else: # success window['psg_ui_output'].update(psg_ui) timers.append(send_board_message(text='*** Done ***', window=window)) elif event == 'convert_btns_events': ui = just_compile(values, *indend_size_n_char) psg_ui = build_boilerplate(layout=ui, btns_event=True, all_events=False) if ui.startswith('Error:'): # fail window['psg_ui_output'].update(ui) timers.append(send_board_message(text='*** Fail ***', window=window)) else: # success window['psg_ui_output'].update(psg_ui) timers.append(send_board_message(text='*** Done ***', window=window)) elif event == 'Try': try: psg_ui = values['psg_ui_output'].strip() psg_ui_lines = psg_ui.split('\n') ''' case 1: import PySimpleGUI as sg ... case 2: sg.Frame('', layout = [ [...], [...], [...], ]) case 3: [ [...], [...], [...], ] ''' if psg_ui.startswith('import PySimpleGUI as sg'): exec(psg_ui) if psg_ui_lines[0].startswith("""sg.Frame('""") and psg_ui_lines[0].endswith("""', layout = ["""): window2 = sg.Window('test', eval(psg_ui)) window2.read() window2.close() if psg_ui_lines[0].startswith("""[""") and psg_ui_lines[-1].endswith("""]"""): possible_ui = eval(psg_ui) possible_ui if type(possible_ui) is list and type(possible_ui[0]) is not list: raise Exception(f"bad ui given. It's not a list of LISTS.") window2 = sg.Window('test', possible_ui) window2.read() window2.close() except Exception as e: sg.popup(str(e)) window.close()
sg.Radio('Radio 1', default=True, group_id='1', disabled=True, key='radio1'), sg.Radio('Radio 2', default=False, group_id='1', disabled=True, key='radio2') ], [ sg.Spin((1, 2, 3, 4), 1, disabled=True, key='spin'), sg.OptionMenu((1, 2, 3, 4), disabled=True, key='option'), sg.Combo(values=(1, 2, 3, 4), disabled=True, key='combo') ], [sg.ML('Multiline', size=(20, 3), disabled=True, key='multi')], [ sg.Slider((1, 10), size=(20, 20), orientation='h', disabled=True, key='slider') ], [ sg.Button('Enable', button_color=('white', 'black')), sg.Button('Disable', button_color=('white', 'black')), sg.Button('Reset', button_color=('white', '#9B0023'), key='reset'), sg.Button('Values', button_color=('white', 'springgreen4')), sg.Button('Exit',
]) status_layout = sg.Frame('Status', [[sg.Button(image_data=icon_status_off, key='-status-', button_color=(sg.theme_background_color(), sg.theme_background_color())), sg.Button(image_data=icon_pi, size=(50, 20), button_color=(sg.theme_background_color(), sg.theme_background_color()), key='-pi-')] ]) device_layout = sg.Frame('Device List', [[sg.Listbox(Devices, size=(18, 10), background_color=sg.theme_background_color(), enable_events=True, key='-device-')]]) description_layout = sg.Frame('Description', [[sg.ML('Here is device description', font='Ubuntu 11', size=(30, 10), key='-description-')]]) column1 = sg.Column([[connect_layout]]) column2 = sg.Column([[status_layout]]) column3 = sg.Column([[device_layout]]) column4 = sg.Column([[description_layout]]) layout = [ [column1, column2], [column3, column4], ] window = sg.Window('gpiozero gui', layout, size=(500, 300), finalize=True) is_connected = False while True: # Event Loop
#!/usr/bin/python3 ''' pip install PySimpleGUI requests ''' import PySimpleGUI as sg, requests layout = [[sg.B('Test', key='test_serv')], [sg.I('', key='itext'), sg.B('Send', key='send_text')], [sg.ML('', size=(60, 15), key='log')]] window = sg.Window('', layout, return_keyboard_events=True) addr = '127.0.0.1:5000' while True: event, values = window() if event in (None, 'Exit'): break if event == 'test_serv': responce = requests.post(f'http://{addr}/') window['log'](responce.text) if event == 'send_text': itext = values['itext'] responce = requests.post(f'http://{addr}/', json={'text': itext}) window['log'](responce.text) if 'F1' in event: window['log'](requests.post(f'http://{addr}/exec', json={ 'i': values['itext'] }).text)
filtered.append(txt) return f'TOTAL funcs amount listed below: {len(filtered)}\n' + '\n'.join( filtered) ############################### # _____ _ _ _____ # # / ____| | | |_ _| # # | | __| | | | | | # # | | |_ | | | | | | # # | |__| | |__| |_| |_ # # \_____|\____/|_____| # # # ############################### window = sg.Window('Dump of tags', [[ sg.ML(size=(80, 40), key='w'), sg.Col([[sg.ML(size=(80, 40), key='w2')], [sg.CB('show _ funcs&methods?', key='-_sc-', enable_events=True)]]) ]], resizable=True, finalize=True) window['w']('\n'.join(messages)) window['w2'](get_filtered_funcs(psg_funcs, True)) while True: event, values = window() if event in ('Exit', None): break print(event) if event == '-_sc-':
size=(5, 10), pad=((15, 5), (10, 5)), enable_events=True, ), ]], title="选择翻译语言", title_color="white", ) ml_frame1 = sg.Frame( key="-IN LANG-", layout=[[ sg.ML( key="-INPUT-", size=(40, 8), font=("微软雅黑", 12), pad=((15, 15), (5, 15)), autoscroll=True, enable_events=True, ), ]], title="中文", ) ml_frame2 = sg.Frame( key="-OUTPUT LANG-", layout=[[ sg.ML( key="-OUTPUT-", size=(40, 8), font=("微软雅黑", 12), pad=((15, 15), (5, 5)),
import PySimpleGUI as sg """ Demonstrates the new change_submits parameter for inputtext elements It ONLY submits when a button changes the field, not normal user input Be careful on persistent forms to not clear the input """ layout = [[sg.Text('Test of reading input field')], [sg.Text('This input is normal'), sg.Input()], [ sg.Text('This input change submits'), sg.Input(change_submits=True) ], [ sg.Text('This multiline input change submits'), sg.ML('', change_submits=True) ], [sg.Text('This input is normal'), sg.Input(), sg.FileBrowse()], [ sg.Text('File Browse submits'), sg.Input(change_submits=True, key='-in1-'), sg.FileBrowse() ], [ sg.Text('Color Chooser submits'), sg.Input(change_submits=True, key='-in2-'), sg.ColorChooserButton('Color...', target=(sg.ThisRow, -1)) ], [ sg.Text('Folder Browse submits'),
3. Read any event from the window which will close the window and return Note that while the window has no scrollbar, you can still use the mousewheel to scroll Copyright 2021 PySimpleGUI """ # ----- Make the window ----- window = sg.Window( 'Postit', [[sg.T('Postit Note', text_color='black', background_color='#FFFF88')], [ sg.ML(size=(30, 5), background_color='#FFFF88', no_scrollbar=True, k='-ML-', border_width=0, expand_y=True, expand_x=True), sg.Sizegrip(background_color='#FFFF88') ]], no_titlebar=True, grab_anywhere=True, margins=(0, 0), background_color='#FFFF88', element_padding=(0, 0), right_click_menu=sg.MENU_RIGHT_CLICK_EXIT, keep_on_top=True, font='_ 20', resizable=True, finalize=True)
[ sg.Text('Digite algo:'), sg.MLine('', key="-Text-"), sg.Button("Criptar", border_width=0, size=(10, 3)) ], [ sg.Text('Criptado:'), sg.MLine(size=(60, 3), disabled=True, key='-Cript-') ], [sg.HSeparator()], [ sg.Text("Insira a chave: "), sg.Input('', size=(57, 5), key='-Cha2-') ], [ sg.Text("Digite a mensagem criptada: "), sg.ML('', size=(43, 1), key='-Text2-') ], [ sg.Text("Descriptada: "), sg.MLine(size=(56, 1), disabled=True, key='-Cript2-') ], [sg.Button('Descriptar', size=(63, 2))]] # criando janela janela = sg.Window("Projeto Cript", font='132 11').layout(layout) def Criptar(mensagem, chave): lista = '''aAbBcCdDeEêfFgGrRsStTuUvVwWxXyYzZ1234 567890àá~ãõ-=+_éèâ& {([])}\/,.:;'"@hHiIjJ?!kKlLmMnNoOpPqQ''' nova = [ lista[(lista.index(c) + chave) %