Search code examples
pythonpysimplegui

how to add more items to column in PySimpleGUI


i'm not english so sorry for typing problems

i'm writing a little version of instagram,and in my main page in start, i have 10 post(text for test) and in the end of that a button . when user clicks on the button i want to add 10 more post(text) to the end of the previous posts and before the button. so now i should have 20 posts(text) and button.(the size of width is fixed but height will grow) i'm doing this with columns.

can you guys help me with this? a code that show the way in enough

and addition if you can answer: is there any way to make a scrollable column without scrollbar showing?(like table i guess)because its make the app a little ill-sorted.

Any explanation and help is appreciated. and i'm new to PySimpleGUI thank in advance.


Solution

  • Demo Code

    import PySimpleGUI as sg
    
    sg.theme('DarkGreen')
    layout = [
        [sg.Multiline('', size=(80, 15), autoscroll=True, no_scrollbar=True, key='ML')],
        [sg.Button("User 1"), sg.Push(), sg.Button("User 2")],
    ]
    window = sg.Window('Chat', layout, finalize=True)
    ml = window['ML']
    
    while True:
    
        event, values = window.read()
    
        if event == sg.WIN_CLOSED:
            break
        elif event in ("User 1", "User 2"):
            ml.update(event+": Hello !\n", append=True)
    
    window.close()
    

    You can use method window.extend_layout to add new layout inside a Column element, remember to call column.contents_changed() to update the scroll region.

    Here column.contents_changed() replaced by tkinter code canvas.configure(scrollregion=canvas.bbox("all")).

    import PySimpleGUI as sg
    
    def repack(widget, option):
        pack_info = widget.pack_info()
        pack_info.update(option)
        widget.pack(**pack_info)
    
    def configure_canvas(event, canvas, frame_id):
        canvas.itemconfig(frame_id, width=canvas.winfo_width())
    
    def configure_frame(event, canvas):
        canvas.configure(scrollregion=canvas.bbox("all"))
    
    def cell(i):
        layout = [
            [sg.Text('Hello World', expand_x=True, key=f'TA{i}'),
             sg.Text('Hello World', expand_x=True, justification='center', key=f'TB{i}')]
        ]
        return [[sg.Frame(f'Frame {i}', layout, background_color='blue', expand_x=True, key=f'FRAME{i}')]]
    
    
    layout = [
        [sg.Button('New Frame')],
        [sg.Column(cell(0), scrollable=True,  vertical_scroll_only=True, pad=(0, 0), expand_x=True, expand_y=True, key='COLUMN')],
    ]
    location = sg.Window.get_screen_size()
    window = sg.Window('Title', layout, resizable=True, finalize=True, margins=(0, 0), location=location)
    
    repack(window[f'TA{0}'].widget, {'fill':'none', 'expand':0, 'before':window[f'TB{0}'].widget})
    
    column = window['COLUMN'].widget
    frame_id, frame, canvas = column.frame_id, column.TKFrame, column.canvas
    
    canvas.bind("<Configure>", lambda event, canvas=canvas, frame_id=frame_id:configure_canvas(event, canvas, frame_id))
    frame.bind("<Configure>", lambda event, canvas=canvas:configure_frame(event, canvas))
    
    window.set_size((320, 240))
    window.refresh()
    window.move_to_center()
    
    count = 1
    
    while True:
    
        event, values = window.read()
    
        if event == sg.WIN_CLOSED:
            break
        elif event == 'New Frame':
            window.extend_layout(window['COLUMN'], cell(count))
            repack(window[f'TA{count}'].widget, {'fill':'none', 'expand':0, 'before':window[f'TB{count}'].widget})
            count += 1
    
    window.close()
    

    Note: Lot of tkinter code here, so no more information about how they work.