2025, Oct 22 10:01
CTkTabview не растягивается по высоте в customtkinter: что происходит и как исправить
Разбираем баг customtkinter: CTkTabview растягивается, но контент вкладок не заполняет высоту. Минимальный пример и рабочее решение с anchor='s'. Гайд внутри.
CTkTabview не заполняет вертикальное пространство в customtkinter: что происходит и как это исправить
Иногда CTkTabview выглядит так, словно занимает лишь две трети высоты окна, а внизу остается большая пустая область. Grid настроен на растяжение, для sticky указано nsew, но содержимое всё равно не заполняет всю высоту. Разберём минимальный пример, первопричину и рабочее решение.
Минимальный воспроизводимый пример
import customtkinter
class MainWindow(customtkinter.CTk):
    def __init__(self):
        super().__init__()
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)
        self.tabs = TabBook(self)
        self.tabs.grid(column=0, row=0, sticky="nsew")
class TabBook(customtkinter.CTkTabview):
    def __init__(self, master):
        super().__init__(master)
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)
        self.add("Tab")
        self.tab("Tab").grid_columnconfigure(0, weight=1)
        self.tab("Tab").grid_rowconfigure(0, weight=1)
        self.tab("Tab").grid(column=0, row=0, sticky="nsew")
Что на самом деле происходит
Похоже, это баг в customtkinter. Сам экземпляр CTkTabview растягивается и заполняет окно, как и ожидается, но внутренняя область содержимого CTkTabview занимает только верхнюю часть виджета. Остальное пространство остаётся неиспользованным. Это легко проверить: поместите внутри вкладки заметный виджет — он будет прижат к верху, а нижняя часть останется пустой.
Как исправить
Инициализируйте CTkTabview с параметром anchor, установленным в "s". С anchor="s" виджет ведёт себя корректно, и содержимое вкладки использует доступное вертикальное пространство как задумано.
import customtkinter
class MainWindow(customtkinter.CTk):
    def __init__(self):
        super().__init__()
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)
        self.tabs = TabBook(self)
        self.tabs.grid(column=0, row=0, sticky="nsew")
class TabBook(customtkinter.CTkTabview):
    def __init__(self, master):
        super().__init__(master, anchor='s')
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)
        self.add("Tab")
        self.tab("Tab").grid_columnconfigure(0, weight=1)
        self.tab("Tab").grid_rowconfigure(0, weight=1)
        self.tab("Tab").grid(column=0, row=0, sticky="nsew")
Почему это важно
Когда макет выглядит неправильно, легко заподозрить веса grid, флаги sticky или размеры контейнера. В этом случае всё это уже настроено верно; проблема кроется внутри CTkTabview. Знание того, что сам виджет заполняет родительский контейнер, а его область содержимого — нет, помогает не гоняться за мнимыми ошибками сетки в своём коде.
В репозитории CustomTkinter открыт ишью, отслеживающее это поведение: github.com/TomSchimansky/CustomTkinter/issues/2739
Вывод
Если ваш CTkTabview будто упирается в верхнюю часть окна, оставьте текущие настройки grid и sticky как есть и укажите anchor="s" при создании CTkTabview. Пока апстрим-ошибка не исправлена, эта настройка помогает согласовать содержимое вкладок с доступным пространством и вернуть ожидаемую полноэкранную высоту макета.