Skip to content

Instantly share code, notes, and snippets.

@PaulCreusy
Last active June 20, 2024 08:32
Show Gist options
  • Save PaulCreusy/57faa597182d1c968ef1c3385e769f9c to your computer and use it in GitHub Desktop.
Save PaulCreusy/57faa597182d1c968ef1c3385e769f9c to your computer and use it in GitHub Desktop.
Scrollable Frame for tkinter
import os
import tkinter as tk
from tkinter import ttk
class ScrollableFrame(ttk.Frame):
def __init__(self, container, *args, **kwargs):
super().__init__(container, *args, **kwargs)
canvas = tk.Canvas(self, takefocus=0, highlightthickness=0)
self.canvas = canvas
scrollbar = ttk.Scrollbar(self, orient="vertical", command=canvas.yview)
self.scrollable_frame = ttk.Frame(canvas, takefocus=0)
self.scrollable_frame.columnconfigure(index=0, weight=1)
self.scrollable_frame.bind(
"<Configure>",
lambda e: canvas.configure(
scrollregion=canvas.bbox("all")
)
)
self.scrollable_frame_id = canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)
self.canvas.bind('<Configure>', self.on_width_change)
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
def reset_view(self):
self.canvas.xview_moveto(0)
self.canvas.yview_moveto(0)
def on_mousewheel(self, event):
shift = (event.state & 0x1) != 0
scroll = -1 if event.delta > 0 else 1
if shift:
self.canvas.xview_scroll(scroll, "units")
else:
self.canvas.yview_scroll(scroll, "units")
def on_width_change(self, event):
canvas_width = event.width
# canvas_height = event.height
self.canvas.itemconfig(self.scrollable_frame_id, width=canvas_width * 0.99)
# self.canvas.itemconfig(self.scrollable_frame_id, height=canvas_height * 0.99)
def bind_tree(self, event, callback, widget=None):
"""
Binds an event to a widget and all its descendants.
"""
if widget is None:
widget = self
if isinstance(widget, AutocompleteCombobox) \
or isinstance(widget, BoundedSpinbox) \
or isinstance(widget, ttk.Combobox):
return
widget.bind(event, callback, "")
for child in widget.children.values():
self.bind_tree(widget=child, event=event, callback=callback)
def bind_list(self, widgets, event, callback):
for widget in widgets:
self.bind_tree(widget=widget, event=event, callback=callback)
def set_mouse_scroll_on_list(self, widgets):
self.bind_list(widgets, "<MouseWheel>", self.on_mousewheel)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment