Метод Tkinter Frame tkraise() в Python с примерами

Метод Frame tkraise() в Python используется для переключения между фреймами в приложении Tkinter.

Что такое метод Frame tkraise()?

Обычно приложение Tkinter состоит из нескольких фреймов. И часто приходится переключаться между фреймами, чтобы отобразить тот, который соответствует выбору пользователя.

Tkinter позволяет вам накладывать кадры друг на друга. Чтобы показать определенный кадр, вы можете просто поднять один над другим в порядке наложения. Верхний кадр будет виден.

Чтобы переместить рамку наверх, используйте метод tkraise() виджета Frame следующим образом:

frame.tkraise()

Пример метода Frame tkraise()

В этом примере вы расширите приложение преобразователя температуры, добавив преобразование температуры из градусов Цельсия в градусы Фаренгейта:

Пример преобразования температуры из градусов Цельсия в градусы Фаренгейта

По умолчанию приложение преобразует температуру из градусов Фаренгейта в градусы Цельсия.

Использование метода Frame tkraise()

Если вы выберете переключатель «C в F», приложение отобразит новый фрейм, позволяющий преобразовать температуру из градусов Цельсия в градусы Фаренгейта:

Пример выбора переключателя «C в F»

Для создания этого приложения вам понадобятся три основных виджета:

  • Корневое окно.
  • ConverterFrame, отображающий поля формы.
  • И ControlFrame, который показывает переключатели.

Три основных виджета

ConverterFrame будет иметь два экземпляра: один, преобразующий температуру из градусов Фаренгейта в градусы Цельсия, и другой, преобразующий температуру из градусов Цельсия в градусы Фаренгейта:

Пример ConverterFrame

  • Сначала определите класс TemperatureConverter, который имеет два статических метода: fahrenheit_to_celsius и celsius_to_fahrenheit.
class TemperatureConverter:
    @staticmethod
    def fahrenheit_to_celsius(f, format=True):
        result =(f - 32) * 5/9
        if format:
            return f'{f} Fahrenheit = {result:.2f} Celsius'
        return result

    @staticmethod
    def celsius_to_fahrenheit(c, format=True):
        result = c * 9/5 + 32
        if format:
            return f'{c} Celsius = {result:.2f} Fahrenheit'
        return result

Методы fahrenheit_to_celsius и celsius_to_fahrenheit возвращают отформатированную строку, если вы игнорируете второй аргумент или передаете им True. В противном случае они вернут результат в виде числа.

  • Во-вторых, определите ConverterFrame, который будет отображать пользовательский интерфейс для преобразования температуры из градусов Фаренгейта в градусы Цельсия и наоборот.

Для этого вам необходимо сделать ConverterFrame более гибким, добавив следующие параметры в метод __init__():

  • Строка, которая будет отображаться в градусах Фаренгейта и Цельсия.
  • Функция обратного вызова для преобразования температуры.

Ниже показан полный класс ConverterFrame:

class ConverterFrame(ttk.Frame):
    def __init__(self, container, unit_from, converter):
        super().__init__(container)

        self.unit_from = unit_from
        self.converter = converter

        # field options
        options = {'padx': 5, 'pady': 0}

        # temperature label
        self.temperature_label = ttk.Label(self, text=self.unit_from)
        self.temperature_label.grid(column=0, row=0, sticky='w',  **options)

        # temperature entry
        self.temperature = tk.StringVar()
        self.temperature_entry = ttk.Entry(self, textvariable=self.temperature)
        self.temperature_entry.grid(column=1, row=0, sticky='w', **options)
        self.temperature_entry.focus()

        # button
        self.convert_button = ttk.Button(self, text='Convert')
        self.convert_button.grid(column=2, row=0, sticky='w', **options)
        self.convert_button.configure(command=self.convert)

        # result label
        self.result_label = ttk.Label(self)
        self.result_label.grid(row=1, columnspan=3, **options)

        # add padding to the frame and show it
        self.grid(column=0, row=0, padx=5, pady=5, sticky="nsew")

    def convert(self, event=None):
        """  Handle button click event
        """
        try:
            input_value = float(self.temperature.get())
            result = self.converter(input_value)
            self.result_label.config(text=result)
        except ValueError as error:
            showerror(title='Error', message=error)

    def reset(self):
        self.temperature_entry.delete(0, "end")
        self.result_label.text = ''

Как это работает.

  1. Используйте аргумент unit_from, чтобы отобразить метку температуры.
  2. Вызовите обратный вызов self.convert в методе convert(), чтобы преобразовать температуру из одних единиц измерения в другие.
  3. Определите метод reset() для очистки виджета ввода и метки результата при переключении фрейма с одного на другой.
  • В-третьих, определите класс ControlFrame, который показывает переключатели для выбора кадра для показа. Класс ControFrame наследуется от ttk.LabelFrame.
class ControlFrame(ttk.LabelFrame):
    def __init__(self, container):

        super().__init__(container)
        self['text'] = 'Options'

        # radio buttons
        self.selected_value = tk.IntVar()

        ttk.Radiobutton(
            self,
            text='F to C',
            value=0,
            variable=self.selected_value,
            command=self.change_frame).grid(column=0, row=0, padx=5, pady=5)

        ttk.Radiobutton(
            self,
            text='C to F',
            value=1,
            variable=self.selected_value,
            command=self.change_frame).grid(column=1, row=0, padx=5, pady=5)

        self.grid(column=0, row=1, padx=5, pady=5, sticky='ew')

        # initialize frames
        self.frames = {}
        self.frames[0] = ConverterFrame(
            container,
            'Fahrenheit',
            TemperatureConverter.fahrenheit_to_celsius)
        self.frames[1] = ConverterFrame(
            container,
            'Celsius',
            TemperatureConverter.celsius_to_fahrenheit)

        self.change_frame()

    def change_frame(self):
        frame = self.frames[self.selected_value.get()]
        frame.reset()
        frame.tkraise()

Как это работает.

  1. Каждый переключатель имеет значение 0 или 1.
  2. Создайте два экземпляра класса ConverterFrame, один из которых отвечает за преобразование температуры из градусов Фаренгейта в градусы Цельсия, а другой преобразует температуру из градусов Цельсия в градусы Фаренгейта. Также определите словарь для хранения этих кадров. Ключи кадров совпадают со значениями переключателей.
  3. При нажатии на переключатель вызывается метод change_frame() для выбора соответствующего фрейма из словаря на основе значения выбранной кнопки.
  4. Вызовите метод reset() фрейма, чтобы сбросить поле ввода и метку результата. А также вызовите метод tkraise(), чтобы отобразить фрейм.
  • В-четвертых, определите класс App, который является подклассом класса tk.Tk:
class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title('Temperature Converter')
        self.geometry('300x120')
        self.resizable(False, False)
  • Наконец, загрузите приложение из блока if __name__ == «__main__»:
if __name__ == "__main__":
    app = App()
    ControlFrame(app)
    app.mainloop()

Соберите все вместе.

import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import showerror


class TemperatureConverter:
    @staticmethod
    def fahrenheit_to_celsius(f, format=True):
        result =(f - 32) * 5/9
        if format:
            return f'{f} Fahrenheit = {result:.2f} Celsius'
        return result

    @staticmethod
    def celsius_to_fahrenheit(c, format=True):
        result = c * 9/5 + 32
        if format:
            return f'{c} Celsius = {result:.2f} Fahrenheit'
        return result


class ConverterFrame(ttk.Frame):
    def __init__(self, container, unit_from, converter):
        super().__init__(container)

        self.unit_from = unit_from
        self.converter = converter

        # field options
        options = {'padx': 5, 'pady': 0}

        # temperature label
        self.temperature_label = ttk.Label(self, text=self.unit_from)
        self.temperature_label.grid(column=0, row=0, sticky='w',  **options)

        # temperature entry
        self.temperature = tk.StringVar()
        self.temperature_entry = ttk.Entry(self, textvariable=self.temperature)
        self.temperature_entry.grid(column=1, row=0, sticky='w', **options)
        self.temperature_entry.focus()

        # button
        self.convert_button = ttk.Button(self, text='Convert')
        self.convert_button.grid(column=2, row=0, sticky='w', **options)
        self.convert_button.configure(command=self.convert)

        # result label
        self.result_label = ttk.Label(self)
        self.result_label.grid(row=1, columnspan=3, **options)

        # add padding to the frame and show it
        self.grid(column=0, row=0, padx=5, pady=5, sticky="nsew")

    def convert(self, event=None):
        """  Handle button click event
        """
        try:
            input_value = float(self.temperature.get())
            result = self.converter(input_value)
            self.result_label.config(text=result)
        except ValueError as error:
            showerror(title='Error', message=error)

    def reset(self):
        self.temperature_entry.delete(0, "end")
        self.result_label.text = ''


class ControlFrame(ttk.LabelFrame):
    def __init__(self, container):

        super().__init__(container)
        self['text'] = 'Options'

        # radio buttons
        self.selected_value = tk.IntVar()

        ttk.Radiobutton(
            self,
            text='F to C',
            value=0,
            variable=self.selected_value,
            command=self.change_frame).grid(column=0, row=0, padx=5, pady=5)

        ttk.Radiobutton(
            self,
            text='C to F',
            value=1,
            variable=self.selected_value,
            command=self.change_frame).grid(column=1, row=0, padx=5, pady=5)

        self.grid(column=0, row=1, padx=5, pady=5, sticky='ew')

        # initialize frames
        self.frames = {}
        self.frames[0] = ConverterFrame(
            container,
            'Fahrenheit',
            TemperatureConverter.fahrenheit_to_celsius)
        self.frames[1] = ConverterFrame(
            container,
            'Celsius',
            TemperatureConverter.celsius_to_fahrenheit)

        self.change_frame()

    def change_frame(self):
        frame = self.frames[self.selected_value.get()]
        frame.reset()
        frame.tkraise()


class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title('Temperature Converter')
        self.geometry('300x120')
        self.resizable(False, False)


if __name__ == "__main__":
    app = App()
    ControlFrame(app)
    app.mainloop()
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *