diff --git a/DemoPrograms/Demo_Table_Checkmark.py b/DemoPrograms/Demo_Table_Checkmark.py new file mode 100644 index 00000000..83e7fd77 --- /dev/null +++ b/DemoPrograms/Demo_Table_Checkmark.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +import PySimpleGUI as sg +import random +import string + +""" + Demo Program - Table with checkboxes + + This clever solution was sugged by GitHub user robochopbg. + The beauty of the simplicity is that the checkbox is simply another column in the table. When the checkbox changes + state, then the data in the table is changed and the table is updated in the Table element. + A big thank you again to user robochopbg! + +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⣿⠆⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⡿⠁⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⣿⠟⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣿⡿⠃⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀ +⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣿⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠺⣿⣷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠈⠻⣿⣿⣦⣄⠀⠀⠀⠀⠀⠀⣠⣿⣿⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠈⠻⣿⣿⣷⣤⡀⠀⠀⣰⣿⣿⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣦⣼⣿⣿⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⣿⣿⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ + + Copyright 2023 PySimpleGUI +""" + +# Characters used for the checked and unchecked checkboxes. Feel free to change +BLANK_BOX = '☐' +CHECKED_BOX = '☑' + +# ------ 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] = [BLANK_BOX if random.randint(0,2) % 2 else CHECKED_BOX] + [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[0] = 'Checkbox' +# The selected rows is stored in a set +selected = {i for i, row in enumerate(data[1:][:]) if row[0] == CHECKED_BOX} + +# ------ Window Layout ------ +layout = [[sg.Table(values=data[1:][:], headings=headings, max_col_width=25, auto_size_columns=False, col_widths=[10, 10, 20, 20 ,30, 5], + display_row_numbers=True, justification='center', num_rows=20, key='-TABLE-', selected_row_colors='red on yellow', + expand_x=False, expand_y=True, vertical_scroll_only=False, enable_click_events=True, font='_ 14'), + sg.Sizegrip()]] + +# ------ Create Window ------ +window = sg.Window('Table with Checkbox', layout, resizable=True, finalize=True) + +# Highlight the rows (select) that have checkboxes checked +window['-TABLE-'].update(values=data[1:][:], select_rows=list(selected)) + +# ------ Event Loop ------ +while True: + event, values = window.read() + if event == sg.WIN_CLOSED: + break + elif event[0] == '-TABLE-' and event[2][0] not in (None, -1): # if clicked a data row rather than header or outside table + row = event[2][0]+1 + if data[row][0] == CHECKED_BOX: # Going from Checked to Unchecked + selected.remove(row-1) + data[row][0] = BLANK_BOX + else: # Going from Unchecked to Checked + selected.add(row-1) + data[row ][0] = CHECKED_BOX + window['-TABLE-'].update(values=data[1:][:], select_rows=list(selected)) # Update the table and the selected rows + +window.close() +