Шаг 19.
Библиотека Tkinter. Размещение компонентов в контейнерах. Диспетчеры компоновки. Адаптивный интерфейс и его реализация

    На этом шаге мы рассмотрим создание такого интерфейса.

    Очень часто какое-либо окно (обычно главное) позволяет пользователю изменять свои размеры, и при этом размеры присутствующих там элементов управления изменяются автоматически, чтобы занять все пространство окна. Подобного рода интерфейс носит название адаптивного.

    В Tkinter-приложениях реализовать адаптивный интерфейс несложно. Проще всего, если окно должно позволять пользователю менять лишь свою ширину. Тогда мы можем поместить контейнер в окно с помощью диспетчера компоновки Pack, указав для параметра fill метода pack() значение "both" (за подробностями - в 14 шаг). Вот пример кода, реализующего такой подход:

  class Application(tkinter.ttk.Frame): 
      def __init__ (self, master=None):
          .    .    .    .
          self.pack(fill="both")
          .    .    .    .
          self.master.resizable(True, False)

    Однако, если планируется сделать изменяемыми и ширину, и высоту окна, диспетчер компоновки Pack не подойдет, поскольку он в таком случае почему-то не растягивается по высоте окна. Удобнее тогда использовать диспетчер компоновки Grid (см. 16 шаг), настроив соответствующим образом параметры сетки.

    Ранее уже говорилось, что библиотека Tkinter рассматривает окна как компоненты, и окна поддерживают функциональность диспетчеров компоновки. Тогда, поместив контейнер с компонентами в окно посредством диспетчера компоновки Grid, мы можем вызвать у самого окна методы row_configure() и column_configure() - с целью указать параметры для строки и столбца сетки. В частности, мы можем сделать их растягивающимися, задав соответствующие значения для параметра weight этих методов.

    Пример ниже содержит исправленный код класса контейнера в приложении из 16 шага. В новой версии приложения окно позволяет пользователю менять и ширину, и высоту, а кнопка Выход в любом случае будет находиться в правом нижнем углу окна.

import tkinter
import tkinter.ttk

class Application(tkinter.ttk.Frame):
      def __init__(self, master=None):
            super().__init__(master)

            # Помещаем контейнер в окно и указываем, что он должен
            # растягиваться на все свободное пространство окна
            self.grid(sticky="w, n, e, s", padx=4, pady=4)
            # Указываем, что единственная строка и единственный столбец
            # сетки в окне должны растягиваться
            self.master.grid_rowconfigure(0, weight=1)
            self.master.grid_columnconfigure(0, weight=1)

            self.create_widgets()
            self.master.title("Grid")

            # Удаляем вызов метода resizable() окна, указывая тем самым, что
            # оно предоставляет пользователю возможность менять оба размера


      def create_widgets(self):
            entValue = tkinter.ttk.Entry(self)

            entValue.grid(sticky="w, e")
            btnShow = tkinter.ttk.Button(self, text="Вывести значение")
            btnShow.grid(row=0, column=1, sticky="w, e")
            btnExit = tkinter.ttk.Button(self, text="Выход")
            btnExit.grid(column=1, sticky="e, s")

            # Делаем вторую строку, в которой находится кнопка выхода,
            # растягивающейся
            self.grid_rowconfigure(1, weight=1, pad=5)
            
            self.grid_columnconfigure(0, minsize=100, weight=2, pad=5)
            self.grid_columnconfigure(1, weight=1, pad=5)


root = tkinter.Tk()
app = Application(master=root)
root.mainloop()
Архив с файлом можно взять здесь.

    Результат работы приложения изображен на рисунке 1.


Рис.1. Результат работы приложения

    Со следующего шага мы начнем рассматривать работу с окнами.




Предыдущий шаг Содержание Следующий шаг