Расположение таблицы grid на всю область фрэйма вкладки tab

Рейтинг: 1Ответов: 1Опубликовано: 05.04.2023

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

введите сюда описание изображения

import mysql.connector  
import config  
from tkinter import ttk  
import tkinter as tk  

db = mysql.connector.connect(
    host=config.host,
    user=config.user,
    password=config.password,
    database=config.database
)

mycursor = db.cursor()

mycursor.execute("DESCRIBE books")
for x in mycursor:
    print(x)

class LibraryDB:
    def __init__(self):
        self.root = tk.Tk()  
        self.root.geometry("1020x586")  
        self.root.title("Library")  
        self.root.resizable(False, False)
        self.root.iconbitmap("library.ico") 
        self.user_emoji = [":arrows_counterclockwise:"]

        s = ttk.Style()
        s.theme_create("MyStyle", parent="alt", settings={
            "TNotebook": {
                "configure": {
                    "tabmargins": [2, 4, 2, 0],
                    "background": "peachpuff2"
                }
            },
            "TNotebook.Tab": {
                "configure": {
                    "padding": [14, 6],
                    "font": ('Open Sans', '9', 'bold'),
                    "background": "lavender",
                    "foreground": "black"
                },
                "map": {
                    "background": [("selected", "antiquewhite")]
                },
                "label": {"background": "white"}
            },
            "TFrame": {
                "configure": {
                    "background": "antiquewhite"
                }
            }
        })
        s.theme_use("MyStyle")

        
        self.main_frame = tk.Frame(self.root)

        self.main_frame.grid(row=0, column=0, sticky="nsew")

        self.tab_control = ttk.Notebook(self.main_frame)

        self.tab1 = ttk.Frame(self.tab_control)
        self.tab2 = ttk.Frame(self.tab_control)
        self.tab3 = ttk.Frame(self.tab_control)
        self.tab4 = ttk.Frame(self.tab_control)
        self.tab5 = ttk.Frame(self.tab_control)
        self.tab6 = ttk.Frame(self.tab_control)
        self.tab7 = ttk.Frame(self.tab_control)
        self.tab8 = ttk.Frame(self.tab_control)

        self.tab_control.add(self.tab1, text='Книги')
        self.tab_control.add(self.tab2, text='Автор книги')
        self.tab_control.add(self.tab3, text='Авторы')
        self.tab_control.add(self.tab4, text='Жанры книги')
        self.tab_control.add(self.tab5, text='Жанры')
        self.tab_control.add(self.tab6, text='Издания')
        self.tab_control.add(self.tab7, text='Читатели')
        self.tab_control.add(self.tab8, text='Выдача книг')

        self.tab_control.grid(row=0, column=0, columnspan=3, sticky="nsew")

        self.tab1.rowconfigure(0, weight=1)
        self.tab1.columnconfigure(0, weight=1)

   
        self.tab1_obj = FirstTab(self.tab1)
        self.tab2_obj = SecondTab(self.tab2)



class FirstTab:
    def __init__(self, parent): 
        self.parent = parent  

    def frstframetab1(self):
        frame1 = tk.Frame(self.parent)
        # создаем лэйбл
        per_label = tk.Label(self.parent, text="Список книг", bg="antiquewhite",font=("Montserrat", 14))
        per_label.grid(row=0, column=0, padx=10, pady=10, sticky="W" )
        add_button = tk.Button(self.parent, text="Добавить", bg="thistle", width=9, font=("Montserrat", 10, "bold"))
        add_button.grid(row=0, column=0, padx=130, pady=0, sticky="W")
        del_button = tk.Button(self.parent, text="Удалить", bg="thistle", width=9, font=("Montserrat", 10, "bold"))
        del_button.grid(row=0, column=0, padx=160, pady=0, sticky="W")
        isbn_label = tk.Label(self.parent, text="ISBN",bg="antiquewhite", font=("Montserrat", 12))
        isbn_label.grid(row=2, column=0, padx=10, pady=10, sticky="W" )
        isbn_entry = tk.Entry(self.parent, bg="aliceblue", width=13).grid(row=2, column=0, padx=60, pady=10, sticky="W")
        name_label = tk.Label(self.parent, text="Название", bg="antiquewhite", font=("Montserrat", 12))
        name_label.grid(row=2, column=0, padx=153, pady=10, sticky="W")
        name_entry = tk.Entry(self.parent, bg="aliceblue", width=18).grid(row=2, column=0, padx=210, pady=10, sticky="W")
        author_label = tk.Label(self.parent, text="Автор", bg="antiquewhite", font=("Montserrat", 12))
        author_label.grid(row=2, column=0, padx=333, pady=10, sticky="W")
        author_entry = tk.Entry(self.parent, bg="aliceblue", width=15).grid(row=2, column=0, padx=390, pady=10, sticky="W")
        search_button = tk.Button(self.parent, text="Найти", bg="lightcyan", width=8, font=("Montserrat", 10))
        search_button.grid(row=2, column=0, padx=510, pady=10, sticky="W")
        inv_button = tk.Button(self.parent, text="Инвентарь", width=9, bg="powderblue", font=("Montserrat", 11))
        inv_button.grid(row=2, column=0, padx=664, pady=10, sticky="W")
        filauthor_button = tk.Button(self.parent, text="Фильтр по автору", width=25, bg="darksalmon", font=("Montserrat", 10))
        filauthor_button.grid(row=2, rowspan=2, column=0, padx=780, pady=10, sticky="se")
        filname_button = tk.Button(self.parent, text="Фильтр по названию", bg="darksalmon", width=25, font=("Montserrat", 10))
        filname_button.grid(row=3, column=0, padx=780, pady=50, sticky="se")
        filisbn_button = tk.Button(self.parent, text="Фильтр по ISBN", width=25, bg="darksalmon", font=("Montserrat", 10))
        filisbn_button.grid(row=3, rowspan=2, column=0, padx=780, pady=90, sticky="se")
        back_button = tk.Button(self.parent, text="<", bg="palegreen", width=4, font=("Arial", 8))
        back_button.grid(row=3, column=0, padx=780, pady=73, sticky="nw")
        next_button = tk.Button(self.parent, text=">", bg="palegreen", width=4, font=("Arial", 8))
        next_button.grid(row=3, column=0, padx=820, pady=73, sticky="nw")
        change_button = tk.Button(self.parent, text="Изменить", width=10, bg="plum2", font=("Montserrat", 10))
        change_button.grid(row=3, column=0, padx=780, pady=0, sticky="nw")
        save_button = tk.Button(self.parent, text="Сохранить", width=11, bg="palegreen1", font=("Montserrat", 10))
        save_button.grid(row=3, column=0, padx=780, pady=0, sticky="en")
        rollback_button = tk.Button(self.parent, text="Откат изменений", width=25, bg="skyblue", font=("Montserrat", 10))
        rollback_button.grid(row=3, column=0, padx=780, pady=35, sticky="n")

    def select_all_books(self):
        # Выполняем запрос к базе данных для получения всех книг
        # mycursor.execute("SELECT * FROM book")
        # rows = mycursor.fetchall()  # Получаем все строки результата запроса

        # Создаем таблицу для отображения информации о книгах
        table = ttk.Treeview(self.parent, columns=(
        'ISBN', 'Название', 'Издание', 'Город', 'Год', 'Кол-во страниц', 'Кол-во экземпляров'), show='headings')
        table.column('ISBN', width=40, anchor=tk.CENTER)
        table.column('Название', width=120, anchor=tk.CENTER)
        table.column('Издание', width=120, anchor=tk.CENTER)
        table.column('Город', width=100, anchor=tk.CENTER)
        table.column('Год', width=80, anchor=tk.CENTER)
        table.column('Кол-во страниц', width=120, anchor=tk.CENTER)
        table.column('Кол-во экземпляров', width=170, anchor=tk.CENTER)
        table.heading('ISBN', text='ISBN')
        table.heading('Название', text='Название')
        table.heading('Издание', text='Издание')
        table.heading('Город', text='Город')
        table.heading('Год', text='Год')
        table.heading('Кол-во страниц', text='Кол-во страниц')
        table.heading('Кол-во экземпляров', text='Кол-во экземпляров')

        # # Заполняем таблицу данными из базы данных
        # for row in row:
        #     table.insert('', tk.END, values=row)

        # Помещаем таблицу на фрейм
        table.grid(row=3, column=0, columnspan=4, padx=10, pady=0, sticky="W")



class SecondTab:
    def __init__(self, parent):
        self.parent = parent

    def frstframetab2(self):
        # создаем лэйбл
        per_label = tk.Label(self.parent, text="Список книг")
        per_label.grid(row=0, column=0, padx=5, pady=5, sticky="w")


if __name__ == '__main__':
    library_db = LibraryDB()
    library_db.tab1_obj.frstframetab1()
    library_db.tab1_obj.select_all_books()
    library_db.tab2_obj.frstframetab2()
    library_db.root.mainloop()

Ответы

▲ 1Принят

При размещении через grid чтобы фрейм расширялся в окне, нужно для самого окна задать, чтобы его нулевой столбец и нулевая строка сетки имели вес 1. Чтобы Notebook расширялся в этом фрейме, нужно те же настройки выполнить для самого фрейма.

В tab1 наоборот это нужно убрать, иначе его "нулевая" ячейка попытается занять максимальное пространство. В tab1 имеет смысл добавить вес, например, строке с таблицей, чтобы таблица расширилась по высоте (в коде ниже я это не делал).

Т.е. настраивать нужно сетку (веса колонок и строк) у фрейма или окна, где виджет размещается, а не сетку виджета.

Итого, фрагмент кода с изменениями:

self.main_frame = tk.Frame(self.root)
self.main_frame.grid(row=0, column=0, sticky="nsew")
self.root.rowconfigure(0, weight=1)  # <<<
self.root.columnconfigure(0, weight=1)  # <<<

self.tab_control = ttk.Notebook(self.main_frame)
self.tab_control.grid(row=0, column=0, columnspan=3, sticky="nsew")
self.main_frame.rowconfigure(0, weight=1)  # <<<
self.main_frame.columnconfigure(0, weight=1)  # <<<

self.tab1 = ttk.Frame(self.tab_control)
self.tab2 = ttk.Frame(self.tab_control)
self.tab3 = ttk.Frame(self.tab_control)
self.tab4 = ttk.Frame(self.tab_control)
self.tab5 = ttk.Frame(self.tab_control)
self.tab6 = ttk.Frame(self.tab_control)
self.tab7 = ttk.Frame(self.tab_control)
self.tab8 = ttk.Frame(self.tab_control)

self.tab_control.add(self.tab1, text='Книги')
self.tab_control.add(self.tab2, text='Автор книги')
self.tab_control.add(self.tab3, text='Авторы')
self.tab_control.add(self.tab4, text='Жанры книги')
self.tab_control.add(self.tab5, text='Жанры')
self.tab_control.add(self.tab6, text='Издания')
self.tab_control.add(self.tab7, text='Читатели')
self.tab_control.add(self.tab8, text='Выдача книг')

# self.tab1.rowconfigure(0, weight=1)  # ---
# self.tab1.columnconfigure(0, weight=1) # ---
   
self.tab1_obj = FirstTab(self.tab1)
self.tab2_obj = SecondTab(self.tab2)

В принципе, для размещения одного виджета с авторасширением удобнее использовать pack вместо grid, там достаточно все настройки в самом pack указать:

self.main_frame = tk.Frame(self.root)
self.main_frame.pack(fill="both", expand=True)

self.tab_control = ttk.Notebook(self.main_frame)
self.tab_control.pack(fill="both", expand=True)

Скриншот