Criação de Aplicação em Python com Kivy
Framework Kivy
[editar | editar código-fonte]Kivy é uma framework open-source para desenvolvimento de aplicações com interface gráfica em Python[1]. Escrita em Python, foi lançada em 2011 e é compatível com iOS, Android, macOS, Windows, Linux, entre outros[2].
Instalando Kivy
[editar | editar código-fonte]Para instalar Kivy em sua máquina, é necessário que ela já tenha Python e pip instalados. Assim, basta executar o comando:
pip install kivy
Para mais informações, visite o guia de instalação na documentação oficial do Kivy[3].
Construindo uma Calculadora
[editar | editar código-fonte]Nesse tutorial criaremos uma calculadora para demonstrar o básico das capacidades do kivy.
main.py
- A Base da Aplicação
[editar | editar código-fonte]
Começamos o projeto por criar um arquivo main.py
que será a base para a nossa aplicação, e importando as classes Kivy necessárias:
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.app import App
O Kivy funciona com base em uma árvore de widgets (cada um podendo conter outros widgets), sendo eles objetos da ui da aplicação.
BoxLayout
que incluímos é um tipo de widget responsável por organizar seus widgets filhos como uma caixa (mais a frente veremos como personalizar essa organização).
Agora que incluímos o necessário para criar a aplicação precisamos de uma classe para ela e para o widget raiz dela (utilizaremos uma classe que herda de BoxLayout
). Também podemos colocar entre os atributos da classe do aplicativo as cores que utilizaremos na ui (em rgba) para facilitar a leitura do código Kivy.
class Calculator(BoxLayout):
pass
class CalculatorApp(App):
color_background = (97/255 , 97/255 , 104/255, 1)
color_button = (254/255, 254/255, 254/255, 1)
color_press = (49/255 , 159/255, 255/255, 1)
color_equals = (255/255, 145/255, 49/255 , 1)
color_textbox = (207/255, 212/255, 225/255, 1)
color_text = (55/255 , 52/255 , 52/255 , 1)
def build(self):
return Calculator()
A função build
que definimos server para construir a árvore da aplicação, utilizando então um widget do tipo Calculator
como raiz.
Por último em nosso código base, podemos rodar a aplicação e personalizar o tamanho da janela a ser criada.
if __name__ == '__main__':
Window.size = (400, 600)
CalculatorApp().run()
Caso executemos a aplicação agora, teremos apenas uma tela preta, já que precisamos definir a nossa aplicação em um arquivo kv
, então vamos criar calculator.kv
para fazer isso.
calculator.kv
- O Layout da Aplicação
[editar | editar código-fonte]Nesse novo arquivo, começamos por indicar a versão do Kivy que estamos trabalhando, com o seguinte header:
#:kivy 1.0.9
Podemos então descrever nosso widget Calculator
, lembrando que ele é uma classe que herda de BoxLayout
, logo, com suas propriedades conseguimos dizer que seus widgets filhos serão organizados na orientação vertical (posicionados em fila de cima para baixo). Também mudaremos o background da raiz desenhando um retângulo com a cor desejada em sua posição da seguinte forma:
<Calculator>:
orientation: 'vertical'
memory: ""
canvas.before:
Color:
rgba: app.color_background
Rectangle:
pos: self.pos
size: self.size
Definimos o atributo memory
para armazenar os valores a serem calculados posteriormente e utilizamos app.color_background
para acessar a variável de cor que definimos na classe do aplicativo.
Criaremos agora seus primeiros filhos, a área da tela (mais um BoxLayout
) onde teremos a memória e resultados da calculadora, e a área dos botões (GridLayout
de 4x4 espaços).
Para organizar melhor seus tamanhos, fazendo o display da calculadora ocupar 20% e os botões 80% do espaço vertical, podemos utilizar o atributo size_hint
e definir seu tamanho com base no de seu pai, de forma que:
size_hint[0]: 0,5
é a mesma coisa que size[0]: self.parent.size[0]*0,5
(o mesmo vale para size_hint[1]
).
<Calculator>:
...
BoxLayout:
size_hint: 1, 0.2
canvas.before:
Color:
rgba: app.color_textbox
RoundedRectangle:
pos: self.pos[0]+5, self.pos[1]+5 # centraliza o retângulo no widget
size: self.size[0]-10, self.size[1]-10
radius: [10,10,10,10]
GridLayout:
size_hint: 1, 0.8
cols: 4 # define o layout como uma rede 4x4
O RoundedRectangle
definido no canvas do BoxLayout
é outra forma que podemos desenhar, nesse caso para representar o leitor utilizaremos um retângulo arredondado que seja levemente menor que o tamanho de BoxLayout
.
Com os layouts definidos podemos então adicionar o widget de texto (Label
) em BoxLayout
para que o display possa mostrar o que estamos calculando. Daremos um id
à essa Label
para que possamos editar seu texto depois.
<Calculator>:
...
BoxLayout:
...
Label:
id: result_label
halign: 'right' # alinha o texto à direita
valign: 'center' # alinha o texto ao centro do eixo y
padding: [15,0] # distancia levemente o texto da borda
text_size: self.size
font_size: 50
text: ''
color: app.color_text
Agora podemos então definir os botões da calculadora, para isso criaremos uma classe no fim do próprio aquivo kv
, que herda de Button
, para termos a mesma configuração para todos botões sem ser necessário repetir o código.
<CalculatorButton@Button>:
# deixamos o botão invisível para desenhar no lugar dele um retângulo arredondado
background_color: (0,0,0,0)
canvas.before:
Color:
# self.state diz se o botão está pressionado ou não
rgb: app.color_button if self.state == 'normal' else app.color_press
RoundedRectangle:
pos: self.pos[0]+5, self.pos[1]+5
size: self.size[0]-10, self.size[1]-10
radius: [10,10,10,10]
color: app.color_text # cor da fonte do texto do botão
font_size: 25
Com a classe criada podemos instanciar os botões no GridLayout
:
<Calculator>:
...
GridLayout:
...
CalculatorButton:
text: '7'
CalculatorButton:
text: '8'
CalculatorButton:
text: '9'
CalculatorButton:
text: 'C'
CalculatorButton:
text: '4'
CalculatorButton:
text: '5'
CalculatorButton:
text: '6'
CalculatorButton:
text: '+'
CalculatorButton:
text: '1'
CalculatorButton:
text: '2'
CalculatorButton:
text: '3'
CalculatorButton:
text: '-'
CalculatorButton:
text: '0'
CalculatorButton:
text: '*'
CalculatorButton:
text: '/'
CalculatorButton:
text: '='
Podemos alterar a cor do botão '='
definindo um novo fundo para ele, sobrescrevendo a nossa classe CalculatorButton
:
<Calculator>:
...
GridLayout:
...
CalculatorButton:
text: '='
canvas.before:
Color:
rgb: app.color_equals if self.state == 'normal' else app.color_press
RoundedRectangle:
pos: self.pos[0]+5, self.pos[1]+5
size: self.size[0]-10, self.size[1]-10
radius: [10,10,10,10]
Nossa ui da calculadora está pronta, porém os botões ainda não fazem nada. Para corrigir isso, definiremos a função que será chamada quando cada botão é pressionado. Essa função será chamada de input
, e será criada na classe Calculator
no lugar do pass
que colocamos antes:
<CalculatorButton@Button>:
on_press: root.parent.parent.input(self.text) # self.text é o caractere do botão
...
Lembrando que o pai de cada botão é GridLayout
, e seu pai é Calculator
, que possui a função input
, definida no arquivo main.py
:
class Calculator(BoxLayout):
def input(self, value): # value é o caractere do botão que chamou a função
if value == 'C':
self.memory = '' # limpa a memória
self.ids.result_label.text = self.memory # limpa o display
elif value == '=':
try:
result = eval(self.memory) # tenta efetuar o cálculo da memória
if type(result) == int:
self.memory = str(result)
else:
self.memory = f"{result:.7}"
self.ids.result_label.text = self.memory # mostra o resultado no display
except:
self.ids.result_label.text = "Error" # mostra erro no display
self.memory = ''
else:
self.memory += value # coloca o caractere do botão na memória
self.ids.result_label.text = self.memory # mostra a memória no display
Por fim podemos executar a aplicação com o comando python main.py
e utilizar a calculadora.