Я создал графический интерфейс с полосой прокрутки в customtkinter
, но у меня есть некоторые проблемы с этим. Графический интерфейс состоит из двух фреймов: первый представляет собой прокручиваемый фрейм холста с полями ввода; второй фрейм состоит из одной кнопки, при нажатии которой поля добавляются в первый фрейм. Проблема в том, что высота первого кадра изначально установлена на 400, но я хочу добавлять высоту каждый раз, когда нажимается кнопка Add row. Пытался сделать по self.canvas.itemconfigure(self.window, height=400+(50*self.xr)
, но не получается: визуального эффекта нет, но после печати меняется высота рамки.
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()
Высоту рамки лучше не задавать изначально, а просто позволить добавленным полям ввода увеличить ее высоту.
Отступ вашего кода нарушен.
Надеюсь, я правильно понял вашу проблему, так как self.canvas.itemconfigure(self.window, height=400+(50*self.xr)
на самом деле работает (вы можете увидеть, как он становится больше, если вы увеличиваете графический интерфейс).
Проблема, с которой вы, вероятно, сталкиваетесь, заключается в том, что вы не можете получить доступ к вновь созданному пространству с помощью прокрутки. Для этого вам нужно будет добавить
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
прямо под вашим self.canvas.itemconfigure(self.window, height=400+(50*self.xr))
Это позволит вашей полосе прокрутки работать даже после того, как вы измените размер, нажав кнопку.
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()
Поскольку вы используете grid
для управления виджетами ввода в кадре, вам не следует устанавливать высоту объекта холста. Удалив оба экземпляра height=...
, рамка автоматически всегда будет достаточно высокой, чтобы вместить все виджеты входа.
Еще одна вещь, которую вам нужно сделать, это перенастроить scrollregion
всякий раз, когда размер кадра изменяется (либо путем вычисления вами высоты, либо позволяя grid
пересчитать ее для вас.
Если вы удалите явную настройку высоты, вы можете определить add_row
, чтобы она выглядела так — обратите внимание на последнее добавленное утверждение:
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"))
Вам нужно привязать событие
<Configure>
кframe_2
вместоcanvas
.