Basically I have the same issue than this one : issue
I tried this before but I get an error message, I think because I am using frames (I think).
As you can see I tried using window.visibility_changed()
but it did not help.
Test code to explain :
import PySimpleGUI as sg
def frame (n_frame):
layout = [[sg.Text ('test')]]
return layout
def make_window():
layout = [[sg.Column([[sg.Text ('Title')], # First title of the IDS
[sg.Column(frame(1),key = '-LVL 1 CALL-')],
[sg.pin (sg.Frame(title = '',
layout = [[sg.Button(' + ',key = '-ADD A LVL 1 FRAME-'),
sg.Button(' - ',key = '-REMOVE A LVL 1 FRAME-'),
sg.Button('Save')]],
relief = 'flat'))]],
scrollable=True,
vertical_scroll_only=True,
pad =(0,0))]]
window = sg.Window('Window Title', layout, metadata=1, resizable = True, element_padding = (10, 6), finalize = True)
return window
def main():
window = make_window()
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event =='Save':
break
elif event == '-ADD A LVL 1 FRAME-' :
window.metadata += 1
window.extend_layout(window['-LVL 1 CALL-'],(frame(window.metadata)))
window.refresh()
window.visibility_changed()
window['-LVL 1 CALL-'].contents_changed()
window.close()
if __name__ == '__main__':
main()
The error message :
File "C:\...\Lib\site-packages\PySimpleGUI\PySimpleGUI.py", line 8302, in contents_changed
self.TKColFrame.canvas.config(scrollregion=self.TKColFrame.canvas.bbox('all'))
^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Frame' object has no attribute 'canvas'
Additional questions :
These are less important and I can also find by myself, thank you for your help
I would like to update the size of it without having to call .contents_changed() on the specific window that has just been added because I have just so many
Call method contents_changed
only for the scrollable Column element, so here you may add a key, like -Column-
, to main scrollable Column element.
def make_window():
layout = [[sg.Column([[sg.Text ('Title')], # First title of the IDS
[sg.Column(frame(1),key = '-LVL 1 CALL-')],
[sg.pin (sg.Frame(title = '',
layout = [[sg.Button(' + ',key = '-ADD A LVL 1 FRAME-'),
sg.Button(' - ',key = '-REMOVE A LVL 1 FRAME-'),
sg.Button('Save')]],
relief = 'flat'))]],
scrollable=True,
vertical_scroll_only=True,
pad =(0,0),
key="-Column-", # Add key here
)]]
window = sg.Window('Window Title', layout, metadata=1, resizable = True, element_padding = (10, 6), finalize = True)
return window
then you can call method contents_changed
of the '-Column-'
Column element, like
elif event == '-ADD A LVL 1 FRAME-' :
window.metadata += 1
window.extend_layout(window['-LVL 1 CALL-'],(frame(window.metadata)))
window.refresh()
window.visibility_changed()
window['-Column-'].contents_changed()
I would like the scrollbar to adapt to the size of the window if the user resize window
It is much complex to make the scrollable Column to expand when it or window configured, following code demo the way about how I do it, and it need more knowledge about the tkinter.
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()