2025, Sep 27 23:16

Почему grid_columnconfigure не работает в ThemedTKinterFrame и как это исправить

Почему в ThemedTKinterFrame grid_columnconfigure не работает и как это починить: запустите run(cleanresize=False) и настройте веса строк и колонок вручную.

Когда вы собираете интерфейс с TKinterModernThemes и внезапно сетка перестает слушаться ваших настроек, виновник нередко не сама grid. Поведение автоподгонки по умолчанию в ThemedTKinterFrame может перекрывать ручное управление геометрией, из‑за чего создается впечатление, что grid_columnconfigure «не работает». Ниже — короткое объяснение, почему так происходит, и как вернуть контроль, не споря с фреймворком.

Воспроизведение: grid_columnconfigure будто ничего не делает

В примере ниже используется ThemedTKinterFrame: второй колонке отдается «растяжка», а первая должна оставаться фиксированной. На первый взгляд код верный, но компоновка ведет себя не так, как ожидается.

import tkinter as tk
import TKinterModernThemes as TKM

class UiPanel(TKM.ThemedTKinterFrame):
    def __init__(self, theme, mode, usecommandlineargs=True, usethemeconfigfile=True):
        super().__init__("Switch", theme, mode, usecommandlineargs=usecommandlineargs, useconfigfile=usethemeconfigfile)
        self.grp_left = self.addLabelFrame("Switch Frame 1", sticky=tk.NSEW, row=0, col=0)
        self.flag_left = tk.BooleanVar()
        self.grp_left.SlideSwitch("Switch1", self.flag_left)

        self.grp_right = self.addLabelFrame("Switch Frame 2", sticky=tk.NSEW, row=0, col=1)
        self.flag_right = tk.BooleanVar()
        self.grp_right.SlideSwitch("Switch2", self.flag_right)

        self.root.grid_columnconfigure(0, weight=0)
        self.root.grid_columnconfigure(1, weight=1)

        self.run()

if __name__ == "__main__":
    UiPanel("park", "dark")

Что на самом деле происходит

Метод run в фреймворке выполняет внутреннюю логику изменения размеров, которая может перезаписывать ваши настройки grid. На практике из‑за этого вызовы grid_columnconfigure выглядят бесполезными. Если отключить этот внутренний проход, ответственность за компоновку целиком ложится на вас — причём не только по колонкам, но и по строкам.

Решение: отключите внутреннюю подгонку и управляйте grid вручную

Передайте в run параметр cleanresize=False. После этого вручную задайте веса строк, чтобы фреймы растягивались не только по горизонтали, но и по вертикали.

import tkinter as tk
import TKinterModernThemes as TKM

class UiPanel(TKM.ThemedTKinterFrame):
    def __init__(self, theme, mode, usecommandlineargs=True, usethemeconfigfile=True):
        super().__init__("Switch", theme, mode, usecommandlineargs=usecommandlineargs, useconfigfile=usethemeconfigfile)
        self.grp_left = self.addLabelFrame("Switch Frame 1", sticky=tk.NSEW, row=0, col=0)
        self.flag_left = tk.BooleanVar()
        self.grp_left.SlideSwitch("Switch1", self.flag_left)

        self.grp_right = self.addLabelFrame("Switch Frame 2", sticky=tk.NSEW, row=0, col=1)
        self.flag_right = tk.BooleanVar()
        self.grp_right.SlideSwitch("Switch2", self.flag_right)

        self.root.grid_columnconfigure(0, weight=0)
        self.root.grid_columnconfigure(1, weight=1)
        self.root.grid_rowconfigure(0, weight=1)

        self.run(cleanresize=False)

if __name__ == "__main__":
    UiPanel("park", "dark")

С отключенным cleanresize ваши настройки сетки сохраняются; а добавив grid_rowconfigure для строки 0, вы обеспечите вертикальное растяжение фреймов, как и задумывалось.

Почему эта деталь важна

Когда тулкит управляет геометрией неявно, ваши ручные правки компоновки могут тихо откатываться. Понимание того, что ThemedTKinterFrame во время run способен перезаписывать настройки grid, избавляет от долгих поисков причины. Отказавшись от внутренней подгонки, берите сетку под полный контроль: явно настраивайте и колонки, и строки.

Итоги

Если в ThemedTKinterFrame кажется, что grid_columnconfigure игнорируется, отключите внутреннюю подгонку, вызвав run с cleanresize=False, а затем самостоятельно настройте и колонки, и строки grid. Это небольшое изменение возвращает предсказуемый, явный контроль над компоновкой и заставляет интерфейс вести себя ровно так, как вы задумали.

Статья основана на вопросе со StackOverflow от marco и ответе Aadvik.