Метод Tkinter Frame tkraise() в Python с примерами
Метод Frame tkraise() в Python используется для переключения между фреймами в приложении Tkinter.
Что такое метод Frame tkraise()?
Обычно приложение Tkinter состоит из нескольких фреймов. И часто приходится переключаться между фреймами, чтобы отобразить тот, который соответствует выбору пользователя.
Tkinter позволяет вам накладывать кадры друг на друга. Чтобы показать определенный кадр, вы можете просто поднять один над другим в порядке наложения. Верхний кадр будет виден.
Чтобы переместить рамку наверх, используйте метод tkraise() виджета Frame следующим образом:
frame.tkraise()
Пример метода Frame tkraise()
В этом примере вы расширите приложение преобразователя температуры, добавив преобразование температуры из градусов Цельсия в градусы Фаренгейта:
По умолчанию приложение преобразует температуру из градусов Фаренгейта в градусы Цельсия.
Если вы выберете переключатель «C в F», приложение отобразит новый фрейм, позволяющий преобразовать температуру из градусов Цельсия в градусы Фаренгейта:
Для создания этого приложения вам понадобятся три основных виджета:
- Корневое окно.
- ConverterFrame, отображающий поля формы.
- И ControlFrame, который показывает переключатели.
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 = ''
Как это работает.
- Используйте аргумент unit_from, чтобы отобразить метку температуры.
- Вызовите обратный вызов self.convert в методе convert(), чтобы преобразовать температуру из одних единиц измерения в другие.
- Определите метод 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()
Как это работает.
- Каждый переключатель имеет значение 0 или 1.
- Создайте два экземпляра класса ConverterFrame, один из которых отвечает за преобразование температуры из градусов Фаренгейта в градусы Цельсия, а другой преобразует температуру из градусов Цельсия в градусы Фаренгейта. Также определите словарь для хранения этих кадров. Ключи кадров совпадают со значениями переключателей.
- При нажатии на переключатель вызывается метод change_frame() для выбора соответствующего фрейма из словаря на основе значения выбранной кнопки.
- Вызовите метод 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()