Janelas com frames são uteis para organizar interfaces grandes, dividindo a janela com tk.Frame (sub-containers). Você pode criar um frame para o topo (menu), um para o meio (conteúdo) e um para o rodapé, aplicando o pack() para empilhar esses frames e o grid() dentro de cada um deles de forma isolada.
inicialmente defina:
- Que tipo de tela você está tentando construir? (Formulário, painel com botões, etc.)
- Você precisa que a tela seja responsiva (que os botões estiquem ao maximizar a janela)?
Aqui está um exemplo prático utilizando o conceito de Frames. A melhor técnica para esse caso é criar os dois frames no início e alternar a visibilidade deles usando os comandos grid() e grid_forget() (que esconde o frame sem apagá-lo da memória).
Código Prático (Alternando Telas)
Exemplo de uma janela com dois botões, um para exibir um formulário de cadastro, e outro para exibir o que foi cadastrado:
import tkinter as tk
from tkinter import messagebox
# Lista global para armazenar os dados cadastrados
dados_cadastrados = []
def mostrar_tela_cadastro():
# Esconde a tela de exibição e mostra a de cadastro
frame_exibicao.grid_forget()
frame_cadastro.grid(row=1, column=0, columnspan=2, padx=10, pady=10, sticky="nsew")
def mostrar_tela_exibicao():
# Esconde a tela de cadastro e mostra a de exibição
frame_cadastro.grid_forget()
frame_exibicao.grid(row=1, column=0, columnspan=2, padx=10, pady=10, sticky="nsew")
# Atualiza o texto da lista com o que foi cadastrado
# Primeiro limpa o texto antigo
txt_lista.config(state="normal")
txt_lista.delete("1.0", tk.END)
# Adiciona os itens atualizados
if not dados_cadastrados:
txt_lista.insert(tk.END, "Nenhum registro encontrado.")
else:
for i, item in enumerate(dados_cadastrados, 1):
txt_lista.insert(tk.END, f"{i}. Nome: {item['nome']} | E-mail: {item['email']}\n")
txt_lista.config(state="disabled") # Deixa o texto apenas como leitura
def salvar_cadastro():
nome = ent_nome.get().strip()
email = ent_email.get().strip()
if nome == "" or email == "":
messagebox.showwarning("Aviso", "Por favor, preencha todos os campos!")
return
# Salva na lista
dados_cadastrados.append({"nome": nome, "email": email})
messagebox.showinfo("Sucesso", "Cadastro realizado com sucesso!")
# Limpa os campos de entrada
ent_nome.delete(0, tk.END)
ent_email.delete(0, tk.END)
# 1. Configuração da Janela Principal
janela = tk.Tk()
janela.title("Sistema de Cadastro Simples")
janela.geometry("400x300")
# 2. Menu de Navegação (Botões Superiores)
btn_nav_cadastro = tk.Button(janela, text="Ir para Cadastro", command=mostrar_tela_cadastro)
btn_nav_cadastro.grid(row=0, column=0, padx=10, pady=10, sticky="we")
btn_nav_exibicao = tk.Button(janela, text="Ver Cadastrados", command=mostrar_tela_exibicao)
btn_nav_exibicao.grid(row=0, column=1, padx=10, pady=10, sticky="we")
# Configura as colunas do topo para dividirem o espaço igualmente
janela.grid_columnconfigure(0, weight=1)
janela.grid_columnconfigure(1, weight=1)
# ==========================================
# 3. FRAME DE CADASTRO (Design da Tela 1)
# ==========================================
frame_cadastro = tk.LabelFrame(janela, text=" Formulário de Cadastro ", padding=10)
lbl_nome = tk.Label(frame_cadastro, text="Nome:")
lbl_nome.grid(row=0, column=0, padx=5, pady=5, sticky="w")
ent_nome = tk.Entry(frame_cadastro, width=30)
ent_nome.grid(row=0, column=1, padx=5, pady=5)
lbl_email = tk.Label(frame_cadastro, text="E-mail:")
lbl_email.grid(row=1, column=0, padx=5, pady=5, sticky="w")
ent_email = tk.Entry(frame_cadastro, width=30)
ent_email.grid(row=1, column=1, padx=5, pady=5)
btn_salvar = tk.Button(frame_cadastro, text="Salvar Dados", command=salvar_cadastro, bg="#4CAF50", fg="white")
btn_salvar.grid(row=2, column=0, columnspan=2, pady=15)
# ==========================================
# 4. FRAME DE EXIBIÇÃO (Design da Tela 2)
# ==========================================
frame_exibicao = tk.LabelFrame(janela, text=" Registros Salvos ", padding=10)
# Componente de texto para listar as informações
txt_lista = tk.Text(frame_exibicao, width=40, height=8, state="disabled")
txt_lista.grid(row=0, column=0, padx=5, pady=5)
# 5. Inicialização
# Define qual tela abre por padrão ao iniciar o programa
mostrar_tela_cadastro()
janela.mainloop()Como essa estrutura funciona?
LabelFrame: É uma variação doFramecomum que já vem com uma borda e um título incorporado (como “Formulário de Cadastro”). Ajuda visualmente a separar as seções.grid_forget(): Esse é o segredo para alternar telas no Tkinter. Quando você clica em “Ver Cadastrados”, o script rodaframe_cadastro.grid_forget(), o que faz a tela de cadastro desaparecer instantaneamente para dar lugar à outra.- Manipulação do widget
Text: Na tela de exibição, usamos otxt_lista.config(state="normal")para permitir que o Python escreva os nomes cadastrados ali, e logo em seguida mudamos para"disabled"para que o usuário final não consiga apagar ou digitar por cima.