Você está na página 1de 69

Pontifícia Universidade Católica do Paraná (PUCPR)

Concepção de Soluções Baseadas em Aplicativos (CSBA)

Desenvolvimento de Aplicativos para


Dispositivos Móveis
Tutorial
Autores:
Prof. MSc. Arnaldo Carlos Muller Junior

Prof. Dr. Dani Juliano Czelusniak

Prof. Dr. Gregory Moro Puppi Wanderley

Prof. Dr. Luiz Henrique Franco Giovanini

Prof.ª MSc. Mª Angela Moscalewski Roveredo Santos

Revisão e Supervisão:

Prof. Dr. Alcides Calsavara

Curitiba - 2019

1
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Sumário
1. Visão Geral da Disciplina de CSBA .................................................................................................... 4
2. Projetando o Aplicativo ................................................................................................................... 6
2.1. Visão Geral do Aplicativo ........................................................................................................................ 6
2.2. Especificando os Requisitos Funcionais e Não Funcionais.................................................................. 7
2.3. Especificando a Arquitetura de Software ......................................................................................... 10
2.4. Especificando os Algoritmos dos Componentes de Software .......................................................... 10
2.5. Especificando a Interação Humano Computador ............................................................................. 12
3. Implementando o Aplicativo .......................................................................................................... 14
3.1. Criando uma pasta para a implementação do Aplicativo ................................................................. 14
3.2. Passo 1 da implementação do aplicativo .......................................................................................... 14
3.3. Analisando o código .......................................................................................................................... 15
3.4. Passo 2 da implementação do aplicativo .......................................................................................... 16
3.5. Analisando o código .......................................................................................................................... 17
3.6. Passo 3 da implementação do aplicativo .......................................................................................... 19
3.7. Analisando o código do arquivo main.py .......................................................................................... 20
3.8. Analisando o código do arquivo lancador.kv .................................................................................... 21
3.9. Passo 4 da implementação do aplicativo .......................................................................................... 22
3.10. Analisando o código do arquivo main.py .......................................................................................... 23
3.11. Analisando o código do arquivo lancador.kv .................................................................................... 24
3.12. Passo 5 da implementação do aplicativo – Formalismo no código .................................................. 25
3.13. Analisando o código do arquivo main.py quanto ao formalismo ..................................................... 26
3.14. Analisando o código do arquivo lancador.kv – seguindo formalismo .............................................. 29
3.15. Passo 6 da implementação do aplicativo - Conclusão ...................................................................... 31
APÊNDICE A – Referente ao Projeto ...................................................................................................... 40
Desenhando Diagramas com o Draw.io ....................................................................................................... 40
APÊNDICE B – Referente à Implementação ........................................................................................... 47
Instalando o Ambiente de Desenvolvimento Kivy ....................................................................................... 47
APÊNDICE C – Referente aos Layouts do Kivy ........................................................................................ 50
O que é um Layout ....................................................................................................................................... 50
Layouts disponíveis no Kivy .......................................................................................................................... 50
APÊNDICE D – Referente ao Canvas – desenhando formas 2D básicas em Kivy ...................................... 56
O que é Canvas ............................................................................................................................................. 56
2
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

APÊNDICE E – Referente às especificações de tamanhos dos Widgets em Kivy ....................................... 59


Configuração das dimensões dos Widgets .................................................................................................. 59
APÊNDICE F – Referente ao widget TextInput em Kivy ........................................................................... 61
O que é TextInput ......................................................................................................................................... 61
APÊNDICE G – Referente a Classes e Métodos no Python ...................................................................... 63
O que é Programação Orientada a Objetos (POO) ...................................................................................... 63

3
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

1. Visão Geral da Disciplina de CSBA


Por: Prof. Dr. Luiz Giovanini

O mapa mental abaixo apresenta uma visão geral da disciplina de CSBA.

CONCEPÇÃO DE SOLUÇÕES BASEADAS EM APLICATIVOS

PROBLEMAS DE ENGENHARIA CSBA APLICATIVOS (SOLUÇÕES)

orienta

RA1 RA2
PROJETO IMPLEMENTAÇÃO

revisa

recebe Python produz


M odelos Android
Algoritmos iOS
Casos Segurança
Heurísticas Usabilidade
I deias Desempenho
Confiabilidade

RA3. ANÁLISE DE PUBLICAÇÃO TÉCNICO-CIENTÍFICA

Figura 1: Mapa mental de CSBA.

A Figura 2 detalha as três principais etapas envolvidas no desenvolvimento de aplicativos em CSBA: análise
de publicação técnico-científica, projeto e implementação, fazendo uma relação com os indicadores de de-
sempenho da disciplina.

Figura 2: Principais etapas envolvidas no desenvolvimento de aplicativos móveis.


4
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Situação Problema

Nesse tutorial, criaremos um aplicativo que simula o lançamento de uma bola de basquete até a cesta. Para
ver seu funcionamento na íntegra, acesse o link: https://youtu.be/Hb-P18bErIg

O lançamento da bola de basquete até a cesta pode ser representado matematicamente como um movi-
mento oblíquo, onde a bola se desloca para a frente até uma altura máxima e depois começa a descer,
formando uma trajetória parabólica (Figura 3).

Figura 3: Ilustração da trajetória de um objeto em movimento oblíquo.

Como pode ser visto na Figura 3, a bola é lançada a um ângulo 𝜃 com uma velocidade inicial 𝑣0 , estando sob
a ação da força da gravidade 𝑔. As componentes horizontal e vertical da trajetória podem ser calculadas em
função do tempo por meio das seguintes equações, respectivamente:
𝑥(𝑡) = 𝑥0 + |𝑣0 |. cos(𝜃) . 𝑡
𝑔𝑡²
𝑦(𝑡) = 𝑦0 + |𝑣0 |. sen(𝜃) . 𝑡 −
2
Fazendo uma simulação com 𝑥0 = 𝑦0 = 0 𝑚, 𝑔 = 9,8 𝑚/𝑠 2 , 𝜃 = 45°, 𝑡 começando em zero e variando em
incrementos de 0,1 s, e variando a velocidade inicial 𝑣0 , temos as seguintes trajetórias:

Vo = 3 m/s Vo = 5 m/s Vo = 7 m/s


1,4 1,4 1,4
1,2 1,2 1,2
1,0 1,0 1,0
0,8 0,8 0,8
y (m)

y (m)
y (m)

0,6 0,6 0,6


0,4 0,4 0,4
0,2 0,2 0,2
0,0 0,0 0,0
0,0 2,0 4,0 0,0 2,0 4,0 0,0 2,0 4,0
x (m) x (m) x (m)

Figura 4: Simulação do movimento oblíquo para diferentes valores de velocidade inicial. Quando y=0, entende-se que o objeto
atingiu o solo, portanto, não estão sendo mostrados os valores negativos de y.

5
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

2. Projetando o Aplicativo
Por: Prof. Dr. Luiz Giovanini
Prof.ª MSc. Mª Angela M Roveredo Santos

Essa seção do tutorial abordará a etapa de projeto do aplicativo. Nessa etapa, deve-se produzir um docu-
mento com as especificações do aplicativo, que será utilizado para nortear sua implementação. Este docu-
mento deve conter:

➢ A visão geral da concepção do aplicativo, representada graficamente por meio de fluxograma.


➢ Os requisitos funcionais e não funcionais do aplicativo, descritos em texto e também representados
graficamente por meio de diagrama de caso de uso, com a especificação dos respectivos casos.
➢ A arquitetura de software do aplicativo, representada por meio de diagrama de classes, onde são
apresentadas as classes, atributos, métodos e as relações entre os objetos existentes.
➢ Os algoritmos dos componentes de software do aplicativo, ou seja, o detalhamento dos algoritmos
envolvidos na arquitetura de software, descritos por meio de fluxogramas e diagramas de estado.
➢ A Interação Humano Computador do aplicativo, contendo o esboço das telas com suas respectivas
componentes visuais e sonoras de interação com o usuário.

2.1. Visão Geral do Aplicativo


Por: Prof. Dr. Luiz Giovanini

Nesta fase inicial, deve-se pensar na concepção do aplicativo de uma forma mais geral, visando uma análise
alto nível do problema. Isso será feito por meio de um fluxograma (Figura 5), que pode ser desenhado no
computador com o auxílio de ferramenta apropriada (e.g., Draw.io).

Figura 5: Fluxograma do aplicativo referente à situação problema deste tutorial.

6
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

2.2. Especificando os Requisitos Funcionais e Não Funcionais


Por: Prof. Dr. Luiz Giovanini

🎯 Obs.: este item refere-se aos dois primeiros indicadores de desempenho da disciplina de CSBA.

Requisitos são as funcionalidades/capacidades que o aplicativo deve possuir para resolver um problema ou
atingir um objetivo. Em outras palavras, eles descrevem aquilo que o aplicativo deve ser capaz de fazer, os
serviços que deve oferecer e as restrições de funcionamento. Um requisito pode ser classificado como fun-
cional ou não funcional.

➢ Requisitos funcionais: definem as funcionalidades e o comportamento do aplicativo para resolver o


problema ou atingir o objetivo (o que deve fazer, como reagir a determinadas entradas e situações,
etc.). Alguns exemplos gerais são:
o “Permitir que o usuário insira o peso e a altura do paciente”.
o “Verificar o índice de massa corporal para classificar o peso do paciente”.
o “Validar campo de e-mail”.

➢ Requisitos não funcionais: também conhecidos como requisitos de qualidade, referem-se a padrões
de qualidade que o aplicativo deve oferecer, tais como desempenho, confiabilidade, segurança, ro-
bustez, portabilidade, usabilidade, entre outros. Alguns exemplos gerais são:
o “Somente usuários autorizados deverão ter acesso aos dados cadastrais dos clientes”.
o “O tempo de resposta não deverá ultrapassar cinco segundos”.
o “Os arquivos gerados não podem ultrapassar 10 MB”.
o “O aplicativo deverá rodar em qualquer plataforma”.

Para a situação problema deste tutorial (lançamento da bola de basquete), tem-se os seguintes requisitos:

➢ Requisitos funcionais:
o RF01: permitir que o usuário insira os dados de entrada (ângulo de lançamento e velocidade
de lançamento da bola).
o RF02: validar os dados de entrada fornecidos pelo usuário.
o RF03: calcular e reproduzir graficamente a trajetória da bola.
o RF04: verificar se a bola acertou a cesta, emitindo mensagem de sucesso em caso positivo, ou
mensagem de insucesso em caso negativo.
o RF05: ao final de cada lançamento, permitir que o usuário possa escolher entre fazer um novo
lançamento ou encerrar o aplicativo.

➢ Requisitos não funcionais:


o RNF01: o aplicativo deverá executar em plataforma Android.

O diagrama de casos de uso é uma maneira gráfica de se representar o funcionamento do aplicativo, onde
descreve-se suas principais funcionalidades e a interação das mesmas com o usuário (Figura 6). Esse dia-
grama pode ser construído no computador com o auxílio de ferramenta apropriada (e.g., Draw.io).
7
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Figura 6: Diagrama de casos de uso para a situação problema do tutorial.

Sobre o diagrama mostrado na Figura 6:

➢ Cada elipse representa um caso de uso, que está vinculado a um ou mais requisitos do aplicativo.
➢ O jogador se relaciona apenas com os casos “Fornecer entradas”, Lançar bola” e “Encerrar”, nos quais
ele atua diretamente. Os outros casos não envolvem a participação do jogador, ou seja, são realiza-
dos inteiramente pelo sistema.
➢ O caso “Lançar bola” inclui o caso “Verificar bola na cesta”. Ou seja, quando o primeiro for realizado,
o segundo sempre será realizado também. Isso porque o objetivo do aplicativo é que, ao lançar a
bola, verifique-se se ela atingiu ou não a cesta.
➢ O caso “Verificar bola na cesta” estende os casos “Mostrar sucesso” e “Mostrar insucesso”. Ou seja,
quando o primeiro for executado, dependendo do resultado, os outros dois podem ou não ser exe-
cutados. Por exemplo, “Mostrar sucesso” só deve ser executado se o usuário acertar a cesta, e “Mos-
trar insucesso” se o usuário errar a cesta.

Cada um dos casos de uso da Figura 6 devem ainda ser detalhados, conforme apresentado abaixo:

Identificação: UC01
Nome: Fornecer entradas
Requisitos envolvidos: RF01, RF02
Sequência típica de eventos:

Usuário: Sistema:
• Informa o ângulo 𝜃 de lançamento da bola. • Verifica se o ângulo 𝜃 informado é maior que 0° e
• Informa a velocidade inicial 𝑣0 de lança- menor que 90°. Enquanto essa condição não for sa-
mento da bola. tisfeita, apresenta erro de leitura desta entrada.
• Verifica se a velocidade 𝑣0 informada é maior do
que zero. Enquanto essa condição não for satis-
feita, apresenta erro na leitura desta entrada.

Identificação: UC02
Nome: Lançar bola
Requisitos envolvidos: RF03
Sequência típica de eventos:

8
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Usuário: Sistema:
• Informa que deseja realizar o lançamento da • Calcula e mostra graficamente a trajetória da bola
bola (ex.: pressiona botão de “lançar"). por meio das equações:
𝑥(𝑡) = 𝑥0 + |𝑣0 |. cos(𝜃) . 𝑡
𝑔𝑡²
𝑦(𝑡) = 𝑦0 + |𝑣0 |. sen(𝜃) . 𝑡 −
2
• Define 𝑥0 e 𝑦0 em função de características gráfi-
cas da tela do aplicativo.
• Fixa 𝑔 = 9,8 𝑚/𝑠².
• Usa 𝑣0 e 𝜃 lidos do usuário e validados.
• Varia 𝑡 em incrementos de 0,1 s, até que a bola a-
tinja o solo (𝑦 = 0) ou até que acerte a cesta.
Identificação: UC03
Nome: Encerrar
Requisitos envolvidos: RF05
Sequência típica de eventos:

Usuário: Sistema:
• Informa que deseja sair do aplicativo. • Encerra o aplicativo.
Identificação: UC04
Nome: Verificar bola na cesta
Requisitos envolvidos: RF04
Sequência típica de eventos:

Usuário: Sistema:
• Nenhum. • Verifica se, em algum momento da trajetória, as
coordenadas (x,y) da bola coincidem com as co-
ordenadas (x±r,y±r) da cesta, considerando uma
margem de tolerância r. Em caso afirmativo, e-
xecuta o caso “mostrar sucesso”. Em caso nega-
tivo, executa o caso “mostrar insucesso”.
Identificação: UC05
Nome: Mostrar sucesso
Requisitos envolvidos: RF04
Sequência típica de eventos:

Usuário: Sistema:
• Nenhum. • Apresenta na tela mensagem de sucesso: “ACERTOU!”.
Identificação: UC06
Nome: Mostrar insucesso
Requisitos envolvidos: RF04
Sequência típica de eventos:
Usuário: Sistema:
• Nenhum. • Apresenta na tela mensagem de insucesso: “ERROU”.

9
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

2.3. Especificando a Arquitetura de Software


Por: Prof.ª MSc. Mª Angela M Roveredo Santos e Prof. Dr. Luiz Giovanini

🎯 Obs.: este item refere-se ao 4º indicador de desempenho da disciplina de CSBA.

O Diagrama de Classes (DC) é uma representação estática utilizada para descrever a estrutura de um sis-
tema, apresentando suas classes, atributos, métodos e as relações entre os objetos. Sua função é a de sepa-
rar os elementos de interface da codificação do sistema e é utilizada para documentar a arquitetura dos
softwares (Figura 7). Esse diagrama pode ser construído no computador com o auxílio de ferramenta apro-
priada (e.g., Draw.io).

Figura 7: Diagrama de classes para a situação problema do tutorial.

2.4. Especificando os Algoritmos dos Componentes de Software


Por: Prof.ª MSc. Mª Angela M Roveredo Santos e Prof. Dr. Luiz Giovanini

🎯 Obs.: este item refere-se ao 5º indicador de desempenho da disciplina de CSBA.

Nessa etapa, deve-se especificar os algoritmos envolvidos nos métodos das classes, representando-os por
meio de diagramas de estado (Figura 8) e fluxogramas (Figura 9). Esses diagramas podem ser construídos no
computador com o auxílio de ferramenta apropriada (e.g., Draw.io).

DIAGRAMA DE ESTADO

Um Diagrama de Estado (DE) mostra os possíveis estados de um objeto e as transições responsáveis pelas
suas mudanças de estado. O estado de um objeto depende da atividade na qual ele está sendo processado.
Na Figura 9, o objeto bola passa do estado “Pronta para lançamento” para o estado “Em movimento” devido
a transição “lançamento”. O objeto bola atinge a posição de repouso conforme transição executada. Se a
transição for “cesta atingida”, a posição de repouso da bola será “na cesta” ou se a transição for “cesta não
atingida”, a posição de repouso da bola será “no chão”.
10
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Figura 8: Diagrama de estado do objeto bola.

FLUXOGRAMAS

Os fluxogramas apresentados na Figura 9 especificam os algoritmos envolvidos nos métodos das classes
(vide Figura 7, seção 2.3). Assim:
➢ No item (a) da Figura 9, o fluxograma referente ao método lancarBola() da classe Jogador descreve
a entrada válida de valores para a velocidade inicial e o ângulo de lançamento (ambos fornecidos
pelo usuário), a chamada do método mover() da classe Bola e, com base no resultado dessa chamada,
a impressão da mensagem para o usuário.
➢ No item (b) da Figura 9, o fluxograma referente ao método mover() da classe Bola descreve o cálculo
das coordenadas x, y do movimento da bola em função do tempo e dos parâmetros informados (ve-
locidade e ângulo). A cada variação de 0,1 s no tempo, os valores de x e y são atualizados e testados
tanto em relação à posição da cesta como em relação ao chão, até obter o destino final da bola.

(a) Método lancarBola() da classe Jogador. (b) Método mover() da classe Bola.
Figura 9: Fluxogramas dos algoritmos dos métodos (a) Jogador.lancarBola() e (b) Bola.mover()

11
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

2.5. Especificando a Interação Humano Computador


Por: Prof. Dr. Luiz Giovanini

🎯 Obs.: este item refere-se ao 3º indicador de desempenho da disciplina de CSBA.

A Interação Humano Computador (IHC) trata da comunicação entre o usuário e o aplicativo, incluindo tudo
o que pode acontecer durante a sua utilização. Nessa etapa, deve-se especificar todas as telas do aplicativo,
com suas respectivas componentes visuais e sonoras (Figura 10). Os esboços iniciais geralmente são feitos
no papel, mas uma versão final pode ser desenhada no computador com o auxílio de ferramenta apropriada
(e.g., Draw.io).

Componentes visuais:

➢ Caixas de texto, para permitir a leitura de dados do usuário.


➢ Rótulos, para indicar o que se espera ler do usuário em cada caixa de texto.
➢ Botão, para permitir que o usuário realize uma ação.
➢ Imagens, para representar a bola de basquete e a cesta.

Componentes sonoras:

➢ Som de lançamento, a ser reproduzido sempre que a bola entrar em movimento.


➢ Som de sucesso, a ser reproduzido sempre que a bola acertar a cesta.
➢ Som de insucesso, a ser produzido sempre que a bola atingir o solo sem acertar a cesta.

Figura 10: Esboço da tela do aplicativo para o problema do tutorial, com a indicação das componentes visuais utilizadas.
12
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

⚠️ Atenção: é importante que a IHC do aplicativo seja bem planejada, de forma que a experiência do usuário
seja agradável. Em outras palavras, além a funcionalidade do aplicativo, deve-se prezar também pela sua
facilidade de uso. Para isso, atente-se a questões como: quantidade de elementos na tela, facilidade de vi-
sualização das informações (cores, tamanhos de fonte, etc.), facilidade de compreensão das informações
apresentadas, facilidade de interação com o aplicativo, etc.

Para compreender a importância dessa questão, observe a figura abaixo e reflita: qual desses aplicativos de
navegação GPS você se sentiria mais confortável em utilizar?

Figura 11: Aplicativos de navegação GPS gpsGuide (esquerda) e Waze (direita).

13
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

3. Implementando o Aplicativo
Por: Prof. MSc. Arnaldo C. M. Junior
Prof. Dr. Gregory M.P. Wanderley
Prof.ª MSc. Mª Angela M Roveredo Santos

Essa seção do tutorial abordará a implementação do aplicativo no ambiente de desenvolvimento em Kivy


com a linguagem de programação Python.
O framework Kivy é uma biblioteca Python que permite implementar interfaces com o usuário que utilizam
recursos modernos de hardware (por exemplo, multitoque) e que já se encontram disponíveis nos smar-
tphones e tablets. A interface opera de forma similar nos laptops e desktops convencionais com Linux, Win-
dows ou OSX.
Kivy é gratuito assim como o Python e pode ser utilizado no desenvolvimento de sistemas comerciais.

3.1. Criando uma pasta para a implementação do Aplicativo


Uma vez com o Kivy instalado (acessar o Apêndice – B deste tutorial contendo o passo-a-passo da instalação
do Python e do Kivy), é possível começar a ter uma ideia da linguagem.
Crie na sua máquina uma pasta chamada Tutorial.
Os programas a serem criados em Python (.py) e em kvlang (.kv) deverão ser salvos nesta mesma pasta.

🎯 Obs.: kvlang (ou linguagem Kivy) é uma linguagem especializada e semelhante a linguagem Python para a
construção de interfaces gráficas. O objetivo é facilitar a adição e remoção de Widgets (componentes visuais)
ao mesmo tempo que separa o código utilizado para construção gráfica (View) do código Python, ou a lógica de
negócios. O arquivo lancador.kv (criado, neste tutorial, a partir do Passo 3 do Aplicativo) está escrito em
kvlang.

3.2. Passo 1 da implementação do aplicativo

Arquivo main.py

from kivy.app import App


from kivy.uix.boxlayout import BoxLayout

class LancadorApp(App):
def build(self):
self.title = 'Lancador de Bolas de Basquete'
return BoxLayout()

meuApp = LancadorApp()

meuApp.run()
14
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Executando o programa main.py, uma janela vazia é obtida com o título ‘Lancador de Bolas de Basquete’,
conforme a IHC correspondente (Figura 10):

Figura 10: IHC referente ao aplicativo obtido no passo 1 da implementação

Abaixo, linha a linha deste programa está sendo analisada:

3.3. Analisando o código

from kivy.app import App

Importa os métodos relacionados a App (classe principal). Estes métodos (ou funções) criam uma instância
do programa. Todo programa Kivy deve importar um módulo App.

from kivy.uix.boxlayout import BoxLayout

Importa um dos tipos de layout disponível para diagramar o quadro (layout da Aplicação)
class LancadorApp(App):

É a classe da aplicação. Esta classe herda a funcionalidade da classe principal App do Kivy.
def build(self):

O método build, herdado da classe App, define quais componentes estarão no quadro (layout da Aplica-
ção), ou seja, os objetos gráficos (widgets) que compõe a aplicação.
self.title = 'Lancador de Bolas de Basquete'

Define o título do quadro (layout da Aplicação)


return BoxLayout()

Retorna um quadro (layout da Aplicação) vazio


meuApp = LancadorApp()

Cria uma instancia (meuApp) da classe LancadorApp

meuApp.run()

15
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

A aplicação é iniciada pela chamada do método run(), ou seja, abre o quadro (layout da aplicação)

3.4. Passo 2 da implementação do aplicativo

Arquivo main.py

from kivy.app import App


from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button

class LancadorApp(App):
def build(self):
self.title = 'Lancador de Bolas de Basquete'

lay = BoxLayout(orientation='vertical')

lay.add_widget(Label(text='Velocidade:'))
lay.add_widget(TextInput())

lay.add_widget(Label(text='Ângulo:'))
lay.add_widget(TextInput())

button = Button(text='Lancar!')
button.on_release = self.LancarClick
lay.add_widget(button)

return lay

def LancarClick(button):
print("Lançando!!")

meuApp = LancadorApp()

meuApp.run()

Executando o programa main.py, é obtida uma janela com o título ‘Lancador de Bolas de Basquete’ e con-
tendo dois rótulos, duas caixas de texto e um botão, conforme a IHC correspondente (Figura 11):

Figura 11: IHC referente ao aplicativo obtido no passo 2 da implementação

16
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Abaixo, linha a linha deste programa está sendo analisada:

3.5. Analisando o código

from kivy.app import App


from kivy.uix.boxlayout import BoxLayout

Importa os métodos relacionados à classe App e um dos tipos de layout disponível no Kivy
from kivy.uix.label import Label

Importa os métodos relacionados ao widget Label (disponível no Kivy)


from kivy.uix.textinput import TextInput

Importa os métodos relacionados ao widget TextInput (disponível no Kivy)


from kivy.uix.button import Button

Importa os métodos relacionados ao widget Button (disponível no Kivy)

class LancadorApp(App):

É a classe da aplicação. Esta classe herda a funcionalidade da classe principal App do Kivy.
def build(self):

O método build, herdado da classe App, define quais componentes estarão no quadro, ou seja, os objetos
gráficos (widgets) que compõe a aplicação

self.title = 'Lancador de Bolas de Basquete'

Define o título do quadro (layout da Aplicação)


lay = BoxLayout(orientation='vertical')

Cria um quadro (layout da Aplicação), ou seja, cria uma instância (lay) da classe BoxLayout. Nesse quadro
serão inseridos os widgets dispostos na vertical, ou seja, um widget embaixo do outro. Tais widgets serão
definidos na sequência

lay.add_widget(Label(text='Velocidade:'))

Acrescenta à instância lay um widget de rótulo que herda as funcionalidades da classe Label. Uma das
funcionalidades herdadas é a propriedade text que está recebendo um conteúdo (‘Velocidade:’)
lay.add_widget(TextInput())

Acrescenta à instância lay um widget de caixa de texto que herda as funcionalidades da classe TextInput.
Esse widget serve para receber a digitação do usuário
lay.add_widget(Label(text='Ângulo:'))

17
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Acrescenta à instância lay um widget de rótulo que herda as funcionalidades da classe Label. Uma das
funcionalidades herdadas é a propriedade text que está recebendo um conteúdo (‘Ângulo:’)

lay.add_widget(TextInput())

Acrescenta à instância lay um widget de caixa de texto que herda as funcionalidades da classe TextInput.
Esse widget serve para receber a digitação do usuário
button = Button(text='Lancar!')

Cria um botão, ou seja, cria uma instância (button) que herda as funcionalidades da classe Button. Uma
das funcionalidades herdadas é a propriedade text que está recebendo um conteúdo (‘Lancar!’)

button.on_release = self.LancarClick

on_release é um dos eventos herdados da classe Button pelo widget button. Quando esse evento ocorrer,
será iniciado o método LancarClick. Esse evento ocorre somente quando o usuário libera o referido botão
lay.add_widget(button)

Acrescenta à instância lay um widget de botão (instância chamada button) que herda as funcionalidades
da classe Button. Esse widget herda eventos capazes de executar ações programadas dentro da aplicação

return lay

Retorna um quadro (layout da Aplicação) que é a instância (lay) herdada da classe BoxLayout e contendo
os cinco widgets já definidos
def LancarClick(button):

Definição do método LancarClick que é disparado somente pelo evento on_release do botao (button)

print("Lançando!!")

Impressão da mensagem “Lançando!!” no Shell do Python. Essa ação é realizada somente quando ocorrer
a execução do método LancarClick
meuApp = LancadorApp()

Cria uma instância (meu App) que herda as funcionalidades da classe LancadorApp

meuApp.run()

A aplicação é iniciada pela chamada do método run(), ou seja, abre o quadro (layout da aplicação)

18
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

3.6. Passo 3 da implementação do aplicativo

🎯 Obs.: a execução do programa main.py do passo 3 repete, quase que na íntegra, o resultado obtido pelo
mesmo programa main.py do passo 2. As diferenças deste programa do passo 3 em relação à sua descrição no
passo 2 são:

1. no passo 3, quando ocorre a execução do método LancarClick, a ação realizada é a cópia do conteúdo
digitado pelo usuário da caixa de texto referente à velocidade para a caixa de texto referente ao
angulo, perdendo-se o conteúdo inicial referente ao angulo e digitado pelo usuário antes da execução
do método.
2. no passo 3, o programa main.py não importa as classes Label, TextInput e Button do Kivy, pois não
irá criar os widgets correspondentes a elas. Existe um arquivo escrito na linguagem Kivy (com exten-
são .kv) que conterá a descrição da árvore de widgets da aplicação, possibilitando a separação da
lógica da nossa aplicação (que mantem-se no programa em Python) e a interface do usuário (que
estará descrita no programa em Kivy).
Por convenção: o Kivy procura por um arquivo com o mesmo nome da sua classe principal (aquela
que estende de App) e sem o sufixo “App”. Neste aplicativo a classe principal chama-se LancadorApp,
assim o arquivo buscado será lancador.kv.

Arquivo main.py Arquivo lancador.kv

from kivy.app import App <Quadro>


from kivy.uix.boxlayout import BoxLayout orientation:'vertical'

class Quadro(BoxLayout): Label:


def LancarClick(self): text:'Velocidade:'
self.ids.txAng.text = self.ids.txVel.text TextInput:
id:txVel
class LancadorApp(App):
Label:
def build(self):
text:'Angulo:'
self.title = 'Lancador de Bolas de Basquete'
TextInput:
return Quadro() id:txAng
meuApp = LancadorApp() Button:
text:'Lancar!'
meuApp.run() on_release:root.LancarClick()

19
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Executando o programa main.py (que busca o arquivo lancador.kv) é obtida uma janela com o título ‘Lan-
cador de Bolas de Basquete’ e contendo dois rótulos, duas caixas de texto e um botão, conforme a IHC
correspondente (Figura 12):

cópia do conteúdo de
uma caixa de texto para
outra

Figura 12: IHC referente ao aplicativo obtido no passo 3 da implementação

Abaixo, linha a linha do programa main.py está sendo analisada:

3.7. Analisando o código do arquivo main.py

from kivy.app import App


from kivy.uix.boxlayout import BoxLayout

Importa os métodos relacionados à classe App e um dos tipos de layout disponível no Kivy
class Quadro(BoxLayout):

É uma classe declarada no arquivo lancador.kv


def LancarClick(self):

Definição do método LancarClick que é disparado somente pelo evento on_release do botão (Button)
agora declarado no arquivo lancador.kv

self.ids.txAng.text = self.ids.txVel.text

Cópia do conteúdo do TextInput com id de txVel para o TextInput com id txAng. Os dois TextInput estão
declarados no arquivo lancador.kv
class LancadorApp(App):

É a classe da aplicação. Esta classe herda a funcionalidade da classe principal App do Kivy

def build(self):

O método build, herdado da classe App, define quais componentes estarão no quadro, ou seja, os obje-
tos gráficos (widgets) que compõe a aplicação.
A definição dos componentes que compõe a aplicação consta do arquivo lancador.kv
self.title = 'Lancador de Bolas de Basquete'

Define o título do quadro (layout da aplicação)


20
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

return Quadro()

Retorna para a classe Quadrado que está declarada no arquivo lancador.kv


meuApp = LancadorApp()

Cria uma instancia (meuApp) da aplicação e que herda as funcionalidades da classe LancadorApp
meuApp.run()

A aplicação é iniciada pela chamada do método run(), ou seja, abre o quadro (layout da aplicação)

Abaixo, as linhas do programa lancador.kv estão sendo analisada:

3.8. Analisando o código do arquivo lancador.kv

<Quadro>

Criação da representação gráfica da classe Quadro na tela

orientation:'vertical'

Na tela, os widgets que comporão o quadro (layout da aplicação) estarão dispostos na vertical, ou seja,
um widget em baixo do outro. A representação gráfica desses widgets será criada na sequência

Label:
text:'Velocidade:'

Widget que é um rótulo cuja propriedade text, herdada da classe Label, recebe um conteúdo (‘Veloci-
dade:’)

TextInput:
id:txVel

Widget que é uma caixa de texto cuja propriedade id, herdada da classe TextInput, recebe um conteúdo
(txVel). Através do id é possível acessar esse widget que consta do arquivo .kv no programa em Python
(.py)
Label:
text:'Angulo:'

Widget que é um rótulo cuja propriedade text, herdada da classe Label, recebe um conteúdo (‘Angulo:’)
TextInput:
id:txAng

21
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Widget que é uma caixa de texto cuja propriedade id, herdada da classe TextInput, recebe um conteúdo
(txAng). Através do id é possível acessar esse widget que consta do arquivo .kv no programa em Python
(.py)

Button:
text:'Lancar!'
on_release:root.LancarClick()

Widget que é um botão e que herda funcionalidades da classe Button. A propriedade text herdada re-
cebe um conteúdo (‘Lancar!’). O evento herdado on_release executa as ações programadas no método
LancarClick, que está definido na classe Quadro do programa em Python (.py)

3.9. Passo 4 da implementação do aplicativo

🎯 Obs-1.: o programa main.py do passo 4 diferencia-se do anterior principalmente pela presença do laço de
repetição while. Esse laço de repetição é utilizado para calcular a distância percorrida pela bola a cada segundo,
obtendo-se também o tempo total utilizado na obtenção da distância percorrida.

🎯 Obs-2.: o programa lancador.kv do passo 4 diferencia-se do anterior devido ao acréscimo de 4 rótulos


herdados da classe Label. Esses rótulos serão usados para exibir na tela os valores obtidos para a distância
percorrida pela bola e para o tempo total.

🎯 Obs-3.: os trechos dos códigos abaixo escritos em cor verde referem-se às novas linhas de comando
inseridas nos arquivos do passo 4. As demais linhas de comando são idênticas às descritas nos respectivos
arquivos do passo 3.

Arquivo main.py Arquivo lancador.kv

from kivy.app import App <Quadro>


from kivy.uix.boxlayout import BoxLayout orientation:'vertical'

from math import * Label:


text:'Velocidade:'
class Quadro(BoxLayout): TextInput:
def LancarClick(self): id:txVel

x = x0 = 0 Label:
y = y0 = 0 text:'Angulo:'
TextInput:
v0 = float(self.ids.txVel.text) id:txAng
theta = float(self.ids.txAng.text) * pi/180
Button:
dt = 0.1 text:'Lancar!'
t = 0 on_release:root.LancarClick()

while y >= 0: Label:


t = t + dt text:'Distancia Percorrida'
Label:
x = x0 + v0*cos(theta)*t id:txDist

22
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

y = y0 + v0*sin(theta)* t - 9.81*t*t/2
Label:
self.ids.txDist.text="Dist = %.2f cm"%x text:'Tempo Total'
self.ids.txTempo.text="Tempo = %.2f s"%t Label:
id:txTempo

class LancadorApp(App):
def build(self):
self.title = 'Lancador de Bolas de Basquete'
return Quadro()

meuApp = LancadorApp()

meuApp.run()

Executando o programa main.py (que busca o arquivo lancador.kv) é obtida uma janela com o título ‘Lan-
cador de Bolas de Basquete’ e contendo seis rótulos, duas caixas de texto e um botão, conforme a IHC cor-
respondente (Figura 13):

Figura 13: IHC referente ao aplicativo obtido no passo 4 da implementação

Abaixo, as linhas novas inseridas no programa main.py estão sendo analisadas:

3.10. Analisando o código do arquivo main.py

from math import *

Importa tudo da biblioteca math devido as funções matemáticas que serão utilizadas neste programa
x = x0 = 0
y = y0 = 0

Inicializa com zero as variáveis ‘x’, ‘x0’, ‘y’ e ‘y0’ e que indicarão a posição da bola
v0 = float(self.ids.txVel.text)

23
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Leitura do valor digitado pelo usuário numa caixa de texto txVel (originalmente em string). Antes de atri-
buir o valor lido para ‘v0’ que representa a velocidade inicial da bola, a função float() converte o valor lido
em um valor numérico com ponto flutuante

theta = float(self.ids.txAng.text) * pi/180

Leitura do valor digitado pelo usuário numa caixa de texto txAng (originalmente em string). Antes de atri-
buir o valor lido para ‘theta’ que representa o ângulo de lançamento da bola, a função float() converte o
valor lido em um valor numérico com ponto flutuante. Este valor convertido é multiplicado por Π / 180
para obter o valor do ângulo ‘theta’ em radianos
dt = 0.1

Inicializa com 0.1 a variável ‘dt’ que representa o valor incremental do tempo
t = 0

Inicializa com zero a variável ‘t’ que indica o valor do tempo


while y >= 0:

Laço de repetição while que serve para repetir a execução dos comandos pertencentes ao laço. A repeti-
ção finaliza quando o valor de ‘y’ for negativo
t = t + dt

Incrementa em ‘t’ o valor de ‘dt’


x = x0 + v0 * cos(theta) * t
y = y0 + v0 * sin(theta) * t - 9.81 * t * t/2

Implementação das equações matemáticas descritas em ‘Situação Problema’ do item 1 – Visão Geral deste
tutorial
self.ids.txDist.text="Dist = %.2f cm"%x

Mostra na tela o rótulo txDist cujo conteúdo é o valor armazenado em ‘x’, com duas casas decimais. O
valor de ‘x’ representa a distância percorrida pela bola
self.ids.txTempo.text="Tempo = %.2f s"%t

Mostra na tela o rótulo txTempo cujo conteúdo é o valor armazenado em ‘t’, com duas casas decimais. O
valor de ‘t’ representa o tempo total

Abaixo, as linhas novas inseridas no programa lancador.kv estão sendo analisadas:

3.11. Analisando o código do arquivo lancador.kv

Label:
24
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

text:'Distancia Percorrida'

Widget que é um rótulo cuja propriedade text, herdada da classe Label, recebe um conteúdo (‘Distancia
Percorrida’)
Label:
id:txDist

Widget que é um rótulo cuja propriedade id, herdada da classe Label, recebe um conteúdo (txDist). Atra-
vés do id é possível acessar esse widget que consta do arquivo .kv no programa em Python (.py)
Label:
text:'Tempo Total'

Widget que é um rótulo cuja propriedade text, herdada da classe Label, recebe um conteúdo (‘Tempo
Total’)
Label:
id:txTempo

Widget que é um rótulo cuja propriedade id, herdada da classe Label, recebe um conteúdo (txTempo).
Através do id é possível acessar esse widget que consta do arquivo .kv no programa em Python (.py)

3.12. Passo 5 da implementação do aplicativo – Formalismo no código

Mais do que codificar um programa em uma determinada linguagem de programação, há que se ter em
mente todo o referencial que a etapa de projeto fornece através da arquitetura do software e dos algorit-
mos dos componentes do software.

🎯 Até o passo 4 da implementação do aplicativo, foi contemplada apenas a descrição da situação problema
(item 1, página 4), e as fórmulas a serem utilizadas para sua resolução.

Citando o diagrama de classes (Figura 7 – item 2.3) que descreve a arquitetura do aplicativo a ser desenvol-
vido, tem-se:

➢ três classes a serem contempladas: Jogador, Bola e Cesta


➢ a classe Jogador possui o método lancarBola()

25
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

➢ a classe Bola, além dos atributos privados: diametro, x0, y0, x e y, possui também o método mover()
que tem como parâmetros os valores da velocidade inicial e do ângulo, ambos informados pelo usu-
ário
➢ a classe Cesta possui os atributos privados: diametro, x e y

3.13. Analisando o código do arquivo main.py quanto ao formalismo

Passo 4 (arquivo original e sem formalismo) - Arquivo main.py

from kivy.app import App


from kivy.uix.boxlayout import BoxLayout

from math import *

class Quadro(BoxLayout):
def LancarClick(self):

x = x0 = 0
y = y0 = 0

v0 = float(self.ids.txVel.text)
theta = float(self.ids.txAng.text) * pi/180

dt = 0.1
t = 0

while y >= 0:
t = t + dt

x = x0 + v0*cos(theta)*t
y = y0 + v0*sin(theta)* t - 9.81*t*t/2

self.ids.txDist.text="Dist = %.2f cm"%x


self.ids.txTempo.text="Tempo = %.2f s"%t

class LancadorApp(App):
def build(self):
self.title = 'Lancador de Bolas de Basquete'
return Quadro()

meuApp = LancadorApp()

meuApp.run()

26
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Passo 5 – Arquivo main.py considerando formalismo do projeto


from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from math import *
from kivy.uix.widget import Widget
from kivy.core.window import Window

class Bola(Widget):
def __init__(self, **kwargs):
super(Bola, self).__init__(**kwargs)
#Definir as variáveis ao criar a classe Bola
self._x = x0
self.x0 = x0
self._y = y0
self.y0 = y0
self.v0 = 0
self.pos = x0,y0
self.theta = 0

def setEstadoInicial(self, x0, y0):


#Variáveis são reinicializadas quando usuário deseja REINICIAR o aplicativo
self._x = x0
self.x0 = x0
self._y = y0
self.y0 = y0
self.v0 = 0
self.pos = x0,y0
self.theta = 0

def mover(self, velocidade, theta):


self.v0 = velocidade
self.theta = theta
self.dt = 0.1
self.t = 0
while self._y >= 0:
self.t = self.t + self.dt
self._x = self.x0 + self.v0*cos(self.theta)*self.t
self._y = self.y0 + self.v0*sin(self.theta)*self.t-9.81*self.t*self.t/2
self.ids.mensagem.text="Dist= %.2f"%self._x

class Cesta(Widget):
pass

class Jogador():
def lancarBola(self, bola, velocidade, theta):
bola.mover(velocidade, theta)

class Cenario(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
Window.size = (400, 600)
self.jogador = Jogador()
self.bola.setEstadoInicial(0,0)

27
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

def LancarClick(self):
v0 = float(self.ids.txVel.text)
theta = float(self.ids.txAng.text) * pi/180
self.jogador.lancarBola(self.bola, v0, theta)

class LancadorApp(App):
def build(self):
self.title = 'Lancador de Bolas de Basquete'
return Cenario()

meuApp = LancadorApp()

meuApp.run()

Observe como o código descrito informalmente no Passo 4 torna-se formal e fiel ao projeto quando des-
crito como no Passo 5. Na tabela abaixo são citadas as principais alterações para alcançar o formalismo
desejado:
Código não formal Código formal e fiel ao projeto
A classe Quadro (nome sem significado) contém A classe Quadro é renomeada para classe Cenario
um único método definido nela: LancarClick() (nome significativo) contendo um único método
definido nela: LancarClick().
A classe Quadro possui o método LancarClick() que A classe Cenario possui seu método construtor
contém todos os comandos a serem executados
pela aplicação, cujo objetivo principal é o cálculo
da posição da bola a cada segundo em sua movi-
mentação
A classe Cenario cria o objeto jogador da classe Jo-
gador
A classe Cenario chama o método setEstadoIni-
cial() pertencente à classe Bola
A classe Cenario possui o método LancarClick()
que apenas lê os valores da velocidade inicial e ân-
gulo fornecidos pelo usuário e chama o método
lancarBola() pertencente à classe Jogador
A classe Bola possui seu método construtor
A classe Bola possui o método setEstadoInicial()
A classe Bola possui o método mover() definido
nela, conforme diagrama de classes.
O método mover() possui apenas os comandos ne-
cessários para o cálculo da posição da bola a cada
segundo em sua movimentação
A classe Cesta é modelada
A classe Jogador possui o método lancarBola() de-
finido nela, conforme diagrama de classes
A classe Jogador chama o método mover() perten-
cente à classe Bola
Ambos os códigos possuem a classe da aplicação: LancadorApp
28
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Executando o programa main.py (que busca o arquivo lancador.kv) é obtida uma janela com o título ‘Lan-
cador de Bolas de Basquete’, agora, com um layout mais próximo do esperado para o aplicativo deste tuto-
rial. Nesta fase, o layout apresenta duas caixas de texto, três rótulos e um botão, conforme a IHC correspon-
dente (Figura 14):

Figura 14: IHC referente ao aplicativo obtido no passo 5 da implementação

3.14. Analisando o código do arquivo lancador.kv – seguindo formalismo

Abaixo está a descrição do código do arquivo lancador.kv desenvolvido para que o arquivo main.py do
passo 5 possa ser executado com sucesso, respeitando o formalismo detalhado no tópico 3.13.

#:import utils kivy.utils

<Cenario>:
orientation: 'vertical'

#bind entre a variavel "bola" (arquivo main.py)


#com a instancia do objeto da classe Ball "ball_id" (interface)

bola: ball_id

canvas.before:

#Fundo azul
Color:
rgb: utils.get_color_from_hex('#eafbfe')
Rectangle:
pos: (self.width-400, self.height-400)
size: (self.width, self.width)

#Linha marrom do chao

29
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Color:
rgb: utils.get_color_from_hex('#814805')
Line:
width: 4.0
points: self.width-400, self.height-400, self.width, self.height-400

FloatLayout:

#Instancia um objeto da classe Ball

Label:
Bola:
id: ball_id

#Layout de entrada dos parametros


BoxLayout:
id: param
size_hint_y: None
height: root.height-530
orientation: 'horizontal'

#Velocidade inicial (v0 (m/s))


FloatLayout:
Label:
size_hint_y: None
height: 40
size_hint_x: None
width: 30
pos_hint: {'x': 0.1, 'y': 0.1}
text: 'v0:'
TextInput:
id: txVel
size_hint: (None, None)
height: 35
width: 45
multiline: False
hint_text: ''
pos_hint: {'x': 0.3, 'y': 0.1}

#Angulo de lancamento (Theta (graus))


FloatLayout:
Label:
size_hint_y: None
height: 40
size_hint_x: None
width: 30
text: 'Theta:'
pos_hint: {'x': 0.18, 'y': 0.1}
TextInput:
id: txAng
size_hint: (None, None)
height: 35
width: 45
multiline: False

30
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

hint_text: ''
pos_hint: {'x': 0.47, 'y': 0.1}

#Layout do botao "lanca"


FloatLayout:
size_hint_y: None
height: 80

Button:
size_hint: (None, None)
height: 40
width: 120
pos_hint: {'center_x': 0.18, 'center_y': 0.50}
text: 'Lanca'
on_press: root.LancarClick()

<Bola>:
FloatLayout:

#Mensagem com a resposta dos cálculos


Label:
id:mensagem
pos_hint:{'center_x':2.0, 'top':1.4}
text:''
font_size:28
markup:True

3.15. Passo 6 da implementação do aplicativo - Conclusão

Arquivo FINAL main.py com comentários no próprio código

from kivy.app import App


from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget

#importa-se a classe Clock para ter eventos responsivos


from kivy.clock import Clock

from kivy.core.window import Window

#importa-se a classe para vetores do kivy


from kivy.vector import Vector as Vec

from math import *


from kivy.core.audio import SoundLoader
from kivy.properties import StringProperty

#Classe da bola
class Bola(Widget):

31
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

#Properties em kivy são uma forma de ASSOCIAR um evento a uma alteração de um atributo.
#Através deste evento podemos atualizar automaticamente todos os elementos que se
#referem a este atributo.
#O evento é processado por um método que possui o nome on_nomeDaPropriedade
#No nosso caso, o método possuirá o nome on_estado

#As properties podem ser associadas a muitos tipos diferentes de dados


#StringProperty está associada a dados do tipo string
estado = StringProperty("pronta")

#Construtor
def __init__(self, **kwargs):
super(Bola, self).__init__(**kwargs)

#a bola tem o som de quicar


self.som_quica = SoundLoader.load('./som_quica.wav')

#define as variáveis ao criar a classe Bola

#define o estado inicial da bola


self._x = x0
self.x0 = x0
self._y = y0
self.y0 = y0
self.v0 = 0
self.pos = x0,y0
self.theta = 0

#estado inicial (vide diagrama de estado da bola)


self.estado = "pronta"

self.cesta = cesta
self.raio = self.width / 2

def setEstadoInicial(self, x0, y0, cesta):

#variáveis são reinicializadas quando usuário deseja REINICIAR o aplicativo

#define o estado inicial da bola

self._x = x0
self.x0 = x0
self._y = y0
self.y0 = y0
self.v0 = 0
self.pos = x0,y0
self.theta = 0

#estado inicial (vide diagrama de estado da bola)


self.estado = "pronta"

self.cesta = cesta

32
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

self.raio = self.width / 2

#Properties em kivy são uma forma de ASSOCIAR um evento a uma alteração de um atributo.
#O evento da StringProperty, cujo nome é estado será processado por um método que possui
#o nome on_nomeDaPropriedade. No nosso caso, como demos o nome estado à propriedade:
def on_estado(self, instancia, valor):

#avisa o root (Cenario) que a bola mudou de estado


App.get_running_app().root.ObservaBola(valor)

#move a bola
def mover(self, velocidade, theta):

#define a velocidade inicial e o angulo inicial da bola


self.v0 = velocidade
self.theta = theta

#incremento de tempo (em segundos)


self.dt = 5/60

#tempo inicial
self.t = 0

#Toca o som (quica a bola)


self.som_quica.play()

#altera o estado da bola para o movimento


self.estado = "em movimento"

#para aparecer a movimentação da bola durante o cálculo, usa-se o Clock


Clock.schedule_interval(self.moverIncremental, self.dt)

#Funcao callback do Clock para atualizar a posicao da bola (ver explicação detalhada na sequência)
def moverIncremental(self, dt):

#em relação à cesta, verifica-se a parada do movimento


if (self.cesta.verificaBola(self) == False):
return False

#calcula nova posical de x e y


self._x = self.x0 + self.v0*cos(self.theta)*self.t
self._y = self.y0 + self.v0*sin(self.theta)* self.t - 9.81*self.t*self.t/2

#atribui a nova posição para a bola


self.pos = Vec(self._x, self._y)

#incrementa o tempo
self.t = self.t + dt

#Classe da cesta
class Cesta(Widget):

tolerancia = 20

33
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

offsetX = 50
offsetY = 100

def posicao(self, x, y):


self.pos = x, y
self.alvo = self.pos[0] + self.offsetX, self.pos[1] + self.offsetY

def verificaBola(self, bola):

#condições para mudança de estado da bola

#1. Quando a bola estiver abaixo da posição inicial (_y < y0)
if bola._y < bola.y0:

bola.estado = "repouso no chao"


return False

#2. Quando a bola estiver sobre a cesta


if (self.alvo[0] - self.tolerancia < bola._x + bola.raio < self.alvo[0] + \
self.tolerancia) and (self.alvo[1] - self.tolerancia < bola._y + \
bola.raio < self.alvo[1] + self.tolerancia):

bola.estado = "repouso na cesta"


return False
return True

#Classe do jogador
class Jogador():
def lancarBola(self, bola, velocidade, theta):

#jogador lanca a bola


bola.mover(velocidade, theta)

#nova classe, declarada no arquivo Lancador.kv


class Cenario(BoxLayout):

#Construtor
def __init__(self, **kwargs):
super().__init__(**kwargs)

#Tamanho da janela
Window.size = (400, 600)

#Configura os sons
self.som_erro = SoundLoader.load('./som_erro.wav')
self.som_aplauso = SoundLoader.load('./som_aplauso.wav')

#cria um jogador
self.jogador = Jogador()

#inicializa o jogo
self.inicializar()

#Funcao para reiniciar o processo


def inicializar(self):

34
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

#posicao inicial da bola


self.bola.setEstadoInicial(1, 200, self.cesta)

#posicao inicial da cesta


self.cesta.posicao(300, 300)

#limpa a mensagem de erro


self.ids.mensagem.text = ''

#o Cenario fica em suspense, aguardando o estado final da bola


def ObservaBola(self, estadoBola):

if estadoBola == "repouso na cesta":


self.ids.mensagem.text = '[color=#0000FF]ACERTOU![/color]'

#Toca o som (aplauso)


self.som_aplauso.play()

return False

if estadoBola == "repouso no chao":


self.ids.mensagem.text = '[color=#FF0000]ERROU[/color]'

#Toca o som (erro)


self.som_erro.play()

return False

#método disparado pelo on_press do botao - do arquivo .kv


def LancarClick(self):

#velocidade e angulo inicial


if float(self.ids.txVel.text) > 0 and float(self.ids.txAng.text) > 0 \
and float(self.ids.txAng.text) < 90:

v0 = float(self.ids.txVel.text)
theta = float(self.ids.txAng.text) * pi/180

#jogador lanca a bola


self.jogador.lancarBola(self.bola, v0, theta)

#Funcao para sair do aplicativo


def Sair(self):
App.get_running_app().stop()

#Classe da aplicacao
class LancadorApp(App):
# o método build, herdado da classe App, define quais componentes estarão no Cenario
def build(self):
self.title = 'Lancador de Bolas de Basquete'
return Cenario()

#cria uma instancia da aplicação


meuApp = LancadorApp()

35
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

#Abre o quadro da aplicacao


meuApp.run()

🎯 Uso do Clock do Kivy (utilização de Threads):

Um dos requisitos básicos de uma boa interface com o usuário, seja ela em Kivy, Tkinter ou qualquer outra
opção, é que a mesma seja responsiva. Ou seja, mesmo que exista alguma atividade pesada em termos
computacionais operando concorrentemente com a interface, o usuário não deve perceber travamentos
ou demora demasiada para receber a resposta de uma intervenção sua com a interface. Uma forma de se
atingir este objetivo é desenvolver as atividades de interface e cálculo em threads diferentes, com o cálculo
sendo executado em background.

Por que utilizar threads? Muitas vezes, durante a implementação de programas, nos deparamos com situa-
ções nas quais o programa perde muito a sua eficiência. Uma destas situações mais comum é quando uma
determinada rotina gasta muito tempo para terminar, passando ao usuário a impressão de que tudo está
parado, e que o programa “congelou”. Isto ocorre, por exemplo, em casos de rotinas de entrada e saída,
onde os tempos de acesso a periféricos externos podem ser muito grandes, ou em casos nos quais o pro-
grama fica em um loop muito longo. Seria ótimo se pudéssemos criar o código através do uso de rotinas
independentes sendo executadas em paralelo. Assim, uma interface nunca ficaria bloqueada, o acesso a um
periférico não pararia com o restante das tarefas, etc. Estes códigos independentes são denominados thre-
ads. Threads são uma das formas que temos de conseguir uma execução simultânea de várias tarefas utili-
zando apenas um processador.

Quando dizemos “execução simultânea”, estamos na realidade dizendo que num dado intervalo de tempo,
garantimos que todas as tarefas (threads) serão executadas. Uma por vez, mas em um tempo especificado,
todas terão sido executadas”. Se uma tarefa está demorando muito, o sistema pára a sua execução e passa
o comando para a próxima tarefa na fila. Quando esta última tarefa tiver terminado ou “estourado” o seu
tempo, o comando passa para a próxima e assim sucessivamente.

Com o uso de threads, podemos em alguns casos aumentar em muito a velocidade de execução do programa
como um todo, além de manter a interface com o usuário responsiva.

O Clock é um objeto do Kivy que permite “agendar” uma chamada de função no futuro, uma vez ou
repetidamente em intervalos especificados. É possível obter o tempo decorrido entre o agendamento e a
chamada de função por meio do argumento dt. Assim:

# dt significa delta-tempo

def my_callback(dt):
pass

# chama a função my_callback para ser executada a cada 0.5 segundos


Clock.schedule_interval(my_callback, 0.5)

# chama a função my_callback para ser executada em 5 segundos


Clock.schedule_once(my_callback, 5)
36
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

# chama a função my_callback para ser executada tão logo seja possível
Clock.schedule_once(my_callback)

Nota muito importante:


Se a função callback retornar False, o agendamento será cancelado e não mais se repetirá

Do programa main.py podem ser destacados então:

Linhas de código do programa main.py Breve explicação


self.dt = 5/60 a cada 0.1 segundos, aproximadamente
Clock.schedule_interval(self.moverIncremental, self.dt) chamar a função bola.moverIncremental() a
cada 0.1 segundos
if (self.cesta.verificaBola(self) == False): na função bola.moverIncremental() é testado
o retorno da função self.cesta.verificaBola().
Se esse retorno for False, o agendamento feito
pelo Clock é cancelado
self.cesta.verificaBola() são testadas as condições que definem o valor
"repouso no chao" ou "repouso na cesta"
para bola.estado. Quando um dos dois valores
for definido, o retorno da função self.cesta.ve-
rificaBola() será False
Enquanto o retorno da função self.cesta.verificaBola() não forFalse, o objeto Clock continuará cha-
mando a função bola.moverIncremental() a cada 0.1 segundos e os comandos definidos nela continua-
rão sendo executados (cálculo da nova posição da bola)

Arquivo FINAL lancador.kv com comentários no próprio código


#:import utils kivy.utils
#para poder usar utils.get_color_from_hex('#______')

<Cenario>:
orientation: 'vertical'

#bind entre a variavel "bola" (arquivo main.py)


#com a instancia do objeto da classe Bola "ball_id" (interface)
bola: ball_id

#bind entre a variavel "cesta" (arquivo main.py)


#com a instancia do objeto da classe Cesta "cesta_id" (interface)
cesta: cesta_id

canvas.before:
#Fundo azul
Color:
rgb: utils.get_color_from_hex('#eafbfe')
Rectangle:
pos: (self.width-400, self.height-400)
size: (self.width, self.width)

#Linha marrom do chao


Color:

37
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

rgb: utils.get_color_from_hex('#814805')
Line:
width: 4.0
points: self.width-400, self.height-400, self.width, self.height-400

#Layout para colocar a bola e a mensagem de sucesso ou erro


FloatLayout:

#Instancia um objeto da classe Bola


Label:
Bola:
id: ball_id

#Instancia um objeto da classe Cesta


Label:
Cesta:
id: cesta_id

#Mensagem de sucesso ou erro


Label:
id: mensagem
pos_hint: {'center_x': 0.5, 'top' : 1.4}
text:''
font_size:40
markup:True

#Layout de entrada dos parametros


BoxLayout:
id: param
size_hint_y: None
height: root.height-530
orientation: 'horizontal'
#Velocidade inicial (v0 (m/s))
FloatLayout:
Label:
size_hint_y: None
height: 40
size_hint_x: None
width: 30
pos_hint: {'x': 0.1, 'y': 0.1}
text: 'v0:'
TextInput:
id: txVel
size_hint: (None, None)
height: 35
width: 45
multiline: False
hint_text: ''
pos_hint: {'x': 0.3, 'y': 0.1}

#Angulo de lancamento (Theta (graus))


FloatLayout:
Label:
size_hint_y: None
height: 40
size_hint_x: None
width: 30
text: 'Theta:'

38
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

pos_hint: {'x': 0.18, 'y': 0.1}


TextInput:
id: txAng
size_hint: (None, None)
height: 35
width: 45
multiline: False
hint_text: ''
pos_hint: {'x': 0.47, 'y': 0.1}

#Layout dos botoes


FloatLayout:
size_hint_y: None
height: 80
#Botao "lanca"
Button:
size_hint: (None, None)
height: 40
width: 120
pos_hint: {'center_x': 0.18, 'center_y': 0.50}
text: 'Lanca'
on_press: root.LancarClick()

#Botao "reinicio"
Button:
size_hint: (None, None)
height: 40
width: 120
pos_hint: {'center_x': 0.50, 'center_y': 0.50}
text: 'Inicializa'
on_press: root.inicializar()

#Botao "sair"
Button:
size_hint: (None, None)
height: 40
width: 120
pos_hint: {'center_x': 0.82, 'center_y': 0.50}
text: 'Sair'
on_press: root.Sair()

#Modela o objeto da bola de basquete


<Bola>:
size: 50, 50
canvas.after:
Color:
rgba:1, 1, 1, 1
Ellipse:
pos: self.pos
size: self.size
source:'./ball.png'
#Modela o objeto da cesta de basquete
<Cesta>:
canvas.before:
Rectangle:
pos: self.pos
size: (100, 100)
source: './basket.png'

39
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

APÊNDICE A – Referente ao Projeto


Por: Prof. Dr. Dani Juliano Czelusniak

Desenhando Diagramas com o Draw.io

A ferramenta draw.io é um software para a criação de diagramas de diversos tipos, que opera em
plataforma on-line e, pode ser acessado através do endereço https://www.draw.io/ . Logo ao acessar o en-
dereço supracitado, a ferramenta pergunta (inicialmente em idioma inglês) se deseja-se criar um novo dia-
grama ou abrir um existente. Nessa mesma tela inicial, é possível ativar o idioma português clicando em
“Language”, conforme demonstra a figura abaixo e escolhendo o idioma português do Brasil.

Após atualizar a página para que o novo idioma entre em vigor, pode-se clicar em “criar um novo
diagrama” para continuar. Dessa forma a ferramenta irá abrir a caixa de seleção para que escolher o tipo de
diagrama que se deseja trabalhar. Basicamente, no curso de Concepção de Soluções Baseadas em Aplicativos
(CSBA), serão necessários quatro tipos diferentes de diagramas, que serão ilustrados na sequência.

40
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

O primeiro tipo de diagrama é o diagrama de fluxo ou fluxograma, já utilizado em disciplinas anteri-


ores. Ao selecionar a opção “Fluxograma”, nove opções diferentes de fluxogramas são habilitadas na tela.
Os formatos já vistos na disciplina é o penúltimo listado, chamado “flowchart_2.xml”. Esse nome aparece ao
se posicionar o mouse sobre o modelo desejado. Em seguida deve-se clicar no botão “criar”.

Com isso, a aplicação online criará um diagrama exemplo na tela principal. Pode-se utilizar sua estru-
tura como exemplo, com comandos de copia e cola (control + c e control + v) ou, apagar o diagrama exemplo
e arrastar os componentes da barra de ferramentas ao lado esquerdo da tela para compor o próprio dia-
grama. Como exemplo, observe a figura apresentada a seguir.

41
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Para a construção de “diagramas de caso de uso”, usaremos a criação de um diagrama em branco,


para exemplificar. Assim, ao abrir a ferramenta, escolhe-se a opção “diagrama em branco” da aba “básico”,
conforme exemplificado a seguir.

Após a criação do diagrama em branco, deve-se observar a barra de ferramentas do lado esquerdo
da tela, nela existem diversos conjuntos de itens de diagramação que ficam fechados; podem ser estendidos
clicando-se sobre eles. Por exemplo, localizada a opção UML, ao clicar sobre ela, são apresentados seus
elementos de diagramação, conforme figura abaixo:

42
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Então, basta arrastar os componentes desejados para a área de diagramação. Para conectar os ele-
mentos no diagrama, basta posicionar o mouse sobre um dos elementos (qualquer tipo de diagrama), que é
habilitado o modo de conexão no elemento, onde basta clicar na seta desejada e arrastá-la até o outro ele-
mento para conectar.

Resultado do processo… a seguir… :D

43
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Para a criação de “diagramas de classe”, que denota a organização das classes que compõe um apli-
cativo em software, usa-se o diagrama de mesmo nome que está no conjunto de diagramas da UML.
Dessa forma, arrasta-se o elemento “classe” para o diagrama tal qual demonstrado nos diagramas
de caso de uso mostrado anteriormente. O elemento da classe é ilustrado pela figura a seguir:

Durante a disciplina de CSBA, serão abordados os conceitos de classes em software. Neles, será pos-
sível observar que as classes são compostas principalmente por dois elementos distintos, os atributos (field)
e os métodos (method). Quando se traz uma classe para o diagrama, ela vem somente com um atributo e
um método em sua estrutura. Caso sejam necessários mais itens, é necessário dar um duplo clique dentro
da classe para que ela entre em modo de edição, então, colocar os atributos e métodos necessários um a
um, conforme demonstra a figura a seguir. Caso seja necessário, o tamanho da classe pode ser redimensio-
nado para que o texto fique dentro do componente, posicionando o mouse sobre os pontos azul nas bordas.

44
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Por final, também serão utilizados sketchs para criar protótipos de telas de aplicativos e outras apli-
cações. Esses diagramas também podem ser desenhados utilizando essa ferramenta. Rolando a barra de
ferramentas do lado esquerdo da tela até o final, há um botão chamado “+ Mais Formas”. Clicando nele
podem ser habilitadas diversas barras de ferramentas ao gosto do usuário. Dentre elas, há uma barra espe-
cífica para aplicações Android (também para iOS, dentre outras) que pode ser habilitada, conforme imagem
abaixo:

Com a barra Android habilitada, é possível montar o sketch das aplicações para celular diretamente
dentro de um canvas que representa a tela do telefone, tal como representa a figura abaixo.
45
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Para salvar o diagrama, basta ir no menu arquivo e escolher a opção “salvar como”. Dentre diversas
opções online como google drive e outros, é possível salvar o trabalho diretamente em um dispositivo do
computador, como o disco rígido ou um pendrive, clicando-se na opção “dispositivo”.

46
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

APÊNDICE B – Referente à Implementação


Por: Prof.ª MSc. Mª Angela M Roveredo Santos

Instalando o Ambiente de Desenvolvimento Kivy

O desenvolvimento em Kivy está sendo realizado em ambiente Windows, com Kivy: v1.10.1 e Python: v3.7.2
– 64 bits.

Primeiramente o Python deverá ter sido instalado na máquina. Para executar esta instalação, acesse o link:
https://www.python.org/downloads/windows/ e escolha a opção: Download Windows x86-64 executable
installer do Python 3.7.2 - 2018-12-24 (Figura B-1).

Figura B-1: Site de acesso para Download da linguagem Python

Após o download do arquivo indicado na Figura B-1, esse mesmo arquivo deverá ser executado. No início da
execução aparecerá uma tela (Figura B-2), aonde deverão ser selecionados dois itens IMPORTANTES:

47
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Figura B-2: Tela inicial da execução do Download da linguagem Python

( 1 ) Install Now executa a instalação da linguagem Python na pasta indicada por C:\Users\Roveredo\App-
Data\Local\Programs\Python\Python37, aonde somente muda a indicação “Roveredo” para o nome dado à
referida pasta na máquina em que se está instalando a linguagem.

( 2 ) Add Python 3.7 to PATH deverá ser selecionado para que seja possível rodar o python pela linha de
comando (Prompt de Comando) do Windows. Adicionar o python ao path do sistema significa deixá-lo disponível
como variável de ambiente do sistema operacional.

🎯 ATENÇÃO: primeiro selecione a opção ( 2 ) e, por último, a opção ( 1 ) para que seja possível adicionar o python
ao PATH do sistema.

Logo após a instalação da linguagem Python, acesse o Prompt de Comando do Windows e verifique se o
Python está acessível digitando python – version. A partir daí a instalação do Kivy é feita através das seguin-
tes linhas de comando:

1. Atualização dos comandos: pip, wheel e setuptools

python -m pip install --upgrade pip wheel setuptools

2. Dependências do Kivy

python -m pip install pygame


python -m pip install cython

3 Bibliotecas complementares para áudio, vídeo e/ou OpenGL

python -m pip install docutils pygments pypiwin32 kivy.deps.sdl2 kivy.deps.glew


python -m pip install kivy.deps.gstreamer
python -m pip install kivy.deps.angle

48
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

4 Instalação do Kivy:

python -m pip install kivy

5 Instalação de exemplos com Kivy (opcional)

python -m pip install kivy_examples

Agora é possível importar o kivy no programa em Python ou rodar um exemplo básico, caso tenha sido feita
a instalação dos exemplos em Kivy (passo 5 descrito acima). Para rodar um exemplo deve ser digitada a linha
de comando indicada abaixo, no Prompt de Comando do Windows e na pasta do Python (Figura B-3):

python share\kivy-examples\demo\showcase\main.py

Figura B-3: Resultado apresentado com a execução do programa exemplo indicado

49
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

APÊNDICE C – Referente aos Layouts do Kivy


Por: Prof.ª MSc. Mª Angela M Roveredo Santos

O que é um Layout

Um objeto especial que controla a posição e o tamanho dos demais objetos na tela é chamado de Layout.

Layouts disponíveis no Kivy

Nome do Layout Descrição de atuação


BoxLayout organiza os filhos de forma sequencial, seja na vertical seja na horizontal
FloatLayout permite colocar os filhos em posições arbitrárias, assim como alterar o seu tama-
nho de forma também arbitrária
GridLayout organiza os filhos numa grade, definidas as linhas e colunas. Ao menos uma das
dimensões da grade deve ser especificada para que as dimensões dos elementos
sejam calculadas pelo Kivy
StackLayout organiza os filhos de forma sequencial, mas com um tamanho definido em uma
das dimensões, sem forçar o uso de todo o espaço, como ocorre no BoxLayout.
Use quando os filhos devem ter um tamanho predefinido, como um conjunto de
botões
AnchorLayout permite configurar a posição dos filhos relativa às bordas (topo, fundo, direita,
esquerda ou centro) do layout. O tamanho do filho não é alterado
RelativeLayout similar ao FloatLayout, com a diferença que as posições dos filhos é calculada re-
lativa à posição do layout, e não em relação à tela
ScatterLayout os filhos são definidos de forma similar ao RelativeLayout, mas podem ser trans-
ladados, rotacionados e escalados
PageLayout utilizado para criar layouts multipáginas, de forma a permitir “folhear” as páginas
utilizando as bordas

Considerações sobre o BoxLayout

O BoxLayout organiza os objetos filho em sequência, na vertical ou horizontal (default). Na sua forma mais
simples, os objetos ocupam toda a área disponível na divisão e a divisão é feita reservando o mesmo espaço
para cada objeto.
Como exemplo, abaixo são criados três botões.

Programa em Python Programa em Kivy Execução


from kivy.app import App BoxLayout:
orientation:'vertical'
class NomeArquivoKVApp(App):
pass Button:
text: 'B1'
NomeArquivoKVApp().run() Button:
50
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

text: 'B2'
Button:
text: 'B3'
Espaçamento entre os botões:

Instrução Para que serve Sintaxe Execução


spacing Espaço de 50 pixels entre BoxLayout:
os objetos desse layout spacing: 50

padding: Espaço de 20 pixels entre BoxLayout:


[20,20,20,20] cada botão spacing: 50
padding: [20,20,20,20]

Tamanho dos objetos:

- Na instrução “size-hint” os parâmetros podem varia de 0 a 1. O primeiro parâmetro corresponde a di-


mensão horizontal do botão (comparado com a dimensão x a ele designado pelo layout). O segundo parâ-
metro é a dimensão vertical.
No caso [.3 , 1]. isto significa que o nosso botão terá uma dimensão horizontal igual a 30% do tamanho da
tela e uma dimensão vertical igual a 100% do comprimento a ele alocado pelo layout.

Assim, utilizando a instrução size-hint:

Programa em Python Programa em Kivy Execução


from kivy.app import App BoxLayout:
orientation:'vertical'
class NomeArquivoKVApp(App): spacing: 50
pass padding: [20,20,20,20]

NomeArquivoKVApp().run() Button:
text: 'B1'
size_hint: [.2,1]
Button:
text: 'B2'
size_hint: [.4,1]
Button:
text: 'B3'
size_hint: [.3,1]

Posicionamento dos objetos na tela:

- Com a instrução “pos_hint” pode-se posicionar o objeto em qualquer posição dentro da linha da tela alo-
cada a ele.

51
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

O parâmetro em pos_hint estabelece que a posição x do objeto deve corresponder ao valor numérico espe-
cificado. “.5”, por exemplo, significa que o botão será inserido na posição correspondente a 50% do compri-
mento total disponibilizado para o objeto.

Assim, utilizando a instrução pos_hint:

Programa em Python Programa em Kivy Execução


from kivy.app import App BoxLayout:
orientation:'vertical'
class NomeArquivoKVApp(App): spacing: 50
pass padding: [20,20,20,20]

NomeArquivoKVApp().run() Button:
text: 'B1'
size_hint: [.2,1]
pos_hint: {'x' : .1}

Button:
text: 'B2'
size_hint: [.4,1]
pos_hint: {'x' : .3}

Button:
text: 'B3'
size_hint: [.3,1]
pos_hint: {'x': .5}

Considerações sobre o StackLayout

O StackLayout é mais flexível que o BoxLayout, distribuindo os objetos pela área da tela nas seguintes orien-
tações:

Representação Funcionamento
das orientações
lr – tb left (esquerda) righ (direita) top (topo) bottom (fundo) – irá distribuir os objetos da
esquerda para a direita, de cima para baixo
rl – bt direita para esquerda, de baixo para cima
lr – bt esquerda para direita, de baixo para cima
rl – tb direita para esquerda, de cima para baixo
bt – rl de baixo para cima, da direita para esquerda
bt - lr de baixo para cima, da esquerda para direita
tb – rl de cima para baixo, da direita para esquerda
tb – lr de cima para baixo, da esquerda para direita

52
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

A distribuição é realizada pela sequência com que os objetos são inseridos no texto do código fonte em Kivy.

Como exemplo, o StackLayout será usado para criar um teclado binário com suas respectivas operações
binárias correspondentes. Assim:

Programa em Python Programa em Kivy Execução


from kivy.app import App StackLayout:
orientation:'lr-tb'
class NomeArquivoKVApp(App): Button:
pass text: '0'
size_hint:[.33,.5]
NomeArquivoKVApp().run() Button:
text: '1'
size_hint:[.33,.5]
Button:
text: 'AND'
size_hint:[.33,.5]
Button:
text: 'OR'
size_hint:[.33,.5]
Button:
text: 'XOR'
size_hint:[.33,.5]
Button:
text: 'cls'
size_hint:[.33,.5]

Considerações sobre o GridLayout

O GridLayout é muito parecido com o StackLayout na configuração lr – tp (esquerda para direita, de cima
para baixo). A diferença é que podemos estabelecer o número de colunas (cols:) e linhas (rows:). Basta for-
necer um desses parâmetros, que o outro é calculado automaticamente dependendo do número de objetos
na tela. Assim como no caso anterior, um objeto pode ser separado do outro usando instruções spacing e
padding.

Programa em Python Programa em Kivy Execução


from kivy.app import App GridLayout:
cols: 3
class NomeArquivoKVApp(App): spacing:50
pass padding:[20,30]
Button:
NomeArquivoKVApp().run() text: '0'
Button:
text: '1'
Button:
text: 'AND'

53
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Button:
text: 'OR'
size_hint:[.33,.5]
Button:
text: 'XOR'
Button:
text: 'cls'

Considerações sobre o FLoatLayout

Com o FloatLayout, um objeto é implementado na tela com tamanho em função do tamanho total da tela,
ou seja, nas dimensões do objeto não são especificadas em pixels absolutos, mas sim em percentual do
tamanho da tela na horizontal e vertical.
O maior benefício é a tela se ajustar às mudanças de dimensões provocadas pelo usuário, assim como à
adaptações a telas de diferentes tamanhos.
Exemplo de como pode ser usado o FLoatLayout:

Programa em Python Programa em Kivy Execução


from kivy.app import App <Button>:
color: 1,0,0,1
class NomeArquivoKVApp(App): font_size: 32
pass size_hint: .4, .3

NomeArquivoKVApp().run() FloatLayout:
Button:
text: 'Ola'
pos_hint: {'x': 0, 'top': 1}
Button:
text: 'Mundo louco!'
pos_hint: {'right': 1, 'y': 0}

Um objeto do tipo [button] é configurado e será utilizado na tela. Esse objeto:

• terá associado a ele um texto da cor vermelha através da propriedade color (r, g, b, a) onde ‘r’ varia
de 0 a 1 correspondendo ao tom de vermelho da cor, ‘g’ ao tom verde e ‘b’ ao tom azul. O parâmetro
‘a’ corresponde à transparência do texto, sendo 0 totalmente transparente e 1 totalmente opaco;
• font_size estabelece o tamanho da fonte em pixels
• size_hint fornece as dimensões (em percentual) da largura e altura da tela. O valor “.4” significa que
o objeto estará ocupando 40% da largura da tela. O valor “.3” significa que o objeto estará ocupando
30% da altura da tela.
Na sequência do código, quando se faz uso do objeto do tipo [button] já configurado, acrescenta-se a ele:
• text que contém o texto a ser exibido no próprio botão

54
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

• pos_hint define a posição do objeto na tela (x, y). Para y = 1, significa máxima altura possível (ou topo);
para x = 1, significa máxima largura à direita.

55
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

APÊNDICE D – Referente ao Canvas – desenhando formas 2D


básicas em Kivy
Por: Prof.ª MSc. Mª Angela M Roveredo Santos

O que é Canvas

Canvas é um conjunto de instruções que permite representar um objeto visivelmente na tela. ATENÇÃO:
canvas NÃO é um espaço em que são traçados os objetos.
Para desenhar numa tela, são necessários dois tipos de objetos: um objeto é chamado CANVAS e o outro é
chamado INSTRUCTION.
Cada objeto Widget em Kivy, ao ser criado, já nasce com um objeto Canvas, ou seja, quando um widget é
criado, ele já sabe como se desenhar na tela. O que ainda é necessário ser fornecido a ele são os parâmetros
para a realização do desenho.
Aqui serão desenhados linhas, retângulos, triângulos e elipses utilizando o objeto Canvas do Kivy.

Considerações sobre os objetos que podem ser traçados

Programa em Python Programa em Kivy Execução


from kivy.app import App RelativeLayout:
canvas:
class NomeArquivoKVApp(App): Rectangle:
pass pos: 0,0
size: 100,100
NomeArquivoKVApp().run()

Um retângulo é inserido na tela; ele inicia na posição 0, 0 e tem o tamanho de 100 pixels na horizontal e 100
pixels na vertical.
Se forem arrastados os limites horizontais da tela, aumenta e diminuindo a área da janela gráfica, o retângulo
não muda de dimensão. Isso ocorre devido as dimensões do retângulo serem absolutas. Para resolver, serão
estipuladas ao retângulo dimensões relativas as dimensões da tela.
No programa em Kivy acima, substitua a linha:
size: 100,100
pela linha:
size: self.width*0.2, self.height*0.2

56
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Agora as dimensões do retângulo são proporcionais ao tamanho da tela, aonde, nesse caso, corresponde a
20% da largura e da altura da tela. Se houver alteração nas dimensões da janela, as dimensões do retângulo
se alterarão de forma proporcional.

Programa em Python Programa em Kivy Execução


from kivy.app import App RelativeLayout:
canvas:
class NomeArquivoKVApp(App): Rectangle:
pass pos: 0,0
size: 100,100
NomeArquivoKVApp().run()
Ellipse:
segments: 180
angle_start: 0
angle_end: 270
pos: 200,200
size: 100,100

O setor circular que foi construído através do comando Ellipse tem como configuração:

• número de segmentos (o valor default é 180)


• o ângulo de início. Nesse caso valendo 0 (zero) graus corresponde à direção norte (ou, para cima)
• o ângulo de término. Quando o ângulo final é maior que o ângulo inicial, o traçado é sempre feito na
direção horária
• a posição e o tamanho são interpretados exatamente como no caso do retângulo
Observe que a existência do parâmetro “segments”, que define o número de segmentos utilizados no tra-
çado externo, abre uma grande quantidade de formas possíveis de serem obtidas com o comando Ellipse.
Como no próximo exemplo, se segments = 3, será um triângulo. Assim:

Programa em Python Programa em Kivy Execução


from kivy.app import App RelativeLayout:
canvas:
class NomeArqui- Rectangle:
voKVApp(App): pos: 0,0
pass size: 100,100

NomeArquivoKVApp().run() Ellipse:
segments: 180
angle_start: 0
angle_end: 270
pos: 200,200
size: 100,100

Ellipse:
segments: 3
57
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

angle_start: 0
angle_end: 360
pos: 350,350
size: 100,100

Traçando linhas, pontos e outros objetos no Kivy:

Programa em Python Programa em Kivy


from kivy.app import App RelativeLayout:
canvas:
class NomeArquivoKVApp(App): Point:
pass points: 50,50, 60,50, 70,50, 80,50
pointsize: 4
NomeArquivoKVApp().run()
Triangle:
points: 100,100, 150,150, 200,100

Quad:
points: 300,100, 300,200, 400,200, 400,100

Line:
points: 500,100, 550,150, 600,100, 650,150
Execução

Destacam-se:

• o ponto (Point) que é caracterizado por duas coordenadas, “x” e “y”. Acima estão descritos quatro pon-
tos, todos com tamanho de 4 pixels cada
• o triângulo (Triangle) apresenta três pares de coordenadas representando seus vértices
• o quadrilátero (Quad) apresenta quatro pares de coordenadas representando seus vértices
• a linha (Line) apresenta quatro pares de coordenadas (pontos) pelos quais a linha deverá passar

58
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

APÊNDICE E – Referente às especificações de tamanhos dos


Widgets em Kivy
Por: Prof.ª MSc. Mª Angela M Roveredo Santos

Configuração das dimensões dos Widgets

1. As dimensões podem ser definidas de duas formas básicas: absoluta ou relativa


• Tamanho absoluto no código fonte é denominado size()
• Tamanho relativo no código fonte é denominado size_hint()
2. O controle ocorre sobre as dimensões de comprimento e largura (ou “x” e “y”)
3. A propriedade que se refere às dimensões é acessível em todos os widgets do Kivy
4. As seguintes formas de especificação de dimensões estão disponíveis:

Especificação de Tipo de
Para que serve
dimensões dimensão
size_hint_x relativa Especifica dimensão relativa entre os widgets no eixo x
size_hint_y relativa Especifica dimensão relativa entre os widgets no eixo y
size_hint relativa Especifica, simultaneamente, dimensões relativas entre os widgets
nos eixos x e y
width absoluta Especifica um valor absoluto no comprimento (eixo x)
height absoluta Especifica um valor absoluto na altura (eixo y)
size absoluta Especifica, simultaneamente, um valor absoluto para o compri-
mento e um valor absoluto para a altura

ATENÇÃO: se você atribui ao size_hint de um widget o valor “0.5” e a outro o valor “1”, o segundo irá ocupar
uma largura duas vezes maior do que o primeiro. Se todos forem “.3”, todos serão iguais. NÃO é o valor
absoluto atribuído que importa, mas sim a relação entre eles.
Quando se fizer necessário especificar um valor absoluto, as propriedades width e height são usadas, res-
pectivamente para largura e altura, porém, É MUITO IMPORTANTE especificar também as propriedades
size_hint_x ou size_hint_y ou ambas (size_hint), caso necessário, como iguais a None. Sem isso o Kivy NÃO
obedece ao valor absoluto especificado em width e height.

5. Quais unidades são usadas para especificar a altura e a largura de um widget

Para especificar: Usa-se


apenas um número inteiro pixels
em centímetros o sufixo cm após o número
em polegadas o sufixo in após o número
relativo a resolução do display o sufixo dp após o número

59
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Para finalizar: os widgets de layout muitas vezes têm vontade própria e decidem por conta os seus tamanhos.
Geralmente fazem boas escolhas. Mas, só a experimentação em diversos meios de saída poderá assegurar
que a apresentação dos programas está conforme o planejado.

60
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

APÊNDICE F – Referente ao widget TextInput em Kivy


Por: Prof.ª MSc. Mª Angela M Roveredo Santos

O que é TextInput

É um widget que permite a digitação (fornecimento) de texto na tela.

Considerações sobre o arquivo .kv

O arquivo .kv começa a ficar mais sofisticado, porém, o fundamental é observar o aninhamento de conjun-
tos de widgets que se faz necessário para que as propriedades dos widgets (layouts) responsáveis pela dis-
posição dos demais objetos (Labels e TextInputs) na tela possa ser aplicada de forma correta.

Programa em Python Programa em Kivy Execução


from kivy.app import App BoxLayout:
orientation: 'vertical'
class NomeArquivoKVApp(App): BoxLayout:
pass orientation:'vertical'
cols: 1
NomeArquivoKVApp().run() spacing: 20
padding: [200,10]
BoxLayout:
orientation: 'horizontal'
Label:
text: 'Nome:'
size_hint_x: .5
TextInput:
id: txt_nome
size_hint_x: 1
BoxLayout:
orientation: 'horizontal'
Label:
text: 'E-mail:'
size_hint_x: .5
TextInput:
id: txt_email
size_hint_x: 1
BoxLayout:
orientation: 'horizontal'
Label:
text: 'Endereco:'
size_hint_x: .5
TextInput:

61
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

id: txt_endereco
size_hint_x: 1
BoxLayout:
orientation: 'horizontal'
Label:
text: 'Fone:'
size_hint_x: .5
TextInput:
id: txt_fone
size_hint_x: 1

Analisando o arquivo .kv, destacam-se:

BoxLayout:
orientation: 'vertical' os widgets ou conjuntos de widgets serão organizados na vertical

BoxLayout: os campos para entrada de textos e respectivos labels ficam sob esse Layout
orientation:'vertical' cada conjunto (textInput + label) fica numa única linha e na vertical
cols: 1
spacing: 20
padding: [200,10]

BoxLayout:
orientation: 'horizontal' label e textInput ficam na mesma linha, um ao lado do outro
Label:
text: 'Nome:'
size_hint_x: .5 o label tem a metade do tamanho do seu respectivo textInput
TextInput:
id: txt_nome
size_hint_x: 1

... seguem os demais conjuntos de labels e textInputs

62
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

APÊNDICE G – Referente a Classes e Métodos no Python


Por: Prof.ª MSc. Mª Angela M Roveredo Santos

O que é Programação Orientada a Objetos (POO)

É um paradigma para o desenvolvimento de software que se baseia na utilização de componentes indivi-


duais (objetos) que colaboram para construir sistemas mais complexos.
➢ Descreve uma série de técnicas para estruturar soluções para problemas computacionais; e
➢ É um paradigma de programação no qual um programa é estruturado em objetos.

Considerações sobre Objetos:

➢ É a metáfora para se compreender a tecnologia orientada a objetos;


➢ Estamos rodeados por objetos: mesa, carro, livro, pessoa, etc; e
➢ Os objetos do mundo real têm duas características em comum:
✓ Estado – representa as propriedades (nome, peso, altura, cor, etc.); e
✓ Comportamento – representa ações (andar, falar, calcular, etc.).
Ilustrações de Objetos:

Principais vantagens:

➢ Aumento de produtividade;
➢ Reuso de código;
➢ Redução das linhas de código programadas;
➢ Separação de responsabilidades;
➢ Componentização;
➢ Maior flexibilidade do sistema; e
➢ Facilidade na manutenção.

63
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Os quatro pilares da POO:

Abstração Encapsulamento Herança Polimorfismo

Considerações sobre Classes:

➢ A estrutura fundamental para definir novos objetos é a classe; e


➢ Uma classe é definida em código-fonte.

Ilustrações de Classes:

Classe em Python:

Estrutura:
class nome_da_classe:
atributos
construtor
métodos
64
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Demonstração de Classe:

Considerações sobre Instância:

➢ Uma instância é um objeto criado com base em uma classe definida;


➢ Classe é apenas uma estrutura, que especifica objetos, mas que não pode ser utilizada direta-
mente;
➢ Instância representa o objeto concretizado a partir de uma classe;
➢ Uma instância possui um ciclo de vida:
✓ Criada;
✓ Manipulada; e
✓ Destruída.

variável = Classe()

Demonstração de Instância:

65
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Considerações sobre Método Construtor:

➢ Determina que ações devem ser executadas quando da criação de um objeto; e


➢ Pode possuir ou não parâmetros.
Estrutura:
Demonstração de um Método Construtor:

Considerações sobre Métodos:

➢ Representam os comportamentos de uma classe;


➢ Permitem que acessemos os atributos, tanto para recuperar os valores, como para alterá-los, caso
necessário;
➢ Podem retornam ou não algum valor; e
➢ Podem possuir ou não parâmetros.
Estrutura:

Importante: o parâmetro self é obrigatório


Demonstração de Métodos:

66
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Considerações sobre Encapsulamento:

➢ Consiste em separar os aspectos externos de um objeto dos detalhes internos de implementação;


➢ Evita que dados específicos de uma aplicação possa ser acessado diretamente; e
➢ Protege os atributos ou métodos de uma classe.

Ilustração:

Considerações sobre Modificadores de Acesso:

➢ Em Python, existem dois tipos de modificadores de acesso para atributos e métodos:


✓ Público; ou
✓ Privado.
➢ Atributos ou métodos iniciados por dois sublinhados são privados e todas as outras formas são pú-
blicas.

Demonstração de Encapsulamento:

Considerações sobre Herança:

➢ É uma forma de abstração utilizada na orientação a objetos;


➢ Pode ser vista como um nível de abstração acima da encontrada entre classes e objetos;

67
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

➢ Na herança, classes semelhantes são agrupadas em hierarquias;


➢ Cada nível de uma hierarquia pode ser visto como um nível de abstração;
➢ Cada classe em um nível da hierarquia herda as características das classes nos níveis acima;
➢ É uma forma simples de promover reuso através de uma generalização;
➢ Facilita o compartilhamento de comportamento comum entre um conjunto de classes semelhan-
tes; e
➢ As diferenças ou variações de uma classe em particular podem ser organizadas de forma mais
clara.

Ilustração:

Estrutura:

Demonstração de Herança:

Arquivo conta.py que contém a classe Conta():

68
Pontifícia Universidade Católica do Paraná (PUCPR)
Concepção de Soluções Baseadas em Aplicativos (CSBA)

Arquivo que usa a classe Conta():

Invoca-se o método super()


para implementar a funcionali-
dade da classe original que está
sendo herdada, no caso, Conta()

Considerações sobre Polimorfismo:

➢ É originário do grego e significa “muitas formas” (poli = muitas, morphos = formas);


➢ Indica a capacidade de abstrair várias implementações diferentes em uma única interface;
➢ É o princípio pelo qual duas ou mais classes derivadas de uma mesma superclasse podem invocar
métodos que têm a mesma identificação (assinatura) mas comportamentos distintos; e
➢ Quando polimorfismo está sendo utilizado, o comportamento que será adotado por um método só
será definido durante a execução.

Demonstração de Polimorfismo:

69

Você também pode gostar