How to change the headings and column numbers in a pysimplegui Table element

I cannot find out how I can update the headings in a Table element or change the number of columns.

I tried creating two table elements and switching them, but that did not work.

import PySimpleGUI as sg

values = [["John Doe", 30], ["Jane Doe", 25], ["Peter Smith", 40]]
# Create a table with 3 rows and 2 columns
table1 = sg.Table(
    values=values,
    headings=["Name", "Age"],
    auto_size_columns=False,
)
table2 = sg.Table(
    values=values,
    headings=["XXXXX", "YYYY"],
    auto_size_columns=False,
)

table = table1

# Create a layout and show the window
layout = [[table], [sg.Button("Flip", key="-FLIP-"), sg.Push(), sg.Quit()]]

window = sg.Window("Table Example", layout)
while True:
    event, values = window.read()
    print(event, values)
    if event in [sg.WIN_CLOSED, "Quit"]:
        break
    if event == "-FLIP-":
        # update headings in table
        pass
window.close()

I have looked at various examples but they all create new tables in a sg.window(), and do not update an existing table.

Thank you very much for pointers to where I can find out more.

You can create two Table elements at the same row when the beginning, but one with visible=True and another one with visible=False, then update the option visible of element to True or False when flip.

import PySimpleGUI as sg

values = [["John Doe", 30], ["Jane Doe", 25], ["Peter Smith", 40]]
# Create a table with 3 rows and 2 columns
table1 = sg.Table(
    values=values,
    headings=["Name", "Age"],
    auto_size_columns=False,
    key='Table1'
)
table2 = sg.Table(
    values=values,
    headings=["XXXXX", "YYYY"],
    auto_size_columns=False,
    visible=False,
    key='Table2',
)

table = table1

# Create a layout and show the window
layout = [[table1, table2], [sg.Button("Flip", key="-FLIP-"), sg.Push(), sg.Quit()]]

window = sg.Window("Table Example", layout)
while True:
    event, values = window.read()
    print(event, values)
    if event in [sg.WIN_CLOSED, "Quit"]:
        break
    if event == "-FLIP-":
        window['Table1'].update(visible=False)
        window['Table2'].update(visible=True)

window.close()

Another demo code is to rebuild the window with new Table element.

import PySimpleGUI as sg

def new_window(window, table_options):
    if window is not None:
        window.close()
    layout = [
        [sg.Button('Replace!'),
         sg.Table(**table_options, key="-TABLE-"),]
    ]
    return sg.Window('Table', layout, finalize=True)

table_options = {
    'headings'  : ['Col 1', 'Col 2', 'Col 3', 'Col 4', 'Col 5', 'Col 6'],
    'values'    : [['1', '2', '3', '4', '5', '6'],],
}

window = new_window(None, table_options)

while True:
    event, values = window.read()
    if event == sg.WIN_CLOSED:
        break
    elif event == 'Replace!':
        table_options = {
            'headings'  : ['Col6', 'Col5', 'Col4', 'Col3', 'Col2', 'Col1', 'newColumn!'],
            'values'    : [['6', '5', '4', '3', '2', '1', 'nc'],],
            'num_rows'  : 25,
        }
        window = new_window(window, table_options)

window.close()

Another demo code with tkinter code

import PySimpleGUI as sg

class Column(sg.Column):

    pack_info = {}           # Keep pack information of element before forget it.
    on_list = []             # Keep the list of elements displayed for hide them all when required

    def __init__(self, element, pad=(0, 0), expand='XY', align='top', bg=None, **kwargs):
        expand = expand.lower()
        expand_x = True if 'x' in expand else None
        expand_y = True if 'y' in expand else None
        kwargs.update({'pad':pad, 'expand_x':expand_x, 'expand_y':expand_y,
            'vertical_alignment':align, 'background_color':bg})
        super().__init__([[element]], **kwargs)
        self.on_list.append(self)

    def update(self, visible):
        if visible is False:
            if self.TKColFrame:
                if self not in self.pack_info:
                    self.pack_info[self] = self.TKColFrame.pack_info()
                self.TKColFrame.pack_forget()
            if self.ParentPanedWindow:
                self.ParentPanedWindow.remove(self.TKColFrame)
        elif visible is True:
            if self.TKColFrame:
                pack_info = self.pack_info[self]
                self.TKColFrame.pack(**pack_info)
            if self.ParentPanedWindow:
                self.ParentPanedWindow.add(self.TKColFrame)
        if visible is not None:
            self._visible = visible

    @classmethod
    def hide_all(cls):
        for element in cls.on_list:
            element.update(False)
        cls.on_list = []

    @classmethod
    def show(cls, *sequence):
        cls.hide_all()
        for element in sequence:
            element.update(True)
            cls.on_list.append(element)

def new_color(color=None):
    factor = 3/4
    bg = sg.theme_background_color() if color is None else color
    r, g, b = tuple(int(bg.strip('#')[i:i+2], 16) for i in (0, 2, 4))
    r, g, b = int(r*factor), int(g*factor), int(b*factor)
    return '#%02x%02x%02x' % (r, g, b)

items = 10
headings = [[f"Column {i}" for i in range(item+1)] for item in range(items)]
data = [[[f"Cell ({row}, {col})" for col in range(item+1)] for row in range(10)] for item in range(items)]
table = [Column(sg.Table(data[i], headings=headings[i], auto_size_columns=False,
    justification='center', alternating_row_color=new_color(), expand_x=True,
    expand_y=True, vertical_scroll_only=False))
    for i in range(items)]

layout = [[sg.Text('Table  1', key='INDEX')], table, [sg.Push(), sg.Button("PREV"), sg.Button('NEXT')]]
location = sg.Window.get_screen_size()
window = sg.Window('Swap layout', layout, size=(700, 300), location=location, finalize=True)
Column.show(table[0])
window.refresh()
window.move_to_center()

index = 0
while True:
    event, values = window.read()
    if event == sg.WINDOW_CLOSED:
        break
    elif event in ('PREV', 'NEXT'):
        index = (index + (1 if event == 'NEXT' else -1)) % items
        window['INDEX'].update(f'Table {index+1:2d}')
        Column.show(table[index])

window.close()

Leave a Comment