PySimpleGUI/DemoPrograms/Demo_Table_Element_Header_o...

100 lines
3.9 KiB
Python

#!/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()