Alternando entre quadros usando o método Frame tkraise()

Resumo : neste tutorial, você aprenderá como usar o tkraise()método Frame para alternar entre frames em uma aplicação Tkinter.

Introdução ao método Frame tkraise()

Normalmente, um aplicativo Tkinter consiste em vários frames . E muitas vezes você precisa alternar entre quadros para exibir aquele que é relevante para a escolha do usuário.

O Tkinter permite empilhar quadros uns sobre os outros. Para mostrar um quadro específico, você pode simplesmente elevar um acima do outro na ordem de empilhamento. O quadro superior ficará visível.

Para trazer um quadro para o topo, você usa o tkraise()método do widget Quadro como este:

frame.tkraise()Linguagem de código:  Python  ( python )

O exemplo do método Frame tkraise()

Neste exemplo, você estenderá o aplicativo do conversor de temperatura adicionando a conversão de uma temperatura de Celsius para Fahrenheit:

Por padrão, o aplicativo converte a temperatura de Fahrenheit para Celsius.

Se você selecionar o botão de opção C para F , o aplicativo mostrará um novo quadro que permite converter uma temperatura de Celsius para Fahrenheit:

Para construir este aplicativo, você precisará de três widgets principais:

  • Uma janela raiz.
  • O ConverterFrameque mostra os campos do formulário.
  • E ControlFrameisso mostra os botões de opção.

O ConverterFrameterá duas instâncias, uma que converte uma temperatura de Fahrenheit para Celsius e outra que converte uma temperatura de Celsius para Fahrenheit:

Primeiro, defina uma TemperatureConverterclasse que possua dois métodos estáticos: fahrenheit_to_celsiuse 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
Linguagem de código:  Python  ( python )

Os métodos fahrenheit_to_celsiuse celsius_to_fahrenheitretornam uma string formatada se você ignorar o segundo argumento ou passar Truepara eles. Caso contrário, eles retornarão o resultado como um número.

Segundo, defina o ConverterFrameque mostrará a IU para converter a temperatura de Fahrenheit para Celsius e vice-versa.

Para fazer isso, você precisará torná-lo ConverterFramemais flexível adicionando os seguintes parâmetros ao __init__()método:

  • Uma string que será exibida como Fahrenheit e Celsius
  • Uma função de retorno de chamada para converter a temperatura.

O seguinte mostra uma ConverterFrameclasse completa:

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 = ''Linguagem de código:  Python  ( python )

Como funciona.

  • Use o unit_fromargumento para mostrar o rótulo da temperatura.
  • Chame o self.convertretorno de chamada no convert()método para converter uma temperatura de uma unidade para outra.
  • Defina o reset()método para limpar o widget de entrada e o rótulo do resultado quando o quadro for alternado de um para outro.

Terceiro, defina uma ControlFrameclasse que mostre os botões de opção para selecionar um quadro a ser exibido. A ControFrameclasse herda do 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()Linguagem de código:  Python  ( python )

Como funciona.

  • Cada botão de opção contém um valor 0 ou 1.
  • Crie duas instâncias da ConverterFrameclasse, uma é responsável por converter a temperatura de Fahrenheit para Celsius e a outra converte a temperatura de Celsius para Fahrenheit. Além disso, defina um dicionário para armazenar esses quadros. As chaves dos frames são iguais aos valores dos botões de opção.
  • Quando um botão de opção é clicado, o change_frame()método é chamado para selecionar o quadro correspondente do dicionário com base no valor do botão selecionado.
  • Chame o reset()método do quadro para redefinir o campo de entrada e o rótulo do resultado. E também invoque o tkraise()método para exibir o quadro.

Quarto, defina a Appclasse que é subclasse da tk.Tkclasse:

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

        self.title('Temperature Converter')
        self.geometry('300x120')
        self.resizable(False, False)
Linguagem de código:  Python  ( python )

Por fim, inicialize o aplicativo a partir do if __name__ == "__main__"bloco:

if __name__ == "__main__":
    app = App()
    ControlFrame(app)
    app.mainloop()Linguagem de código:  Python  ( python )

Junte tudo.

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()
Linguagem de código:  Python  ( python )

Resumo

  • Use tkraise()o método para colocar um quadro no topo de uma lista de quadros.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *