Scrollable Columns - NEW Feature!
This commit is contained in:
parent
6115a00e30
commit
ccd3e4c797
|
@ -7,18 +7,55 @@ import PySimpleGUI as sg
|
|||
|
||||
# sg.ChangeLookAndFeel('BlueMono')
|
||||
|
||||
# Column layout
|
||||
col = [[sg.Text('col Row 1', text_color='white', background_color='blue')],
|
||||
[sg.Text('col Row 2', text_color='white', background_color='blue'), sg.Input('col input 1')],
|
||||
[sg.Text('col Row 3', text_color='white', background_color='blue'), sg.Input('col input 2')]]
|
||||
|
||||
layout = [[sg.Listbox(values=('Listbox Item 1', 'Listbox Item 2', 'Listbox Item 3'), select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE, size=(20,3)), sg.Column(col, background_color='blue')],
|
||||
[sg.Input('Last input')],
|
||||
[sg.OK()]]
|
||||
def ScrollableColumns():
|
||||
# sg.ChangeLookAndFeel('Dark')
|
||||
|
||||
# Display the form and get values
|
||||
# If you're willing to not use the "context manager" design pattern, then it's possible
|
||||
# to collapse the form display and read down to a single line of code.
|
||||
button, values = sg.FlexForm('Compact 1-line form with column').LayoutAndRead(layout)
|
||||
|
||||
sg.MsgBox(button, values, line_width=200)
|
||||
column1 = [[sg.Text('Column 1', justification='center', size=(20, 1))],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1', key='spin1', size=(30,1))],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 3', key='spin3')]]
|
||||
|
||||
|
||||
column2 = [[sg.T('Table Test')]]
|
||||
|
||||
for i in range(50):
|
||||
column2.append([sg.T(f'{i}{j}', size=(4, 1), background_color='gray25', text_color='white', pad=(1, 1)) for j in range(10)])
|
||||
|
||||
layout = [[sg.Column(column2, scrollable=True, size=(400,300)), sg.Column(column1, scrollable=True, size=(200,150))],
|
||||
[sg.OK()]]
|
||||
|
||||
form = sg.FlexForm('Form Fill Demonstration', default_element_size=(40, 1))
|
||||
b, v = form.LayoutAndRead(layout)
|
||||
|
||||
|
||||
def NormalColumns():
|
||||
# Column layout
|
||||
col = [[sg.Text('col Row 1', text_color='white', background_color='blue')],
|
||||
[sg.Text('col Row 2', text_color='white', background_color='blue'), sg.Input('col input 1')],
|
||||
[sg.Text('col Row 3', text_color='white', background_color='blue'), sg.Input('col input 2')]]
|
||||
|
||||
layout = [[sg.Listbox(values=('Listbox Item 1', 'Listbox Item 2', 'Listbox Item 3'), select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE, size=(20,3)), sg.Column(col, background_color='blue')],
|
||||
[sg.Input('Last input')],
|
||||
[sg.OK()]]
|
||||
|
||||
# Display the form and get values
|
||||
# If you're willing to not use the "context manager" design pattern, then it's possible
|
||||
# to collapse the form display and read down to a single line of code.
|
||||
button, values = sg.FlexForm('Compact 1-line form with column').LayoutAndRead(layout)
|
||||
|
||||
sg.Popup(button, values, line_width=200)
|
||||
|
||||
NormalColumns()
|
||||
ScrollableColumns()
|
|
@ -1059,20 +1059,52 @@ class TkScrollableFrame(tk.Frame):
|
|||
# create a canvas object and a vertical scrollbar for scrolling it
|
||||
self.vscrollbar = tk.Scrollbar(self, orient=tk.VERTICAL)
|
||||
self.vscrollbar.pack(side='right', fill="y", expand="false")
|
||||
self.canvas = tk.Canvas(self, yscrollcommand=self.vscrollbar.set)
|
||||
self.canvas.pack(side="left")
|
||||
|
||||
self.hscrollbar = tk.Scrollbar(self, orient=tk.HORIZONTAL)
|
||||
self.hscrollbar.pack(side='bottom', fill="x", expand="false")
|
||||
|
||||
self.canvas = tk.Canvas(self, yscrollcommand=self.vscrollbar.set, xscrollcommand=self.hscrollbar.set)
|
||||
self.canvas.pack(side="left", fill="both", expand=True)
|
||||
|
||||
self.vscrollbar.config(command=self.canvas.yview)
|
||||
self.hscrollbar.config(command=self.canvas.xview)
|
||||
|
||||
# reset the view
|
||||
self.canvas.xview_moveto(0)
|
||||
self.canvas.yview_moveto(0)
|
||||
|
||||
# create a frame inside the canvas which will be scrolled with it
|
||||
# self.interior = tk.Frame(self.canvas, **kwargs)
|
||||
# self.canvas.create_window(0, 0, window=self.interior, anchor="nw")
|
||||
self.TKFrame = tk.Frame(self.canvas, **kwargs)
|
||||
self.canvas.create_window(0, 0, window=self.TKFrame, anchor="nw")
|
||||
self.canvas.config(borderwidth=0, highlightthickness=0)
|
||||
self.TKFrame.config(borderwidth=0, highlightthickness=0)
|
||||
self.config(borderwidth=0, highlightthickness=0)
|
||||
|
||||
# self.bind('<Configure>', self.set_scrollregion)
|
||||
self.bind('<Configure>', self.set_scrollregion)
|
||||
|
||||
self.bind_mouse_scroll(self.canvas, self.yscroll)
|
||||
self.bind_mouse_scroll(self.hscrollbar, self.xscroll)
|
||||
self.bind_mouse_scroll(self.vscrollbar, self.yscroll)
|
||||
|
||||
|
||||
def yscroll(self, event):
|
||||
if event.num == 5 or event.delta < 0:
|
||||
self.canvas.yview_scroll(1, "unit")
|
||||
elif event.num == 4 or event.delta > 0:
|
||||
self.canvas.yview_scroll(-1, "unit")
|
||||
|
||||
def xscroll(self, event):
|
||||
if event.num == 5 or event.delta < 0:
|
||||
self.canvas.xview_scroll(1, "unit")
|
||||
elif event.num == 4 or event.delta > 0:
|
||||
self.canvas.xview_scroll(-1, "unit")
|
||||
|
||||
def bind_mouse_scroll(self, parent, mode):
|
||||
# ~~ Windows only
|
||||
parent.bind("<MouseWheel>", mode)
|
||||
# ~~ Unix only
|
||||
parent.bind("<Button-4>", mode)
|
||||
parent.bind("<Button-5>", mode)
|
||||
|
||||
def set_scrollregion(self, event=None):
|
||||
""" Set the scroll region on the canvas"""
|
||||
|
@ -1083,7 +1115,7 @@ class TkScrollableFrame(tk.Frame):
|
|||
# Column #
|
||||
# ---------------------------------------------------------------------- #
|
||||
class Column(Element):
|
||||
def __init__(self, layout, background_color = None, pad=None):
|
||||
def __init__(self, layout, background_color = None, size=(None, None), pad=None, scrollable=False):
|
||||
self.UseDictionary = False
|
||||
self.ReturnValues = None
|
||||
self.ReturnValuesList = []
|
||||
|
@ -1093,11 +1125,12 @@ class Column(Element):
|
|||
self.Rows = []
|
||||
self.ParentForm = None
|
||||
self.TKFrame = None
|
||||
self.Scrollable = scrollable
|
||||
bg = background_color if background_color is not None else DEFAULT_BACKGROUND_COLOR
|
||||
|
||||
self.Layout(layout)
|
||||
|
||||
super().__init__(ELEM_TYPE_COLUMN, background_color=background_color, pad=pad)
|
||||
super().__init__(ELEM_TYPE_COLUMN, background_color=background_color, size=size, pad=pad)
|
||||
return
|
||||
|
||||
def AddRow(self, *args):
|
||||
|
@ -1763,9 +1796,23 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
element_size = (int(element_size[0] * toplevel_form.Scale[0]), int(element_size[1] * toplevel_form.Scale[1]))
|
||||
# ------------------------- COLUMN element ------------------------- #
|
||||
if element_type == ELEM_TYPE_COLUMN:
|
||||
col_frame = tk.Frame(tk_row_frame)
|
||||
# col_frame = TkScrollableFrame(tk_row_frame) # do not use yet! not working
|
||||
PackFormIntoFrame(element, col_frame, toplevel_form)
|
||||
if element.Scrollable:
|
||||
col_frame = TkScrollableFrame(tk_row_frame) # do not use yet! not working
|
||||
PackFormIntoFrame(element, col_frame.TKFrame, toplevel_form)
|
||||
col_frame.TKFrame.update()
|
||||
if element.Size == (None, None):
|
||||
col_frame.canvas.config(width=col_frame.TKFrame.winfo_reqwidth(),height=col_frame.TKFrame.winfo_reqheight())
|
||||
else:
|
||||
col_frame.canvas.config(width=element.Size[0],height=element.Size[1])
|
||||
|
||||
if not element.BackgroundColor in (None, COLOR_SYSTEM_DEFAULT):
|
||||
col_frame.canvas.config(background=element.BackgroundColor)
|
||||
col_frame.TKFrame.config(background=element.BackgroundColor, borderwidth =0, highlightthickness=0)
|
||||
col_frame.config(background=element.BackgroundColor, borderwidth =0, highlightthickness=0)
|
||||
else:
|
||||
col_frame = tk.Frame(tk_row_frame)
|
||||
PackFormIntoFrame(element, col_frame, toplevel_form)
|
||||
|
||||
col_frame.pack(side=tk.LEFT, padx=element.Pad[0], pady=element.Pad[1])
|
||||
if element.BackgroundColor != COLOR_SYSTEM_DEFAULT and element.BackgroundColor is not None:
|
||||
col_frame.configure(background=element.BackgroundColor, highlightbackground=element.BackgroundColor, highlightcolor=element.BackgroundColor)
|
||||
|
@ -3092,11 +3139,16 @@ def ChangeLookAndFeel(index):
|
|||
'PROGRESS': DEFAULT_PROGRESS_BAR_COLOR, 'BORDER': 1, 'SLIDER_DEPTH': 0,
|
||||
'PROGRESS_DEPTH': 0},
|
||||
|
||||
'DarkTanBlue': {'BACKGROUND': '#242834', 'TEXT': '#dfe6f8', 'INPUT': '#4f5764',
|
||||
'DarkTanBlue': {'BACKGROUND': '#242834', 'TEXT': '#dfe6f8', 'INPUT': '#97755c',
|
||||
'TEXT_INPUT': 'white', 'SCROLL': '#a9afbb', 'BUTTON': ('white', '#063289'),
|
||||
'PROGRESS': DEFAULT_PROGRESS_BAR_COLOR, 'BORDER': 1, 'SLIDER_DEPTH': 0,
|
||||
'PROGRESS_DEPTH': 0},
|
||||
|
||||
'DarkAmber': {'BACKGROUND': '#2c2825', 'TEXT': '#fdcb52', 'INPUT': '#705e52',
|
||||
'TEXT_INPUT': '#fdcb52', 'SCROLL': '#705e52', 'BUTTON': ('black', '#fdcb52'),
|
||||
'PROGRESS': DEFAULT_PROGRESS_BAR_COLOR, 'BORDER': 1, 'SLIDER_DEPTH': 0,
|
||||
'PROGRESS_DEPTH': 0},
|
||||
|
||||
'DarkBlue': {'BACKGROUND': '#1a2835', 'TEXT': '#d1ecff', 'INPUT': '#335267',
|
||||
'TEXT_INPUT': '#acc2d0', 'SCROLL': '#1b6497', 'BUTTON': ('black', '#fafaf8'),
|
||||
'PROGRESS': DEFAULT_PROGRESS_BAR_COLOR, 'BORDER': 1, 'SLIDER_DEPTH': 0,
|
||||
|
|
Loading…
Reference in New Issue