Расширяете виджеты для заполнения панели в Tkinter?

Я пытаюсь создать простой пользовательский интерфейс в Python / Tkinter с виджетом Entry, виджетом Text и двумя кнопками рядом. Я бы хотел, чтобы все виджеты расширялись по ширине при расширении окна, а виджет «Текст» также увеличивался по высоте при расширении окна.

Я обыскал целую кучу, и всегда всплывает, что в сетке назначается ненулевой вес, но я думаю, что уже делаю это; но когда я изменяю размер, виджеты остаются в центре сетки, а не расширяются, чтобы соответствовать размеру окна.

Вот что у меня есть сейчас; какие-либо предложения?

class EditWindow(Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.create_widgets()

    def create_widgets(self):
        self.grid()

        self.subject_box = Entry(self)
        self.subject_box.insert(0, "Some text")
        self.subject_box.grid(column=0, columnspan=2, row=0, sticky="NSEW")

        self.content_box = Text(self)
        self.content_box.insert(END, "Other text")
        self.content_box.grid(column=0, columnspan=2, row=1, sticky="NSEW")

        self.done_button = Button(self)
        self.done_button["text"] = "Done (Temporary Change)"
        self.done_button["command"] = self.done
        self.done_button.grid(column=0, row=2, sticky="NSEW")

        self.done_and_save_button = Button(self)
        self.done_and_save_button["text"] = "Done (Permanently Save Changes)"
        self.done_and_save_button["command"] = self.done_and_save
        self.done_and_save_button.grid(column=1, row=2, sticky="NSEW")

        Grid.rowconfigure(self.master, 0, weight=1)
        Grid.rowconfigure(self.master, 1, weight=1)
        Grid.rowconfigure(self.master, 2, weight=1)
        Grid.columnconfigure(self.master, 0, weight=1)

    def done(self):
        self.save_changes = False
        self.master.destroy()

    def done_and_save(self):
        self.save_changes = True
        self.master.destroy()

person David    schedule 22.09.2020    source источник
comment
Вы пробовали grid_rowconfigure() и то же самое с столбцом?   -  person Cool Cloud    schedule 22.09.2020
comment
Здесь у вас два разных контейнера - self.master (предположительно окно, я не могу сказать, потому что вы не опубликовали минимальный воспроизводимый пример) и self (фрейм). Каждый имеет свой собственный независимый набор конфигураций строки / столбца. Установка всех этих конфигураций на self.master бесполезна, если это не родительский элемент виджетов, которые вы хотите развернуть.   -  person jasonharper    schedule 22.09.2020


Ответы (1)


Все виджеты существуют внутри EditWindow, поэтому вам нужно вызывать rowconfigure и columnconfigure на self, а не self.master. Этот код не должен ничего делать с master, кроме как использовать его как мастер для себя. Этот код также не должен вызывать self.pack() или self.grid().

Код, создающий экземпляр EditWindow, должен отвечать за вызов pack, place или grid. Когда виджет вызывает одну из команд диспетчера геометрии для себя, он требует, чтобы виджет знал, как он используется мастером. Это ограничивает возможность повторного использования и слишком сильно связывает класс с кодом, который его использует.

Вот полный пример со следующими изменениями:

  • удалено self.pack из __init__
  • удалено self.grid() из create_widgets
  • изменил команды Grid для работы с self, а не с self.master
  • вызвал пакет с соответствующими параметрами из той же области, в которой был создан экземпляр EditWindow.

from tkinter import *

class EditWindow(Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.create_widgets()

    def create_widgets(self):

        self.subject_box = Entry(self)
        self.subject_box.insert(0, "Some text")
        self.subject_box.grid(column=0, columnspan=2, row=0, sticky="NSEW")

        self.content_box = Text(self)
        self.content_box.insert(END, "Other text")
        self.content_box.grid(column=0, columnspan=2, row=1, sticky="NSEW")

        self.done_button = Button(self)
        self.done_button["text"] = "Done (Temporary Change)"
        self.done_button["command"] = self.done
        self.done_button.grid(column=0, row=2, sticky="NSEW")

        self.done_and_save_button = Button(self)
        self.done_and_save_button["text"] = "Done (Permanently Save Changes)"
        self.done_and_save_button["command"] = self.done_and_save
        self.done_and_save_button.grid(column=1, row=2, sticky="NSEW")

        Grid.rowconfigure(self, 0, weight=1)
        Grid.rowconfigure(self, 1, weight=1)
        Grid.rowconfigure(self, 2, weight=1)
        Grid.columnconfigure(self, 0, weight=1)

    def done(self):
        self.save_changes = False
        self.master.destroy()

    def done_and_save(self):
        self.save_changes = True
        self.master.destroy()

root = Tk()
ew = EditWindow(root)
ew.pack(fill="both", expand=True)
root.mainloop()
person Bryan Oakley    schedule 22.09.2020
comment
Спасибо! Это фантастически близко. После этого я понял, что на самом деле мне нужно только изменять размер поля «Контент» по вертикали, но у меня это тоже работало. - person David; 24.09.2020