Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resize Canvas scrollable widget?

The idea is that the scrollable canvas and its text widgets grow or fill the entire root/toplevel when I resize it.

I can do this if I work on Frames but for a scrollable frame you need to create a canvas widget and make it scrollable. Now I don't know if the problem is the canvas or the inserted widgets on the canvas?

import tkinter as tk
from tkinter import ttk

class ScrollableFrame():
    def __init__(self, container, *args, **kwargs):
        self.container = container
        self.canvas = tk.Canvas(self.container, bg="green")
        self.scrollbar = ttk.Scrollbar(self.container, orient="horizontal", command=self.canvas.xview)
        self.scrollable_frame = tk.Frame(self.canvas)
        self.scrollable_frame.grid(sticky="wesn")
        self.scrollable_frame.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))

        self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
        self.canvas.configure(xscrollcommand=self.scrollbar.set)
        
        self.canvas.grid(row=0, column=0, sticky="wesn")
        self.scrollbar.grid(row=1, column=0, sticky="wesn")
        
if __name__ == "__main__":
    root = tk.Tk()
    root.configure(bg="grey20")
    
    s = ScrollableFrame(root)
    
    t = tk.Text(s.scrollable_frame)
    t.grid(row=0, column=0, sticky="wesn")
    
    t2 = tk.Text(s.scrollable_frame)
    t2.grid(row=0, column=1, sticky="wesn")

    root.mainloop()
    

I'm glad for help

like image 319
Module_art Avatar asked May 18 '26 20:05

Module_art


1 Answers

Base on the requirement in the comment, you want to grow/shrink the two text boxes when the root window is resized. Below is the modified code with the necessary changes to achieve it:

import tkinter as tk
from tkinter import ttk

class ScrollableFrame():
    def __init__(self, container, *args, **kwargs):
        self.container = container
        self.canvas = tk.Canvas(self.container, bg="green")
        self.scrollbar = ttk.Scrollbar(self.container, orient="horizontal", command=self.canvas.xview)
        self.scrollable_frame = tk.Frame(self.canvas)
        self.scrollable_frame.grid(sticky="wesn")
        self.scrollable_frame.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))

        self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw", tags="scrollable")
        self.canvas.configure(xscrollcommand=self.scrollbar.set)

        self.canvas.grid(row=0, column=0, sticky="wesn")
        self.scrollbar.grid(row=1, column=0, sticky="we") # fill horizontally only

        # make self.canvas to fill all the available space of container
        container.rowconfigure(0, weight=1)
        container.columnconfigure(0, weight=1)

        # resize self.scrollable_frame when self.canvas is resized
        self.canvas.bind("<Configure>", lambda e: self.canvas.itemconfig("scrollable", width=e.width, height=e.height))

if __name__ == "__main__":
    root = tk.Tk()
    root.configure(bg="grey20")

    s = ScrollableFrame(root)

    # make the two text boxes to fill all the space of s.scrollable_frame
    s.scrollable_frame.rowconfigure(0, weight=1)
    s.scrollable_frame.columnconfigure((0,1), weight=1)

    t = tk.Text(s.scrollable_frame)
    t.grid(row=0, column=0, sticky="wesn")

    t2 = tk.Text(s.scrollable_frame)
    t2.grid(row=0, column=1, sticky="wesn")

    root.mainloop()

So basically the logic is when the root window is resized, the canvas is resized to fill the root window. Then the frame (scrollable_frame) inside the canvas is resized to fill the canvas and finally the two text widgets are resized to fill the scrollable_frame.

like image 103
acw1668 Avatar answered May 22 '26 01:05

acw1668



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!