I have created a GUI with a scrollbar in customtkinter
, but I have some problems with it. The GUI consists of two frames: the first one is a scrollable canvas frame with input fields; the second frame consists of a single button that, when clicked, adds fields to the first frame. The problem is that the height of the first frame is initially set to 400, but I want to add some height each time the Add row button is clicked. I tried to do it by self.canvas.itemconfigure(self.window, height=400 (50*self.xr)
, but it doesn't seem to work: there is no visual effect, but after printing the height of the frame is changed.
import customtkinter
class Adder:
def __init__(self, app):
self.app = app
self.app.title("self.Scrollbar testing")
self.app.geometry('{}x{} {} {}'.format(550, 460, 750, 250))
self.xr = 1
self.app.grid_rowconfigure(0, weight=1)
self.app.grid_columnconfigure(0, weight=1)
self.frame = customtkinter.CTkFrame(master=self.app)
self.frame.grid(row=0,column=0, padx=15,pady=15, sticky="NSEW")
self.frame.grid_rowconfigure(0, weight=1)
self.frame.grid_columnconfigure(0, weight=1)
self.canvas = customtkinter.CTkCanvas(self.frame)
self.canvas.grid(row=0,column=0, sticky="NSEW")
self.canvas.grid_rowconfigure(0, weight=1)
self.canvas.grid_columnconfigure(0, weight=1)
self.frame_2 = customtkinter.CTkFrame(master=self.canvas)
self.scrollbar = customtkinter.CTkScrollbar(master=self.frame, orientation="vertical", command=self.canvas.yview, height=460, width=15)
self.scrollbar.grid(row=0, column=0, sticky="NE")
self.canvas.configure(yscrollcommand=self.scrollbar.set)
self.canvas.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
self.window = self.canvas.create_window((0,0), window=self.frame_2, anchor="nw", height=400)
self.entry_1 = customtkinter.CTkEntry(master=self.frame_2, placeholder_text=f"entry")
self.entry_1.grid(row=0, column=0, sticky="NSEW", padx=10, pady=10)
self.entry_2 = customtkinter.CTkEntry(master=self.frame_2, placeholder_text=f"entry")
self.entry_2.grid(row=0, column=1, sticky="NSEW", padx=10, pady=10)
self.entry_3 = customtkinter.CTkEntry(master=self.frame_2, placeholder_text=f"entry")
self.entry_3.grid(row=0, column=2, sticky="NSEW", padx=10, pady=10)
self.frame_3 = customtkinter.CTkFrame(master=self.app)
self.frame_3.grid(row=1,column=0, sticky="NSEW", pady=10)
def add_row():
self.canvas.itemconfigure(self.window, height=400 (50*self.xr))
self.entry_1 = customtkinter.CTkEntry(master=self.frame_2, placeholder_text=f"entry")
self.entry_1.grid(row=self.xr, column=0, sticky="NSEW", padx=10, pady=10)
self.entry_2 = customtkinter.CTkEntry(master=self.frame_2, placeholder_text=f"entry")
self.entry_2.grid(row=self.xr, column=1, sticky="NSEW", padx=10, pady=10)
self.entry_3 = customtkinter.CTkEntry(master=self.frame_2, placeholder_text=f"entry")
self.entry_3.grid(row=self.xr, column=2, sticky="NSEW", padx=10, pady=10)
self.xr = 1
button = customtkinter.CTkButton(master=self.frame_3, text="Add row", command=add_row)
button.grid(row=0, column=1, columnspan=3, padx=10, pady=10)
root = customtkinter.CTk()
app = Adder(root)
root.mainloop()
CodePudding user response:
I hope i understood your problem correctly as the self.canvas.itemconfigure(self.window, height=400 (50*self.xr)
in fact does work (you can see it getting bigger if you make the gui bigger).
The problem you are probably having is that you cant access the newly created space by scrolling. To achieve this you will need to add
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
right below your self.canvas.itemconfigure(self.window, height=400 (50*self.xr))
This let's your scrollbar work even after you change the size by clicking the button.
import customtkinter
class Adder:
def __init__(self, app):
self.app = app
self.app.title("self.Scrollbar testing")
self.app.geometry('{}x{} {} {}'.format(550, 460, 750, 250))
self.xr = 1
self.app.grid_rowconfigure(0, weight=1)
self.app.grid_columnconfigure(0, weight=1)
self.frame = customtkinter.CTkFrame(master=self.app)
self.frame.grid(row=0, column=0, padx=15, pady=15, sticky="NSEW")
self.frame.grid_rowconfigure(0, weight=1)
self.frame.grid_columnconfigure(0, weight=1)
self.canvas = customtkinter.CTkCanvas(self.frame)
self.canvas.grid(row=0, column=0, sticky="NSEW")
self.canvas.grid_rowconfigure(0, weight=1)
self.canvas.grid_columnconfigure(0, weight=1)
self.frame_2 = customtkinter.CTkFrame(master=self.canvas)
self.scrollbar = customtkinter.CTkScrollbar(
master=self.frame, orientation="vertical", command=self.canvas.yview, height=460, width=15)
self.scrollbar.grid(row=0, column=0, sticky="NE")
self.canvas.configure(yscrollcommand=self.scrollbar.set)
self.canvas.bind("<Configure>", lambda e: self.canvas.configure(
scrollregion=self.canvas.bbox("all")))
self.window = self.canvas.create_window(
(0, 0), window=self.frame_2, anchor="nw", height=400)
self.entry_1 = customtkinter.CTkEntry(
master=self.frame_2, placeholder_text=f"entry")
self.entry_1.grid(row=0, column=0, sticky="NSEW", padx=10, pady=10)
self.entry_2 = customtkinter.CTkEntry(
master=self.frame_2, placeholder_text=f"entry")
self.entry_2.grid(row=0, column=1, sticky="NSEW", padx=10, pady=10)
self.entry_3 = customtkinter.CTkEntry(
master=self.frame_2, placeholder_text=f"entry")
self.entry_3.grid(row=0, column=2, sticky="NSEW", padx=10, pady=10)
self.frame_3 = customtkinter.CTkFrame(master=self.app)
self.frame_3.grid(row=1, column=0, sticky="NSEW", pady=10)
def add_row():
self.canvas.itemconfigure(self.window, height=400 (50*self.xr))
self.canvas.configure(
scrollregion=self.canvas.bbox("all"))
self.entry_1 = customtkinter.CTkEntry(
master=self.frame_2, placeholder_text=f"entry")
self.entry_1.grid(row=self.xr, column=0,
sticky="NSEW", padx=10, pady=10)
self.entry_2 = customtkinter.CTkEntry(
master=self.frame_2, placeholder_text=f"entry")
self.entry_2.grid(row=self.xr, column=1,
sticky="NSEW", padx=10, pady=10)
self.entry_3 = customtkinter.CTkEntry(
master=self.frame_2, placeholder_text=f"entry")
self.entry_3.grid(row=self.xr, column=2,
sticky="NSEW", padx=10, pady=10)
self.xr = 1
button = customtkinter.CTkButton(
master=self.frame_3, text="Add row", command=add_row)
button.grid(row=0, column=1, columnspan=3, padx=10, pady=10)
root = customtkinter.CTk()
app = Adder(root)
root.mainloop()
CodePudding user response:
Since you are using grid
to manage the entry widgets in the frame, you shouldn't set the height of the canvas object. By removing both instances of height=...
the frame will automatically always be tall enough to hold all of the entry widgets.
The other thing you need to do is reconfigure the scrollregion
whenever the frame changes size (either by you computing the height, or by letting grid
recompute it for you.
If you remove the explicit setting of the height, you can define add_row
to look like this - note the final statement that was added:
def add_row():
self.entry_1 = customtkinter.CTkEntry(master=self.frame_2, placeholder_text=f"entry")
self.entry_1.grid(row=self.xr, column=0, sticky="NSEW", padx=10, pady=10)
self.entry_2 = customtkinter.CTkEntry(master=self.frame_2, placeholder_text=f"entry")
self.entry_2.grid(row=self.xr, column=1, sticky="NSEW", padx=10, pady=10)
self.entry_3 = customtkinter.CTkEntry(master=self.frame_2, placeholder_text=f"entry")
self.entry_3.grid(row=self.xr, column=2, sticky="NSEW", padx=10, pady=10)
self.xr = 1
self.canvas.configure(scrollregion=self.canvas.bbox("all"))