Tutorial: Criando um Quiz com Kivy (Python)
O Kivy é uma biblioteca Python voltada para o desenvolvimento de interfaces gráficas interativas, permitindo a criação de aplicações com janelas, botões, campos de texto e múltiplas telas. Diferente de programas que funcionam apenas no terminal, o Kivy possibilita construir aplicações visuais semelhantes a apps reais, como questionários, sistemas de login, jogos simples e telas de navegação.
Neste tutorial, você vai aplicar conceitos fundamentais de programação com interface gráfica, aprendendo a organizar elementos na tela, capturar dados digitados pelo usuário e controlar a navegação entre diferentes telas do aplicativo.
Passo 1 – Instalando o Kivy
Antes de criar qualquer aplicativo com Kivy, é necessário instalar a biblioteca no seu ambiente Python.
Abra o terminal (ou prompt de comando) e execute:
python --version
Se o Python estiver instalado, a versão será exibida. Caso contrário, instale o Python antes de continuar.
Com o Python instalado, execute o comando abaixo:
pip install kivy
Explicação:
pipé o gerenciador de pacotes do Python.Esse comando faz o download e instala o Kivy e suas dependências.
O processo pode levar alguns minutos, dependendo da sua conexão.
Passo 2 — Importando as bibliotecas do Kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
Explicação dos comandos:
App: é a classe principal do aplicativo Kivy.ScreenManager: gerencia as telas (permite trocar de tela).Screen: representa uma tela do aplicativo.BoxLayout: organiza os elementos na tela (em coluna ou linha).Label: mostra textos na interface.TextInput: cria um campo para digitar.Button: cria botões clicáveis.
Passo 3 — Criando as perguntas e o gabarito
P1 = "1) Qual comando usamos para mostrar algo na tela no Python?"
C1 = "print"
P2 = "2) Qual é o tipo de dado do valor 10 no Python? (int, float, str ou bool)"
C2 = "int"
P3 = "3) Qual símbolo usamos para comentário de uma linha no Python?"
C3 = "#"
P4 = "4) Qual palavra usamos para criar uma função no Python?"
C4 = "def"
P5 = "5) Qual comando usamos para condições?"
C5 = "if"
Explicação dos comandos:
P1...P5são os textos das perguntas.C1...C5são as respostas corretas (gabarito).São apenas variáveis simples, sem listas e sem dicionários.
Passo 4 — Tela 1 (Pergunta 1)
class Tela1(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = BoxLayout(orientation="vertical", padding=20, spacing=10)
layout.add_widget(Label(text="Pergunta 1 de 5", font_size="22sp"))
layout.add_widget(Label(text=P1, font_size="18sp"))
self.msg = Label(text="", font_size="16sp")
layout.add_widget(self.msg)
self.campo = TextInput(multiline=False, hint_text="Digite sua resposta...")
layout.add_widget(self.campo)
btn = Button(text="Próximo")
btn.on_press = self.proximo
layout.add_widget(btn)
self.add_widget(layout)
def proximo(self):
resp = self.campo.text.strip().lower()
if resp == "":
self.msg.text = "Digite uma resposta antes de continuar."
return
App.get_running_app().r1 = resp
self.manager.current = "tela2"
Explicação dos comandos:
BoxLayout(orientation="vertical")organiza os elementos em coluna.TextInput(multiline=False)impede quebra de linha.btn.on_press = self.proximochama a função ao clicar.resp = self.campo.text.strip().lower()trata a resposta diretamente.App.get_running_app().r1 = respguarda a resposta no app.self.manager.current = "tela2"muda para a tela 2.
Passo 5 — Tela 2 (Pergunta 2)
class Tela2(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = BoxLayout(orientation="vertical", padding=20, spacing=10)
layout.add_widget(Label(text="Pergunta 2 de 5", font_size="22sp"))
layout.add_widget(Label(text=P2, font_size="18sp"))
self.msg = Label(text="", font_size="16sp")
layout.add_widget(self.msg)
self.campo = TextInput(multiline=False, hint_text="Digite sua resposta...")
layout.add_widget(self.campo)
botoes = BoxLayout(size_hint=(1, None), height="45sp", spacing=10)
voltar = Button(text="Voltar")
voltar.on_press = self.voltar
botoes.add_widget(voltar)
proximo = Button(text="Próximo")
proximo.on_press = self.proximo
botoes.add_widget(proximo)
layout.add_widget(botoes)
self.add_widget(layout)
def voltar(self):
self.manager.current = "tela1"
def proximo(self):
resp = self.campo.text.strip().lower()
if resp == "":
self.msg.text = "Digite uma resposta antes de continuar."
return
App.get_running_app().r2 = resp
self.manager.current = "tela3"
Explicação dos comandos:
BoxLayout(orientation="vertical")organiza os elementos em coluna.TextInput(multiline=False)impede quebra de linha.btn.on_press = self.proximochama a função ao clicar.resp = self.campo.text.strip().lower()trata a resposta diretamente.self.manager.current = "tela1"volta para a anterior.App.get_running_app().r2 = respguarda a resposta 2.
Passo 6 — Tela 3 (Pergunta 3)
class Tela3(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = BoxLayout(orientation="vertical", padding=20, spacing=10)
layout.add_widget(Label(text="Pergunta 3 de 5", font_size="22sp"))
layout.add_widget(Label(text=P3, font_size="18sp"))
self.msg = Label(text="", font_size="16sp")
layout.add_widget(self.msg)
self.campo = TextInput(multiline=False, hint_text="Digite sua resposta...")
layout.add_widget(self.campo)
botoes = BoxLayout(size_hint=(1, None), height="45sp", spacing=10)
voltar = Button(text="Voltar")
voltar.on_press = self.voltar
botoes.add_widget(voltar)
proximo = Button(text="Próximo")
proximo.on_press = self.proximo
botoes.add_widget(proximo)
layout.add_widget(botoes)
self.add_widget(layout)
def voltar(self):
self.manager.current = "tela2"
def proximo(self):
resp = self.campo.text.strip().lower()
if resp == "":
self.msg.text = "Digite uma resposta antes de continuar."
return
App.get_running_app().r3 = resp
self.manager.current = "tela4"
Explicação dos comandos:
BoxLayout(orientation="vertical")organiza os elementos em coluna.TextInput(multiline=False)impede quebra de linha.btn.on_press = self.proximochama a função ao clicar.resp = self.campo.text.strip().lower()trata a resposta diretamente.self.manager.current = "tela2"volta para a anterior.App.get_running_app().r2 = respguarda a resposta 2.
Passo 7 — Tela 4 (Pergunta 4)
class Tela4(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = BoxLayout(orientation="vertical", padding=20, spacing=10)
layout.add_widget(Label(text="Pergunta 4 de 5", font_size="22sp"))
layout.add_widget(Label(text=P4, font_size="18sp"))
self.msg = Label(text="", font_size="16sp")
layout.add_widget(self.msg)
self.campo = TextInput(multiline=False, hint_text="Digite sua resposta...")
layout.add_widget(self.campo)
botoes = BoxLayout(size_hint=(1, None), height="45sp", spacing=10)
voltar = Button(text="Voltar")
voltar.on_press = self.voltar
botoes.add_widget(voltar)
proximo = Button(text="Próximo")
proximo.on_press = self.proximo
botoes.add_widget(proximo)
layout.add_widget(botoes)
self.add_widget(layout)
def voltar(self):
self.manager.current = "tela3"
def proximo(self):
resp = self.campo.text.strip().lower()
if resp == "":
self.msg.text = "Digite uma resposta antes de continuar."
return
App.get_running_app().r4 = resp
self.manager.current = "tela5"
Explicação dos comandos:
BoxLayout(orientation="vertical")organiza os elementos em coluna.TextInput(multiline=False)impede quebra de linha.btn.on_press = self.proximochama a função ao clicar.resp = self.campo.text.strip().lower()trata a resposta diretamente.self.manager.current = "tela2"volta para a anterior.App.get_running_app().r2 = respguarda a resposta 2.
Passo 7 — Tela 5 (Pergunta 5)
class Tela5(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = BoxLayout(orientation="vertical", padding=20, spacing=10)
layout.add_widget(Label(text="Pergunta 5 de 5", font_size="22sp"))
layout.add_widget(Label(text=P5, font_size="18sp"))
self.msg = Label(text="", font_size="16sp")
layout.add_widget(self.msg)
self.campo = TextInput(multiline=False, hint_text="Digite sua resposta...")
layout.add_widget(self.campo)
botoes = BoxLayout(size_hint=(1, None), height="45sp", spacing=10)
voltar = Button(text="Voltar")
voltar.on_press = self.voltar
botoes.add_widget(voltar)
finalizar = Button(text="Finalizar")
finalizar.on_press = self.finalizar
botoes.add_widget(finalizar)
layout.add_widget(botoes)
self.add_widget(layout)
def voltar(self):
self.manager.current = "tela4"
def finalizar(self):
resp = self.campo.text.strip().lower()
if resp == "":
self.msg.text = "Digite uma resposta antes de continuar."
return
App.get_running_app().r5 = resp
self.manager.current = "resultado"
Explicação dos comandos:
BoxLayout(orientation="vertical")organiza os elementos em coluna.TextInput(multiline=False)impede quebra de linha.btn.on_press = self.proximochama a função ao clicar.resp = self.campo.text.strip().lower()trata a resposta diretamente.self.manager.current = "resultado"leva para a tela final.App.get_running_app().r2 = respguarda a resposta 2.
Passo 8 — Tela 5 (Pergunta 5)
class Tela5(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = BoxLayout(orientation="vertical", padding=20, spacing=10)
layout.add_widget(Label(text="Pergunta 5 de 5", font_size="22sp"))
layout.add_widget(Label(text=P5, font_size="18sp"))
self.msg = Label(text="", font_size="16sp")
layout.add_widget(self.msg)
self.campo = TextInput(multiline=False, hint_text="Digite sua resposta...")
layout.add_widget(self.campo)
botoes = BoxLayout(size_hint=(1, None), height="45sp", spacing=10)
voltar = Button(text="Voltar")
voltar.on_press = self.voltar
botoes.add_widget(voltar)
finalizar = Button(text="Finalizar")
finalizar.on_press = self.finalizar
botoes.add_widget(finalizar)
layout.add_widget(botoes)
self.add_widget(layout)
def voltar(self):
self.manager.current = "tela4"
def finalizar(self):
resp = self.campo.text.strip().lower()
if resp == "":
self.msg.text = "Digite uma resposta antes de continuar."
return
App.get_running_app().r5 = resp
self.manager.current = "resultado"
Explicação dos comandos:
BoxLayout(orientation="vertical")organiza os elementos em coluna.TextInput(multiline=False)impede quebra de linha.btn.on_press = self.proximochama a função ao clicar.resp = self.campo.text.strip().lower()trata a resposta diretamente.self.manager.current = "resultado"leva para a tela final.App.get_running_app().r2 = respguarda a resposta 2.
Passo 9 — Tela Resultado
class TelaResultado(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.layout = BoxLayout(orientation="vertical", padding=20, spacing=10)
self.layout.add_widget(Label(text="Resultado Final", font_size="24sp"))
self.resumo = Label(text="", font_size="16sp")
self.layout.add_widget(self.resumo)
refazer = Button(text="Refazer")
refazer.on_press = self.refazer
self.layout.add_widget(refazer)
self.add_widget(self.layout)
def on_pre_enter(self, *args):
app = App.get_running_app()
acertos = 0
texto = ""
status1 = "❌ ERROU"
if app.r1 == C1:
status1 = "✅ ACERTOU"
acertos += 1
texto += f"{P1}\nSua resposta: {app.r1}\nGabarito: {C1}\n{status1}\n\n"
status2 = "❌ ERROU"
if app.r2 == C2:
status2 = "✅ ACERTOU"
acertos += 1
texto += f"{P2}\nSua resposta: {app.r2}\nGabarito: {C2}\n{status2}\n\n"
status3 = "❌ ERROU"
if app.r3 == C3:
status3 = "✅ ACERTOU"
acertos += 1
texto += f"{P3}\nSua resposta: {app.r3}\nGabarito: {C3}\n{status3}\n\n"
status4 = "❌ ERROU"
if app.r4 == C4:
status4 = "✅ ACERTOU"
acertos += 1
texto += f"{P4}\nSua resposta: {app.r4}\nGabarito: {C4}\n{status4}\n\n"
status5 = "❌ ERROU"
if app.r5 == C5:
status5 = "✅ ACERTOU"
acertos += 1
texto += f"{P5}\nSua resposta: {app.r5}\nGabarito: {C5}\n{status5}\n\n"
self.resumo.text = f"Você acertou {acertos} de 5.\n\n" + texto
Explicação dos comandos:
on_pre_enter: executa automaticamente quando a tela vai aparecer.app = App.get_running_app(): pega o app e acessar1,r2…if app.r1 == C1: compara diretamente com o gabarito (simples).self.resumo.text = ...: mostra o texto final na tela.
Passo 10 — Botão Refazer
def refazer(self):
app = App.get_running_app()
app.r1 = ""
app.r2 = ""
app.r3 = ""
app.r4 = ""
app.r5 = ""
self.manager.get_screen("tela1").campo.text = ""
self.manager.get_screen("tela2").campo.text = ""
self.manager.get_screen("tela3").campo.text = ""
self.manager.get_screen("tela4").campo.text = ""
self.manager.get_screen("tela5").campo.text = ""
self.manager.current = "tela1"
Explicação dos comandos:
limpa respostas guardadas no app
limpa os campos de texto de cada tela usando:
get_screen("telaX")para pegar a tela.campo.text = ""para apagar
volta para a primeira tela.
Passo 11 — Criando o App principal e conectando as telas
class QuizKivy(App):
def build(self):
self.r1 = ""
self.r2 = ""
self.r3 = ""
self.r4 = ""
self.r5 = ""
sm = ScreenManager()
sm.add_widget(Tela1(name="tela1"))
sm.add_widget(Tela2(name="tela2"))
sm.add_widget(Tela3(name="tela3"))
sm.add_widget(Tela4(name="tela4"))
sm.add_widget(Tela5(name="tela5"))
sm.add_widget(TelaResultado(name="resultado"))
return sm
if __name__ == "__main__":
QuizKivy().run()
Explicação dos comandos:
self.r1...self.r5: cria variáveis simples para guardar as respostas.ScreenManager: controla as telas.add_widget(...): adiciona as telas ao gerenciador.name="tela1": define o nome usado na troca de telas.return sm: define a interface principal.Executa o app apenas quando esse arquivo for rodado diretamente.
.run()inicia o aplicativo e abre a janela.
Resultado Final
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
# ---------------------------
# PERGUNTAS + RESPOSTAS CERTAS (SEM DICIONÁRIO)
# ---------------------------
P1 = "1) Qual comando usamos para mostrar algo na tela no Python?"
C1 = "print"
P2 = "2) Qual é o tipo de dado do valor 10 no Python? (int, float, str ou bool)"
C2 = "int"
P3 = "3) Qual símbolo usamos para comentário de uma linha no Python?"
C3 = "#"
P4 = "4) Qual palavra usamos para criar uma função no Python?"
C4 = "def"
P5 = "5) Qual comando usamos para condições?"
C5 = "if"
# ---------------------------
# TELA 1
# ---------------------------
class Tela1(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = BoxLayout(orientation="vertical", padding=20, spacing=10)
layout.add_widget(Label(text="Pergunta 1 de 5", font_size="22sp"))
layout.add_widget(Label(text=P1, font_size="18sp"))
self.msg = Label(text="", font_size="16sp")
layout.add_widget(self.msg)
self.campo = TextInput(multiline=False, hint_text="Digite sua resposta...")
layout.add_widget(self.campo)
btn = Button(text="Próximo")
btn.on_press = self.proximo
layout.add_widget(btn)
self.add_widget(layout)
def proximo(self):
resp = self.campo.text.strip().lower()
if resp == "":
self.msg.text = "Digite uma resposta antes de continuar."
return
App.get_running_app().r1 = resp
self.manager.current = "tela2"
# ---------------------------
# TELA 2
# ---------------------------
class Tela2(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = BoxLayout(orientation="vertical", padding=20, spacing=10)
layout.add_widget(Label(text="Pergunta 2 de 5", font_size="22sp"))
layout.add_widget(Label(text=P2, font_size="18sp"))
self.msg = Label(text="", font_size="16sp")
layout.add_widget(self.msg)
self.campo = TextInput(multiline=False, hint_text="Digite sua resposta...")
layout.add_widget(self.campo)
botoes = BoxLayout(size_hint=(1, None), height="45sp", spacing=10)
voltar = Button(text="Voltar")
voltar.on_press = self.voltar
botoes.add_widget(voltar)
proximo = Button(text="Próximo")
proximo.on_press = self.proximo
botoes.add_widget(proximo)
layout.add_widget(botoes)
self.add_widget(layout)
def voltar(self):
self.manager.current = "tela1"
def proximo(self):
resp = self.campo.text.strip().lower()
if resp == "":
self.msg.text = "Digite uma resposta antes de continuar."
return
App.get_running_app().r2 = resp
self.manager.current = "tela3"
# ---------------------------
# TELA 3
# ---------------------------
class Tela3(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = BoxLayout(orientation="vertical", padding=20, spacing=10)
layout.add_widget(Label(text="Pergunta 3 de 5", font_size="22sp"))
layout.add_widget(Label(text=P3, font_size="18sp"))
self.msg = Label(text="", font_size="16sp")
layout.add_widget(self.msg)
self.campo = TextInput(multiline=False, hint_text="Digite sua resposta...")
layout.add_widget(self.campo)
botoes = BoxLayout(size_hint=(1, None), height="45sp", spacing=10)
voltar = Button(text="Voltar")
voltar.on_press = self.voltar
botoes.add_widget(voltar)
proximo = Button(text="Próximo")
proximo.on_press = self.proximo
botoes.add_widget(proximo)
layout.add_widget(botoes)
self.add_widget(layout)
def voltar(self):
self.manager.current = "tela2"
def proximo(self):
resp = self.campo.text.strip().lower()
if resp == "":
self.msg.text = "Digite uma resposta antes de continuar."
return
App.get_running_app().r3 = resp
self.manager.current = "tela4"
# ---------------------------
# TELA 4
# ---------------------------
class Tela4(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = BoxLayout(orientation="vertical", padding=20, spacing=10)
layout.add_widget(Label(text="Pergunta 4 de 5", font_size="22sp"))
layout.add_widget(Label(text=P4, font_size="18sp"))
self.msg = Label(text="", font_size="16sp")
layout.add_widget(self.msg)
self.campo = TextInput(multiline=False, hint_text="Digite sua resposta...")
layout.add_widget(self.campo)
botoes = BoxLayout(size_hint=(1, None), height="45sp", spacing=10)
voltar = Button(text="Voltar")
voltar.on_press = self.voltar
botoes.add_widget(voltar)
proximo = Button(text="Próximo")
proximo.on_press = self.proximo
botoes.add_widget(proximo)
layout.add_widget(botoes)
self.add_widget(layout)
def voltar(self):
self.manager.current = "tela3"
def proximo(self):
resp = self.campo.text.strip().lower()
if resp == "":
self.msg.text = "Digite uma resposta antes de continuar."
return
App.get_running_app().r4 = resp
self.manager.current = "tela5"
# ---------------------------
# TELA 5
# ---------------------------
class Tela5(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = BoxLayout(orientation="vertical", padding=20, spacing=10)
layout.add_widget(Label(text="Pergunta 5 de 5", font_size="22sp"))
layout.add_widget(Label(text=P5, font_size="18sp"))
self.msg = Label(text="", font_size="16sp")
layout.add_widget(self.msg)
self.campo = TextInput(multiline=False, hint_text="Digite sua resposta...")
layout.add_widget(self.campo)
botoes = BoxLayout(size_hint=(1, None), height="45sp", spacing=10)
voltar = Button(text="Voltar")
voltar.on_press = self.voltar
botoes.add_widget(voltar)
finalizar = Button(text="Finalizar")
finalizar.on_press = self.finalizar
botoes.add_widget(finalizar)
layout.add_widget(botoes)
self.add_widget(layout)
def voltar(self):
self.manager.current = "tela4"
def finalizar(self):
resp = self.campo.text.strip().lower()
if resp == "":
self.msg.text = "Digite uma resposta antes de continuar."
return
App.get_running_app().r5 = resp
self.manager.current = "resultado"
# ---------------------------
# TELA RESULTADO (SEM DICIONÁRIO)
# ---------------------------
class TelaResultado(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.layout = BoxLayout(orientation="vertical", padding=20, spacing=10)
self.layout.add_widget(Label(text="Resultado Final", font_size="24sp"))
self.resumo = Label(text="", font_size="16sp")
self.layout.add_widget(self.resumo)
refazer = Button(text="Refazer")
refazer.on_press = self.refazer
self.layout.add_widget(refazer)
self.add_widget(self.layout)
def on_pre_enter(self, *args):
app = App.get_running_app()
acertos = 0
texto = ""
status1 = "❌ ERROU"
if app.r1 == C1:
status1 = "✅ ACERTOU"
acertos += 1
texto += f"{P1}\nSua resposta: {app.r1}\nGabarito: {C1}\n{status1}\n\n"
status2 = "❌ ERROU"
if app.r2 == C2:
status2 = "✅ ACERTOU"
acertos += 1
texto += f"{P2}\nSua resposta: {app.r2}\nGabarito: {C2}\n{status2}\n\n"
status3 = "❌ ERROU"
if app.r3 == C3:
status3 = "✅ ACERTOU"
acertos += 1
texto += f"{P3}\nSua resposta: {app.r3}\nGabarito: {C3}\n{status3}\n\n"
status4 = "❌ ERROU"
if app.r4 == C4:
status4 = "✅ ACERTOU"
acertos += 1
texto += f"{P4}\nSua resposta: {app.r4}\nGabarito: {C4}\n{status4}\n\n"
status5 = "❌ ERROU"
if app.r5 == C5:
status5 = "✅ ACERTOU"
acertos += 1
texto += f"{P5}\nSua resposta: {app.r5}\nGabarito: {C5}\n{status5}\n\n"
self.resumo.text = f"Você acertou {acertos} de 5.\n\n" + texto
def refazer(self):
app = App.get_running_app()
app.r1 = ""
app.r2 = ""
app.r3 = ""
app.r4 = ""
app.r5 = ""
self.manager.get_screen("tela1").campo.text = ""
self.manager.get_screen("tela2").campo.text = ""
self.manager.get_screen("tela3").campo.text = ""
self.manager.get_screen("tela4").campo.text = ""
self.manager.get_screen("tela5").campo.text = ""
self.manager.current = "tela1"
# ---------------------------
# APP PRINCIPAL
# ---------------------------
class QuizKivy(App):
def build(self):
self.r1 = ""
self.r2 = ""
self.r3 = ""
self.r4 = ""
self.r5 = ""
sm = ScreenManager()
sm.add_widget(Tela1(name="tela1"))
sm.add_widget(Tela2(name="tela2"))
sm.add_widget(Tela3(name="tela3"))
sm.add_widget(Tela4(name="tela4"))
sm.add_widget(Tela5(name="tela5"))
sm.add_widget(TelaResultado(name="resultado"))
return sm
if __name__ == "__main__":
QuizKivy().run()
Caso o Python ainda não esteja instalado em seu dispositivo, clique no botão abaixo para realizar a instalação.







