diff --git a/DemoPrograms/Demo_Table_Element_Header_or_Cell_Clicks.py b/DemoPrograms/Demo_Table_Element_Header_or_Cell_Clicks.py new file mode 100644 index 00000000..01fa231a --- /dev/null +++ b/DemoPrograms/Demo_Table_Element_Header_or_Cell_Clicks.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python +import PySimpleGUI as sg +import random +import string +import operator + +""" + Table Element Demo With Sorting + + The data for the table is assumed to have HEADERS across the first row. + This is often the case for CSV files or spreadsheets + + In release 4.48.0 a new enable_click_events parameter was added to the Table Element + This enables you to click on Column Headers and individual cells as well as the standard Row selection + + This demo shows how you can use these click events to sort your table by columns + +""" + +sg.theme('Light green 6') +# ------ Some functions to help generate data for the table ------ +def word(): + return ''.join(random.choice(string.ascii_lowercase) for i in range(10)) +def number(max_val=1000): + return random.randint(0, max_val) + +def make_table(num_rows, num_cols): + data = [[j for j in range(num_cols)] for i in range(num_rows)] + data[0] = [word() for __ in range(num_cols)] + for i in range(1, num_rows): + data[i] = [i, word(), *[number() for i in range(num_cols - 1)]] + return data + +# ------ Make the Table Data ------ +data = make_table(num_rows=15, num_cols=6) +# headings = [str(data[0][x])+' ..' for x in range(len(data[0]))] +headings = [f'Col {col}' for col in range(len(data[0]))] + +def sort_table(table, cols): + """ sort a table by multiple columns + table: a list of lists (or tuple of tuples) where each inner list + represents a row + cols: a list (or tuple) specifying the column numbers to sort by + e.g. (1,0) would sort by column 1, then by column 0 + """ + for col in reversed(cols): + try: + table = sorted(table, key=operator.itemgetter(col)) + except Exception as e: + sg.popup_error('Error in sort_table', 'Exception in sort_table', e) + return table + +# ------ Window Layout ------ +layout = [[sg.Table(values=data[1:][:], headings=headings, max_col_width=25, + auto_size_columns=True, + display_row_numbers=True, + justification='right', + num_rows=20, + alternating_row_color='lightyellow', + key='-TABLE-', + selected_row_colors='red on yellow', + enable_events=True, + expand_x=True, + expand_y=True, + enable_click_events=True, # Comment out to not enable header and other clicks + tooltip='This is a table')], + [sg.Button('Read'), sg.Button('Double'), sg.Button('Change Colors')], + [sg.Text('Cell clicked:'), sg.T(k='-CLICKED-')], + [sg.Text('Read = read which rows are selected')], + [sg.Text('Double = double the amount of data in the table')], + [sg.Text('Change Colors = Changes the colors of rows 8 and 9'), sg.Sizegrip()]] + +# ------ Create Window ------ +window = sg.Window('The Table Element', layout, + ttk_theme='clam', + resizable=True) + +# ------ Event Loop ------ +while True: + event, values = window.read() + print(event, values) + if event == sg.WIN_CLOSED: + break + if event == 'Double': + for i in range(1, len(data)): + data.append(data[i]) + window['-TABLE-'].update(values=data[1:][:]) + elif event == 'Change Colors': + window['-TABLE-'].update(row_colors=((8, 'white', 'red'), (9, 'green'))) + if isinstance(event, tuple): + # TABLE CLICKED Event has value in format ('-TABLE=', '+CLICKED+', (row,col)) + if event[0] == '-TABLE-': + if event[2][0] == -1 and event[2][1] != -1: # Header was clicked and wasn't the "row" column + col_num_clicked = event[2][1] + new_table = sort_table(data[1:][:],(col_num_clicked, 0)) + window['-TABLE-'].update(new_table) + data = [data[0]] + new_table + window['-CLICKED-'].update(f'{event[2][0]},{event[2][1]}') +window.close()