Обновление размера рамки на холсте в customtkinter

Я создал графический интерфейс с полосой прокрутки в, но у меня есть некоторые проблемы с этим. Графический интерфейс состоит из двух фреймов: первый представляет собой прокручиваемый фрейм холста с полями ввода; второй фрейм состоит из одной кнопки, при нажатии которой поля добавляются в первый фрейм. Проблема в том, что высота первого кадра изначально установлена ​​на 400, но я хочу добавлять высоту каждый раз, когда Add rowнажимается кнопка. я пытался сделать это через, но вроде не работает: визуального эффекта нет, но после печати высота рамки меняется.

      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()

2 ответа

Надеюсь, я правильно понял вашу проблему, поскольку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()

Поскольку вы используете для управления виджетами ввода в кадре, вам не следует устанавливать высоту объекта холста. Удалив оба экземпляра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"))

Другие вопросы по тегам