Last active
June 20, 2024 08:32
-
-
Save PaulCreusy/57faa597182d1c968ef1c3385e769f9c to your computer and use it in GitHub Desktop.
Scrollable Frame for tkinter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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