Você está na página 1de 46

Machine Translated by Google

Capítulo 4 Objetos e
Gráficos

Objetivos
• Para entender o conceito de objetos e como eles podem ser usados para simplificar

programação.

• Familiarizar-se com os diversos objetos disponíveis na biblioteca de gráficos.

• Ser capaz de criar objetos em programas e chamar métodos apropriados para realizar
cálculos gráficos.

• Compreender os conceitos fundamentais da computação gráfica, especialmente o


papel dos sistemas de coordenadas e das transformações de coordenadas.

• Para entender como trabalhar com entrada baseada em mouse e texto em um


contexto de programação gráfica.

• Ser capaz de escrever programas gráficos interativos simples usando os gráficos


biblioteca.

14.11 Visão geral

Até agora, escrevemos programas que usam os tipos de dados internos do Python para
números e strings. Vimos que cada tipo de dado pode representar um determinado conjunto
de valores e cada um possui um conjunto de operações associadas. Basicamente, vimos os
dados como entidades passivas que foram manipuladas e combinadas por meio de operações
ativas. Esta é uma maneira tradicional de ver a computação. Para construir sistemas complexos,

83
Machine Translated by Google

84 Capítulo 4. Objetos e Gráficos

no entanto, ajuda a ter uma visão mais rica do relacionamento entre dados e operações.

A maioria dos programas de computador modernos são construídos usando uma


abordagem orientada a objetos (00) . A orientação do objeto não é facilmente definida. Ele
abrange vários princípios para projetar e implementar software, princípios aos quais
retornaremos várias vezes ao longo deste livro. Este capítulo fornece uma introdução básica
aos conceitos de objetos por meio de alguns gráficos de computador.
A programação gráfica é muito divertida e fornece um ótimo veículo para aprender
sobre objetos. No processo, você também aprenderá os princípios da computação gráfica
que fundamentam muitos aplicativos de computador modernos. A maioria dos aplicativos
com os quais você está familiarizado provavelmente tem a chamada interface gráfica do
usuário (GUI) que fornece elementos visuais como janelas, ícones (imagens representativas),
botões e menus.
A programação gráfica interativa pode ser muito complicada; livros didáticos inteiros
são dedicados aos meandros dos gráficos e interfaces gráficas. Os aplicativos GUI de força
industrial geralmente são desenvolvidos usando uma estrutura de programação gráfica
dedicada. Python vem com seu próprio módulo GUI padrão chamado Tkinter. No que diz
respeito às estruturas de GUI, o Tkinter é um dos mais simples de usar, e o Python é uma
ótima linguagem para desenvolver GUIs do mundo real. Ainda assim, neste ponto de sua
carreira de programação, seria um desafio aprender os meandros de qualquer estrutura de
GUI, e isso não contribuiria muito para os principais objetivos deste capítulo, que são
apresentá-lo aos objetos e aos princípios fundamentais. ples de computação gráfica.

Para facilitar o aprendizado desses conceitos básicos, usaremos uma biblioteca de


gráficos (graphics .py) escrita especificamente para uso com este livro. Esta biblioteca é um
wrapper em torno do Tkinter que o torna mais adequado para programadores iniciantes.
Ele está disponível gratuitamente como um arquivo de módulo Python1 e você pode usá-lo
como achar melhor. Eventualmente, você pode querer estudar o código da própria biblioteca
como um trampolim para aprender a programar diretamente no Tkinter.

14.21 O Objeto dos Objetos


A ideia básica do desenvolvimento orientado a objetos é ver um sistema complexo como a
interação de objetos mais simples. A palavra objetos está sendo usada aqui em um sentido
técnico específico. Parte do desafio da programação 00 é descobrir o vocabulário. Você
pode pensar em um objeto 00 como uma espécie de tipo de dado ativo que

1O módulo gráfico está disponível no site de suporte deste livro.


Machine Translated by Google

4.3. Programação gráfica simples 85

combina dados e operações. Para simplificar, os objetos sabem coisas (contêm dados) e podem
fazer coisas (têm operações). Os objetos interagem enviando mensagens uns aos outros. Uma
mensagem é simplesmente uma solicitação para que um objeto execute uma de suas operações.

Considere um exemplo simples. Suponha que queremos desenvolver um sistema de


processamento de dados para uma faculdade ou universidade. Teremos de manter o controle de
informações consideráveis. Para começar, devemos manter registros sobre os alunos que
frequentam a escola. Cada aluno poderia ser representado no programa como um objeto. Um
objeto aluno conteria determinados dados, como nome, número de identificação, cursos realizados,
endereço do campus, endereço residencial, GPA, etc. Cada objeto aluno também seria capaz de
responder a determinadas solicitações. Por exemplo, para enviar uma correspondência,
precisaríamos imprimir um endereço para cada aluno. Essa tarefa pode ser tratada por uma
operação printCampusAddress . Quando um objeto aluno específico recebe a mensagem
printCampusAddress , ele imprime seu próprio endereço. Para imprimir todos os endereços, um
programa percorreria a coleção de objetos de aluno e enviaria a cada um a mensagem
printCampusAddress .
Objetos podem se referir a outros objetos. Em nosso exemplo, cada curso da faculdade
também pode ser representado por um objeto. Objetos de curso saberiam coisas como quem é o
instrutor, quais alunos estão no curso, quais são os pré-requisitos e quando e onde o curso atende.
Um exemplo de operação pode ser addStudent, que faz com que um aluno seja matriculado no
curso. O aluno matriculado seria representado pelo objeto aluno apropriado. Os instrutores seriam
outro tipo de objeto, assim como as salas e até os tempos. Você pode ver como o refinamento
sucessivo dessas ideias pode levar a um modelo bastante sofisticado da estrutura de informação
da faculdade.

Como programador iniciante, você provavelmente ainda não está pronto para lidar com um
sistema de informação universitário. Por enquanto, estudaremos objetos no contexto de uma
programação gráfica simples.

14.31 Programação de Gráficos Simples

Para executar os programas gráficos e exemplos deste capítulo (e do restante do livro), você
precisará de uma cópia do arquivo graphics . py que é fornecido com os materiais suplementares.
Usar a biblioteca de gráficos é tão fácil quanto colocar uma cópia dos gráficos. py na mesma pasta
que seu(s) programa(s) gráfico(s).
Alternativamente, você pode colocá-lo em um diretório do sistema onde outras bibliotecas Python
são armazenadas para que ele possa ser usado em qualquer pasta do sistema.
A biblioteca de gráficos facilita a experimentação de gráficos de forma interativa
Machine Translated by Google

86 Capítulo 4. Objetos e Gráficos

e escrever programas gráficos simples. Ao fazer isso, você aprenderá princípios de programação
orientada a objetos e computação gráfica que podem ser aplicados em ambientes de programação
gráfica mais sofisticados. Os detalhes do módulo gráfico serão explorados em seções posteriores.
Aqui vamos nos concentrar em uma introdução prática básica para abrir seu apetite.

Como de costume, a melhor maneira de começar a aprender novos conceitos é arregaçar


as mangas e experimentar alguns exemplos. O primeiro passo é importar o módulo gráfico.
Supondo que você tenha colocado gráficos . py em um local apropriado, você pode importar os
comandos gráficos para uma sessão interativa do Python. Se você estiver usando o IDLE, talvez
seja necessário primeiro "apontar" o IDLE para a pasta onde você salvou os gráficos . py.
Uma maneira simples de fazer isso é carregar e executar um de seus programas existentes
dessa pasta. Então você deve poder importar gráficos para a janela do shell:

>>> importar gráficos


>>>

Se essa importação falhar, significa que o Python não conseguiu encontrar o módulo gráfico.
Verifique se o arquivo está na pasta correta e tente novamente.
Em seguida, precisamos criar um local na tela onde os gráficos aparecerão.
Esse local é uma janela gráfica ou GraphWin, que é fornecida por graphics :

>>> vitória = gráficos. GraphWin()


>>>

Observe o uso da notação de ponto para invocar a função GraphWin que "vive" na biblioteca de
gráficos. Isso é análogo a quando usamos math. sqrt (x) para invocar a função raiz quadrada do
módulo da biblioteca matemática. A função Graph Win () cria uma nova janela na tela. A janela
terá o título "Janela de Gráficos". O GraphWin pode se sobrepor à janela do shell do Python,
portanto, talvez seja necessário redimensionar ou mover o shell para tornar as duas janelas
totalmente visíveis. A Figura 4.1 mostra um exemplo de exibição de tela.

O GraphWin é um objeto, e nós o atribuímos à variável chamada win.


Agora podemos manipular o objeto window através desta variável. Por exemplo, quando
terminamos uma janela, podemos destruí-la. Isso é feito emitindo o comando close :

>>> vitória. perto ()


>>>

Digitar este comando faz com que a janela desapareça da tela.


Machine Translated by Google

4.3. Programação gráfica simples 87

com isto ele indo

Python 3.4.3 (v3.4.3:9b73flc3e601, 24 de fevereiro de 2015, 22:44:40) (HSC v.1600 64 bit (AI1D64) ) no win32 Digite
"copyright", "credits" ou "license()" para mais informações. >>> da importação de gráficos ÿ >>> win = GraphWin()

»> eu

Figura 4.1: Captura de tela com um shell Python e um GraphWin

Observe que estamos novamente usando a notação de ponto, mas agora a estamos
usando com um nome de variável, não um nome de módulo, no lado esquerdo do ponto.
Lembre-se de que win foi atribuído anteriormente como um objeto do tipo GraphWin. Uma
das coisas que um objeto GraphWin pode fazer é se fechar. Você pode pensar nesse
comando como invocando a operação de fechamento associada a essa janela específica. O
resultado é que a janela desaparece da tela.
A propósito, devo mencionar aqui que experimentar comandos gráficos de forma
interativa como este pode ser complicado em alguns ambientes. Se você estiver usando um
shell em um IDE como o IDLE, é possível que em sua plataforma específica uma janela
gráfica pareça não responder. Por exemplo, você pode ver um cursor "ocupado" ao passar o
mouse sobre a janela e pode não conseguir arrastar a janela para posicioná-la. Em alguns
casos, sua janela gráfica pode estar completamente oculta sob o IDE e você para procurá-lo.
Essas falhas
Machine Translated by Google

88 Capítulo 4. Objetos e Gráficos

são devidos ao IDE e à janela gráfica, ambos se esforçando para controlar suas
interações. Independentemente de quaisquer dificuldades que você possa ter ao jogar
com os gráficos de forma interativa, tenha certeza de que seus programas que usam a
biblioteca de gráficos devem funcionar bem na maioria dos ambientes padrão. Eles
definitivamente funcionarão no Windows, macOS e Linux.
Estaremos usando alguns comandos da biblioteca de gráficos, e fica tedioso ter
que digitar os "gráficos". notação cada vez que usamos um. Python tem uma forma
alternativa de importação que pode ajudar:

da importação de gráficos *

A instrução from permite carregar definições específicas de um módulo de biblioteca.


Você pode listar os nomes das definições a serem importadas ou usar um asterisk,
como mostrado, para importar tudo o que está definido no módulo. Os comandos
importados ficam disponíveis diretamente sem ter que prefaciá-los com o nome do
módulo. Após fazer essa importação, podemos criar um GraphWin de forma mais simples:

vitória = GraphWin()

Todos os demais exemplos gráficos assumirão que todo o módulo gráfico foi importado
usando from.
Vamos tentar nossa mão em algum desenho. Uma janela gráfica é, na verdade,
uma coleção de pequenos pontos chamados pixels (abreviação de "elementos de
imagem"). Ao controlar a cor de cada pixel, controlamos o que é exibido na janela. Por
padrão, um GraphWin tem 200 pixels de altura e 200 pixels de largura. Isso significa
que existem 40.000 pixels no GraphWin. Desenhar uma imagem atribuindo uma cor a
cada pixel individual seria um desafio assustador. Em vez disso, contaremos com uma
biblioteca de objetos gráficos. Cada tipo de objeto faz sua própria contabilidade e sabe
como se desenhar em um GraphWin.
O objeto mais simples no módulo gráfico é um Point. Na geometria, um ponto é
uma localização no espaço. Um ponto é localizado por referência a um sistema de
coordenadas. Nosso objeto gráfico Point é semelhante; ele pode representar um local
em um GraphWin. Definimos um ponto fornecendo as coordenadas x e y (x, y). O valor
x representa a localização horizontal do ponto e o valor y representa a vertical.
Tradicionalmente, os programadores gráficos localizam o ponto (0, 0) no canto
superior esquerdo da janela. Assim , os valores de x aumentam da esquerda para a
direita e os valores de y aumentam de cima para baixo. No GraphWin padrão de 200 x
200 , o canto inferior direito tem as coordenadas (199, 199). Drawing a Point define a
cor do pixel correspondente no GraphWin. A cor padrão para desenho é preto.
Aqui está um exemplo de interação com Python ilustrando o uso de Pontos:
Machine Translated by Google

4.3. Programação gráfica simples 89

>>> p = Ponto (50 , 60)


>>> p.getX O 50
>>> p.getY O 60

>>> win = GraphWin() >>>


p . draw(win) >>> p2 =
Ponto ( 140 >>> p2 . , 100)
draw(win)

A primeira linha cria um Point localizado em (100, 120). Após a criação do Ponto ,
seus valores de coordenadas podem ser acessados pelas operações getX e getY.
Como em todas as chamadas de função, certifique-se de colocar os parênteses no final
quando estiver tentando usar as operações. Um Point é desenhado em uma janela usando
a operação draw . Neste exemplo, dois objetos Point diferentes (p e p2) são criados e
desenhados no GraphWin chamado win. A Figura 4.2 mostra a saída gráfica resultante.

Figura 4.2: Janela de gráficos com dois pontos desenhados

Além de pontos, a biblioteca de gráficos contém comandos para desenhar linhas,


círculos, retângulos, ovais, polígonos e texto. Cada um desses objetos é criado e
desenhado de maneira semelhante. Aqui está um exemplo de interação para desenhar
várias formas em um GraphWin:
Machine Translated by Google

90 Capítulo 4. Objetos e Gráficos

>>> #### Abra uma janela gráfica >>>


win= GraphWin('Shapes')
>>> #### Desenhe um círculo vermelho centrado no ponto (100,100) com raio 30 >>> center =
Point(100,100) >>> eire = Circle(center, 30) >>> circ.setFill('red' ) >>> circ.draw(ganhar)

>>> #### Coloque um rótulo textual no centro do círculo >>> label =


Text(center, "Red Circle") >>> label.draw(win)

>>> #### Desenhe um quadrado usando um objeto Rectangle


>>> rect = Rectangle(Point(30,30), Point(70,70)) >>> rect.draw(win)

>>> #### Desenhe um segmento de linha usando um objeto Line


>>>line= Line(Point(20,30), Point(180, 165)) >>> line.draw(win)

>>> #### Desenhe uma oval usando o objeto Oval oval=


>>> Oval(Point(20,150), Point(180,199)) oval.draw(win)
>>>

Tente descobrir o que cada uma dessas declarações faz. Se você digitá-los como mostrado,
o resultado final será semelhante à Figura 4.3.

Formas

Figura 4.3: Várias formas do módulo gráfico


Machine Translated by Google

4.4. Usando objetos gráficos 91

14.41 Usando Objetos Gráficos


Alguns dos exemplos nas interações acima podem parecer um pouco estranhos para você.
Para realmente entender o módulo gráfico, precisamos adotar um ponto de vista orientado
a objetos. Lembre-se, objetos combinam dados com operações. A computação é realizada
pedindo a um objeto que execute uma de suas operações. Para fazer uso de objetos, você
precisa saber como criá-los e como solicitar operações.

Nos exemplos interativos acima, manipulamos vários tipos diferentes de objetos:


GraphWin, Point, Circle, Oval, Line, Text e Rectangle. Estes são exemplos de classes.
Cada objeto é uma instância de alguma classe, e a classe descreve as propriedades que a
instância terá.
Tomando emprestada uma metáfora biológica, quando dizemos que Fido é um
cachorro, na verdade estamos dizendo que Fido é um indivíduo específico na classe maior
de todos os cães. Na terminologia 00 , Fido é uma instância da classe dog. Como Fido é
uma instância dessa classe, esperamos certas coisas. Fido tem quatro patas, um rabo, um
nariz frio e úmido e late. Se Rex for um cão, esperamos que ele tenha propriedades
semelhantes, embora Fido e Rex possam diferir em detalhes específicos, como tamanho ou cor.
As mesmas ideias valem para nossos objetos computacionais. Podemos criar duas
instâncias separadas de Point, digamos p e p2. Cada um desses pontos tem um valor xey
e ambos suportam o mesmo conjunto de operações como getX e draw . Essas propriedades
são válidas porque os objetos são Pontos. No entanto, diferentes instâncias podem variar
em detalhes específicos, como os valores de suas coordenadas.
Para criar uma nova instância de uma classe, usamos uma operação especial
chamada construtor. Uma chamada para um construtor é uma expressão que cria um novo objeto.
A forma geral é a seguinte: <class-
name> (<param1> , <param2> , ... )
Aqui <class-name> é o nome da classe da qual queremos criar uma nova instância, por
exemplo, Circle ou Point. As expressões entre parênteses são quaisquer parâmetros
necessários para inicializar o objeto. O número e o tipo dos parâmetros dependem da
classe. Um Point requer dois valores numéricos, enquanto um GraphWin pode ser
construído sem nenhum parâmetro. Freqüentemente, um construtor é usado no lado direito
de uma instrução de atribuição e o objeto resultante é imediatamente atribuído a uma
variável no lado esquerdo que é então usada para manipular o objeto.

Para dar um exemplo concreto, vejamos o que acontece quando criamos um ponto
gráfico. Aqui está uma declaração do construtor do exemplo interativo acima:
Machine Translated by Google

92 Capítulo 4. Objetos e Gráficos

p = Ponto (50 , 60)

O construtor da classe Point requer dois parâmetros fornecendo as coordenadas xey para o
novo ponto. Esses valores são armazenados como variáveis de instância dentro do objeto.
Nesse caso, o Python cria uma instância de Point com um valor x de 50 e um valor y de 60.
O ponto resultante é então atribuído à variável p.

Um diagrama conceitual do resultado é mostrado na Figura 4.4. Observe que neste


diagrama, assim como em outros semelhantes, apenas os detalhes mais salientes são mostrados.
Os pontos também contêm outras informações, como sua cor e em qual janela (se houver)
eles são desenhados. A maioria dessas informações é definida com os valores padrão
quando o Ponto é criado.

p: Ponto '

x: I 50 I y: I

60 I

Figura 4.4: A variável p refere-se a um novo Ponto

Para realizar uma operação em um objeto, enviamos uma mensagem ao objeto. O


conjunto de mensagens às quais um objeto responde é chamado de métodos do objeto.
Você pode pensar em métodos como funções que vivem dentro do objeto. Um método é
invocado usando notação de ponto.

<objeto> . <nome do método> (<param1>, <param2> , ... )

O número e o tipo dos parâmetros são determinados pelo método que está sendo usado.
Alguns métodos não requerem nenhum parâmetro. Você pode encontrar vários exemplos de
invocação de método nos exemplos interativos acima.
Como exemplos de métodos sem parâmetros, considere estas duas expressões:

p.getX()
p.getY()

Os métodos getX e getY retornam os valores x e y de um ponto, respectivamente.


Métodos como esses às vezes são chamados de acessadores, porque nos permitem acessar
informações das variáveis de instância do objeto.
Machine Translated by Google

4.4. Usando objetos gráficos 93

Outros métodos alteram os valores das variáveis de instância de um objeto, alterando assim o
estado do objeto. Todos os objetos gráficos têm um método de movimento .
Aqui está uma especificação:

dx . , dy): Move o objeto dx unidades na direção x e dy unidades em que eles se movem (direção

Para mover o ponto p para as 10 unidades à direita, poderíamos usar esta declaração:

p.mover ( 10 , 0)

Isso altera a variável de instância x de p adicionando 10 unidades. Se o ponto estiver atualmente


desenhado em um GraphWin, o movimento também se encarregará de apagar a imagem antiga e
desenhá-la em sua nova posição. Os métodos que alteram o estado de um objeto às vezes são
chamados de modificadores.
O método move deve ser fornecido com dois parâmetros numéricos simples indicando a distância
para mover o objeto ao longo de cada dimensão. Alguns métodos requerem parâmetros que são
objetos complexos. Por exemplo, desenhar um círculo em um GraphWin envolve dois objetos. Vamos
examinar uma sequência de comandos que faz isso:

eire = Circle (Point ( 100 , 100) , 30)


win = GraphWin() circ .
draw(win)
A primeira linha cria um Circle com um centro localizado no Point (100, 100) e um raio de 30. Observe
que usamos o construtor Point para criar uma localização para o primeiro parâmetro do construtor
Circle . A segunda linha cria um GraphWin. Você vê o que está acontecendo na terceira linha? Esta é
uma solicitação para que o objeto Circle eire se desenhe no objeto GraphWin win. O efeito visível desta
declaração é um círculo no GraphWin centrado em (100, 100) e com um raio de 30. Nos bastidores,
muito mais está acontecendo.

Lembre-se, o método draw fica dentro do objeto eire . Usando informações sobre o centro e o raio
do círculo das variáveis de instância, o método draw emite uma sequência apropriada de comandos de
desenho de baixo nível (uma sequência de invocações de métodos) para o GraphWin. Uma imagem
conceitual das interações entre os objetos Point, Circle e GraphWin é mostrada na Figura 4.5.
Felizmente, geralmente não precisamos nos preocupar com esses tipos de detalhes; eles são todos
cuidados pelos objetos gráficos. Nós apenas criamos objetos, chamamos os métodos apropriados e
deixamos que eles façam o trabalho. Esse é o poder da programação orientada a objetos.
Machine Translated by Google

94 Capítulo 4. Objetos e Gráficos

.
c1rc: - Círculo

Ponto
centro: EU

EU
.

I raio: I 30 I
x: I 100 I
y: I 100 I
desenhar ( 1)

. EU

EU

.
EU

EU

I Comandos de desenho de baixo nível '

.
w1n: ... - Gráfico de vitória

.

Figura 4.5: Interações de objetos para desenhar um círculo

Há uma "pegadinha" sutil que você precisa ter em mente ao usar objetos. É possível que duas
variáveis diferentes se refiram exatamente ao mesmo objeto; as alterações feitas no objeto por meio
de uma variável também serão visíveis para a outra. Suponha, por exemplo, que estamos tentando
escrever uma sequência de código que desenha uma carinha sorridente. Queremos criar dois olhos
separados por 20 unidades. Aqui está uma sequência de código destinada a desenhar os olhos:

## Maneira incorreta de criar dois círculos .


leftEye = Circle (Point (80 50),setFill , ('yellow')
leftEye 5).
= leftEye setOutline
move (20 rightEye
('red') leftEye
. . rightEye

, 0)
A ideia básica é criar o olho esquerdo e depois copiá-lo para um olho direito, que é então movido por
20 unidades.
Isso não funciona. O problema aqui é que apenas um objeto Circle é criado. A atribuição

olho direito = olho esquerdo


Machine Translated by Google

4.4. Usando objetos gráficos 95

simplesmente faz rightEye se referir ao mesmo círculo que leftEye. A Figura 4.6
mostra a situação. Quando o círculo é movido na última linha de código, tanto
rightEye quanto leftEye se referem a ele em seu novo local no lado direito. Essa
situação em que duas variáveis se referem ao mesmo objeto é chamada de aliasing
e, às vezes, pode produzir resultados bastante inesperados.

olho esquerdo: Círculo


--"'

---

Ponto ""
centro: I
EU

EU

raio: I 10 I
x: eu I 80

anos: I 50 I

olho direito:
./

Figura 4.6: As variáveis leftEye e rightEye são aliases

Uma solução para este problema seria criar um círculo separado para cada olho:

## Uma maneira correta de criar dois .


círculos leftEye = Circle (Point, (80 , 5)setFill
('yellow')
50)
rightEye =leftEye
Circle .(Point
setOutline
( 100,('red')
50) setFill
leftEye .
rightEye .('yellow') rightEye .setOutline ('red')
, 5)

Isso certamente funcionará, mas é complicado. Tivemos que escrever código


duplicado para os dois olhos. Isso é fácil de fazer usando uma abordagem "recortar
e colar", mas não é muito elegante. Se decidirmos mudar a aparência dos olhos,
teremos que fazer as alterações em dois lugares.
A biblioteca gráfica oferece uma solução melhor; todos os objetos gráficos
suportam um método clone que faz uma cópia do objeto. Usando clone, podemos
resgatar a abordagem original:

## Maneira correta de criar dois círculos , usando clone .


leftEye = Circle (Point (80 50), setFill
, ('yellow')
leftEye 5).setOutline ('red')
leftEye .
Machine Translated by Google

96 Capítulo 4. Objetos e Gráficos

leftEye . 0) clone() # rightEye é uma cópia exata do left rightEye =


(20 rightEyemover
. ,

O uso estratégico da clonagem pode facilitar muito algumas tarefas gráficas.

14.51 Representação gráfica do valor futuro

Agora que você tem alguma idéia de como usar objetos de gráficos, estamos prontos para
experimentar uma programação gráfica real. Um dos usos mais importantes dos gráficos
é fornecer uma representação visual dos dados. Dizem que uma imagem vale mais que
mil palavras; é quase certamente melhor do que mil números. Praticamente qualquer
programa que manipula dados numéricos pode ser melhorado com um pouco de saída
gráfica. Você se lembra do programa do Capítulo 2 que calculava o valor futuro de um
investimento de dez anos? Vamos tentar criar um resumo gráfico.

Programar com gráficos requer um planejamento cuidadoso. Você provavelmente vai


querer lápis e papel à mão para desenhar alguns diagramas e riscar cálculos à medida
que avançamos. Como de costume, começamos considerando a especificação do que
exatamente o programa fará. . py tinha duas entradas: a quantidade de dinheiro para o
juros anualizada. Usando essas entradas,
programao programa
original futval
calculou
ser investido
a variação
e ado
taxa
principal
de
ano a ano por dez anos usando a fórmula principal = principal * (1 + abr). Em seguida,
imprimiu o valor final do principal. Na versão gráfica, a saída será um gráfico de barras de
dez anos onde a altura das barras sucessivas representa o valor do principal em anos
sucessivos.

Vamos usar um exemplo concreto para ilustração. Suponha que investimos $ 2.000 a
10% de juros. A Tabela 4.1 mostra o crescimento do investimento em um período de dez
anos. Nosso programa exibirá essas informações em um gráfico de barras. A Figura 4. 7
mostra os mesmos dados em forma gráfica. O gráfico contém onze barras. A primeira
barra mostra o valor original do principal. Para referência, vamos numerar essas barras de
acordo com o número de anos de juros acumulados, de 0 a 10.
Aqui está um esboço para o programa:

Imprimir uma introdução

Obter valor do principal e apr do usuário


Criar um GraphWin
Desenhe etiquetas de escala no lado esquerdo da janela

Desenhe a barra na posição 0 com altura correspondente ao principal


Machine Translated by Google

4.5. Representação gráfica do valor futuro 97

I anos valorizo I 0 $
2.000,00 1 $
2.200,00 2 $
2.420,00 3 $
2.662,00 4 $
2.928,20 5 $
3.221,02 6 $
3.542. 12 7 $
3.897,43 8 $
4.287,18 9 $
4.715,90 10 $
5.187,49

Tabela 4. 1: Tabela mostrando crescimento de $ 2.000 com juros de 10%

Para anos sucessivos de 1 a 10


Calcular principal = principal * (1 + abr)
Desenhe uma barra para este ano com uma altura correspondente ao principal
Aguarde o usuário pressionar Enter .

A pausa criada pelo último passo é necessária para manter a janela gráfica exibida para que
possamos interpretar os resultados. Sem essa pausa, o programa terminaria e o GraphWin
desapareceria com ele.
Embora esse design nos dê as pinceladas amplas para nosso algoritmo, existem alguns
detalhes muito importantes que foram encobertos. Devemos decidir exatamente qual será o
tamanho da janela gráfica e como posicionaremos os objetos que aparecem nesta janela. Por
exemplo, o que significa desenhar, digamos, uma barra para o ano cinco com altura correspondente
a $ 3.221,02?
Vamos começar com o tamanho do GraphWin. Lembre-se de que o tamanho de uma janela é
dado em termos do número de pixels em cada dimensão. As telas de computador também são
medidas em termos de pixels. O número de pixels ou resolução da tela é determinado pelo monitor
e placa gráfica do computador que você usa. A tela de resolução mais baixa que você provavelmente
encontrará em um computador pessoal hoje em dia é a chamada tela VGA estendida , com
1024x768 pixels.
A maioria das telas são consideravelmente maiores. Nossa janela padrão de 200 x 200 pixels
provavelmente parecerá um pouco pequena. Vamos fazer o GraphWin 320x240; que o tornará
cerca de 1/8 do tamanho de uma tela pequena.
Machine Translated by Google

98 Capítulo 4. Objetos e Gráficos

Figura 4. 7: Gráfico de barras mostrando crescimento de US$ 2.000 com juros de 1 Oo/o

Dada essa análise, podemos detalhar um pouco do nosso design. A terceira linha do
design agora deve ler:

Crie um GraphWin de 320 x 240 intitulado ''Gráfico de crescimento de investimento''

Você pode estar se perguntando como isso se traduzirá em código Python. Você já viu que o construtor
GraphWin permite que um parâmetro opcional especifique o título da janela. Você também pode fornecer
parâmetros de largura e altura para controlar o tamanho da janela. Assim, o comando para criar a janela de
saída será:

vitória = GraphWin(" Gráfico de Crescimento do Investimento", 320 , 240)

Em seguida, voltamos ao problema de imprimir etiquetas ao longo da borda esquerda de nossa janela.
Para simplificar o problema, vamos supor que o gráfico é sempre dimensionado para um máximo de $ 10.000
com os cinco rótulos "O.OK" a "10.0K", conforme mostrado na janela de exemplo. A questão é como os rótulos
devem ser desenhados? Vamos precisar de alguns objetos Text . Ao criar Texto, especificamos o ponto de
ancoragem (o ponto em que o texto está centralizado) e a string a ser usada como rótulo.

As sequências de rótulos são fáceis. Nosso rótulo mais longo tem cinco caracteres, e todos os rótulos
devem estar alinhados no lado direito de uma coluna, para que as strings mais curtas sejam preenchidas à
esquerda com espaços. A colocação das etiquetas é escolhida com um pouco
Machine Translated by Google

4.5. Representação gráfica do valor futuro 99

de cálculo e algumas tentativas e erros. Brincando com alguns exemplos interativos, parece que
uma string de comprimento cinco parece bem posicionada na direção horizontal, colocando o
centro a 20 pixels da borda esquerda. Isso deixa apenas um pouco de espaço em branco na
margem.
Na direção vertical, temos pouco mais de 200 pixels para trabalhar. Uma escala simples
seria ter 100 pixels representando $ 5.000. Isso significa que nossos cinco rótulos devem ser
espaçados em 50 pixels. Usar 200 pixels para o intervalo de 0 a 10.000 deixa 240 - 200 = 40
pixels para dividir entre as margens superior e inferior. Podemos querer deixar um pouco mais
de margem no topo para acomodar valores que cresçam além de US$ 10.000. Uma pequena
experimentação sugere que colocar o rótulo "O.OK" a 10 pixels da parte inferior (posição 230)
parece bom.
Elaborando nosso algoritmo para incluir esses detalhes, o único passo

Desenhe etiquetas de escala no lado esquerdo da janela

torna-se uma sequência de passos:

Desenhar rótulo II O. _ OK11 em (20 , 230)


Desenhar rótulo II 2 . 5K11 às (20 5 . , 180)
II
Desenhar rótulo 0K11 às (20 7 . 5K11 , 130)
II
Desenhar rótulo às (20 11 10 . 0K11 , 80)
Desenhar rótulo às (20 , 30)

O próximo passo no projeto original é desenhar a barra que corresponde ao valor inicial do
principal. É fácil ver onde o canto inferior esquerdo dessa barra deve estar. O valor de $ 0,0 está
localizado verticalmente no pixel 230 e os rótulos são centralizados a 20 pixels da borda esquerda.
Adicionar mais 20 pixels nos leva à borda direita dos rótulos. Assim, o canto inferior esquerdo da
barra Oth deve estar no local ( 40, 230).

Agora só precisamos descobrir onde o canto oposto (superior direito) da barra deve estar
para que possamos desenhar um retângulo apropriado. Na direção vertical, a altura da barra é
determinada pelo valor do principal.
Ao desenhar a escala, determinamos que 100 pixels equivalem a US$ 5.000. Isso significa que
temos 100/5000 = 0,02 pixels por dólar. Isso nos diz, por exemplo, que um principal de $ 2.000
deve produzir uma barra de altura 2.000(.02) = 40 pixels. Em geral, a posição y do canto superior
direito será dada por 230- (principal)(0,02). (Lembre-se que 230 é o ponto 0, e as coordenadas y
diminuem subindo.)

Qual deve ser a largura da barra? A janela tem 320 pixels de largura, mas 40 pixels são
consumidos pelos rótulos à esquerda. Isso nos deixa com 280 pixels para 11 barras:
Machine Translated by Google

100 Capítulo 4. Objetos e Gráficos

280/11 = 25,4545. Vamos apenas fazer com que cada barra tenha 25 pixels; isso nos dará um
pouco de margem no lado direito. Portanto, a borda direita da nossa primeira barra estará na
posição 40 + 25 = 65.
Agora podemos preencher os detalhes para desenhar a primeira barra em nosso algoritmo:

Desenhe um retângulo de (40, 230) a (65 , 230 - principal * 0,02)

Neste ponto, tomamos todas as principais decisões e cálculos necessários para resolver o
problema. Tudo o que resta é infiltrar esses detalhes no restante do algoritmo. A Figura 4.8 mostra
o layout geral da janela com algumas das dimensões que escolhemos.

olhar

7.Slt

240 s.ox

2,5X
50
O.OK -.

{315.230)
10 {40.230)
ÿ
{319.239)
0 eu 25
1 ..
320 ÿ

Figura 4.8: Posição dos elementos no gráfico de barras de valor futuro

Vamos descobrir onde o canto inferior esquerdo de cada barra será localizado. Escolhemos
uma largura de barra de 25, então a barra para cada ano sucessivo começará 25 pixels mais à
direita do que no ano anterior. Podemos usar uma variável ano para representar o número do ano
e calcular a coordenada x do canto inferior esquerdo como (ano)(25) + 40. (O +40 deixa espaço na
borda esquerda para os rótulos.) Claro , a coordenada deste ponto ainda é 230 (a parte inferior do
gráfico).
Para encontrar o canto superior direito de uma barra, adicionamos 25 (a largura da barra) ao
valor x do canto inferior esquerdo. O valor do canto superior direito é determinado a partir do valor
(atualizado) do principal exatamente como determinamos para a primeira barra. Aqui está o
algoritmo refinado:

para o ano que vai de um valor de 1 a 10:


Machine Translated by Google

4.5. Representação gráfica do valor futuro 101

Calcular principal = principal * (1 + abr)


Calcule xll = 25 * ano + 40 Calcule altura
= principal * 0,02 Desenhe um retângulo de (xll
230) a (xll+25 , , 230 - altura)

A variável xll representa x inferior esquerdo - o valor x do canto inferior esquerdo da barra.

Juntar tudo isso produz o algoritmo detalhado mostrado abaixo:

Imprima uma introdução


Obtenha o valor do principal e do apr do usuário
Crie um GraphWin de 320 x 240 intitulado ''Gráfico de crescimento do investimento''
Desenhe o "O.OK" em (20 230),
Desenhar rótulo " 2,5K"
rótulo em (20
180) 130) 80) 30) ,230) a
Desenhar rótulo " 5,0 K" em (20 , (65)
Desenhar rótulo " 7,5K" em (20 ,
Desenhar rótulo "10,0K" em (20 ,
Desenhe um retângulo de (40 , , 230 - principal * 0,02)
para o ano que vai de um valor de 1 até 10 :
Calcular principal = principal * (1 + abr)
Calcular xll = 25 * ano + 40
Desenhe um retângulo de (xll , 230) a (xll+25 , 230 - principal * 0,02)
Aguarde o usuário pressionar Enter

Uau! Isso deu muito trabalho, mas finalmente estamos prontos para traduzir esse
algoritmo em código Python real. A tradução é direta usando objetos da biblioteca de
gráficos. Aqui está o programa:

# futval_graph . py

da importação de gráficos *

def main() :
# Introdução
print( "Este programa traça o crescimento de um investimento de 10 anos . ")

# Obtém o principal e a taxa de juros


principal = float (input("Digite o principal inicial:")) apr = float(input("Digite a
taxa de juros anualizada:"))
Machine Translated by Google

102 Capítulo 4. Objetos e Gráficos

# Cria uma janela gráfica com rótulos na borda esquerda


win = GraphWin( " 240)
Gráfico de Crescimento de Investimento ", ,
320 vitórias . setBackground( "white ")
Texto (Ponto (20 230)
, , 'O. OK') . empatar (ganhar)
Texto (Ponto (20 180)
, , ' 2 . 5K'). empatar (ganhar)
Texto (Ponto (20 130)
, , '5,0K'). empatar (ganhar)
Texto (Ponto (20 80)
, 30) , ' 7 . 5K'). empatar (ganhar)
Texto (Ponto (20 , , '10. 0K'). empatar (ganhar)

# Desenha a barra para a altura inicial


do principal = principal * 0,02 bar =
Retângulo (Ponto (40 230) bar , Ponto (65, 230 de altura))
, . setFill
( "verde") bar . setWidth(2) bar .
draw(win)

# Desenha barras para anos


11):
sucessivos por ano no, intervalo (1
# calcula valor para o próximo ano
principal = principal * (1 + abr) # desenha
barra para este valor
xll = ano * 25 + 40 altura =
principal * 0,02 bar = Retângulo
(Ponto (xll bar . setFill ("verde") , 230) , Ponto (xll+25 , 230-altura))
bar.setWidth(2) bar . draw(win)

input("Pressione <Enter> para


sair") win. perto ()

a Principal()

Se você estudar este programa com cuidado, verá que adicionei vários recursos
para enfeitá-lo um pouco. Todos os objetos gráficos suportam métodos para
mudança de cor. Eu configurei a cor de fundo da janela para branco:

ganhar . setBackground("branco")
Machine Translated by Google

4.6. Escolhendo Coordenadas 103

Eu também mudei a cor do objeto bar . A linha a seguir pede que a barra pinte seu
interior de verde (porque é dinheiro, você sabe):

bar . setFill ("verde")

Você também pode alterar a cor do contorno de uma forma usando o método setOutline .
Nesse caso, optei por deixar o contorno no preto padrão para que as barras se destaquem
umas das outras. Para melhorar esse efeito, este código torna o contorno mais largo (dois
pixels em vez do padrão):

bar . setWidth(2)

Você também pode ter notado a economia de notação ao desenhar os rótulos.


Como nunca mudamos os rótulos, atribuí-los a uma variável é desnecessário. Podemos
apenas criar um objeto Text , dizer a ele para desenhar a si mesmo e pronto.
Aqui está um exemplo:

Texto (Ponto (20 , 230) , 'O. OK') . empatar (ganhar)

Finalmente, dê uma olhada no uso da variável year no loop:

para o ano no intervalo (1 , 11):

A expressão range (! dex , 11) produz uma sequência de ints 1-10. O laço em
variável ano percorre esta sequência em sucessivas iterações do loop. Assim, a primeira
vez no ano é 1, depois 2, depois 3, etc., até 10. O valor de ano é então usado para calcular
a posição adequada do canto inferior esquerdo de cada barra:

xll = ano * 25 + 40

Espero que você esteja começando a pegar o jeito da programação gráfica. É um pouco
cansativo, mas muito viciante.

14.61 Escolhendo Coordenadas

A maior parte do trabalho de projetar o programa futval_graph foi determinar as coordenadas


precisas onde as coisas seriam colocadas na tela.
A maioria dos problemas de programação gráfica requer algum tipo de transformação de
coordenadas para alterar os valores de um problema do mundo real para as coordenadas
da janela que são mapeadas na tela do computador. Em nosso exemplo, o domínio do problema
Machine Translated by Google

104 Capítulo 4. Objetos e Gráficos

pediu valores x representando o ano (0-10) andy valores representando quantias


monetárias ($0-$10.000). Tivemos que transformar esses valores para serem representados
em uma janela de 320 x 240. É bom trabalhar com um ou dois exemplos para ver como
essa transformação acontece, mas torna a programação tediosa.
A transformação de coordenadas é um componente integral e bem estudado da
computação gráfica. Não é preciso muito conhecimento matemático para ver que o
processo de transformação sempre segue o mesmo padrão geral. Tudo o que segue um
padrão pode ser feito automaticamente. Para evitar o problema de ter que converter
explicitamente entre sistemas de coordenadas, a biblioteca de gráficos fornece um
mecanismo simples para fazer isso por você. Ao criar um GraphWin , você pode especificar
um sistema de coordenadas para a janela usando o método setCoords . O método requer
quatro parâmetros especificando as coordenadas dos cantos inferior esquerdo e superior
direito, respectivamente. Você pode então usar este sistema de coordenadas para colocar
objetos gráficos na janela.
Para dar um exemplo simples, suponha que queremos apenas dividir a janela em
nove quadrados iguais, no estilo jogo da velha. Isso pode ser feito sem muitos problemas
usando a janela padrão de 200 x 200, mas exigiria um pouco de aritmética. O problema se
torna trivial se primeiro alterarmos as coordenadas da janela para correr de 0 a 3 em
ambas as dimensões:

# cria uma janela padrão de 200x200 win =


GraphWin( "Tic-Tac-Toe")

# define as coordenadas para ir de (0 , 0) no canto inferior esquerdo


# para , 3) no canto superior direito.
(3 vitórias . setCoords (O .O, 0.0, 3.0, 3.0)

# Desenha linhas verticais


Linha (Ponto ( 1 , 0) , Ponto , 3)) .draw(ganhar)
Linha (Ponto (2,0) , ( 1 Ponto (2,3)) .draw(win)

# Desenha linhas horizontais


Linha (Ponto (0,1 ) , Ponto (3,1 )) .draw(vitória)
Linha (Ponto (0,2) , Ponto (3,2)) .draw(win)

Outro benefício dessa abordagem é que o tamanho da janela pode ser alterado
simplesmente alterando as dimensões usadas quando a janela é criada (por exemplo , win
, 300) a).setCoords)
GraphWin( "Tic-Tac-Toe", 300 a janela (devido Como as mesmas coordenadas
os objetos span =
serão dimensionados
adequadamente para o novo
Machine Translated by Google

4.6. Escolhendo Coordenadas 105

tamanho da janela. O uso de coordenadas de janela "brutas" exigiria alterações nas definições
das linhas.
Podemos aplicar essa ideia para simplificar nosso programa gráfico de valor futuro.
Basicamente, queremos que nossa janela gráfica vá de 0 a 10 (representando anos) na
dimensão x e de 0 a 10.000 (representando dólares) em sua dimensão. Poderíamos criar
apenas uma janela como esta:

vitória = GraphWin(" Gráfico de crescimento do , 240)


investimento", 320 win.setCoords (O .O, 0.0, 10 .0, 10000 . 0)

Então, criar uma barra para quaisquer valores de ano e principal seria simples.
Cada barra começa em um determinado ano e uma linha de base de 0, e cresce para o
próximo ano e uma altura igual ao principal.

bar = Retângulo (Ponto (ano , 0) , Ponto (ano+1, principal))

Há um pequeno problema com este esquema. Você pode ver o que eu tenho para
começar? As onze barras preencherão toda a janela; não deixamos espaço para rótulos ou
margens nas bordas. Isso é facilmente corrigido expandindo ligeiramente as coordenadas da
janela. Como nossas barras começam em 0, podemos localizar os rótulos do lado esquerdo
em -1. Podemos adicionar um pouco de espaço em branco ao redor do gráfico expandindo as
coordenadas um pouco além daquelas necessárias para nosso gráfico. Um pouco de
experimentação leva a esta definição de janela:

vitória = GraphWin(" Gráfico de crescimento do investimento , 240)


", 320 . setCoords (-1 . 75,-200 , 1 1 .5, 10400) vitória

Aqui está o programa novamente, usando o sistema de coordenadas alternativo:

# futval_graph2 . py

da importação de gráficos *

def main() : #
Introdução
print( "Este programa traça o crescimento de um investimento de 10 anos . ")

# Obtém o principal e a taxa de juros


principal = float (input("Digite o principal inicial:")) apr = float(input("Digite a
taxa de juros anualizada:"))
Machine Translated by Google

106 Capítulo 4. Objetos e Gráficos

# Cria uma janela gráfica com rótulos na borda esquerda


Gráfico de crescimento do investimento ,
win = GraphWin( " 240)
", 320 vitórias . setBackground( "branco") vitória . setCoords
(-1 . 75,-200 , 1 1 .5, 10400)
Texto (Ponto (-1 'O, .0) , . draw(win)
OK')
,
Texto (Ponto (-1 2500) , ' 2 . 5K'). empatar (ganhar)
,
Texto (Ponto (-1 5000) , '5,0K'). empate (vitória) '
Texto (Ponto (-1 , 7500) , 7 . 5k'). empatar (ganhar)
Texto (Ponto (-1 , 10.000) , '10. 0K'). empatar (ganhar)

# Desenha a barra para a barra


principal inicial = Rectangle ,(Point
0) , Point
(O (! , principal))
bar . setFill ( "verde") bar . setWidth(2) bar . draw(win)

# Desenhe uma barra para cada ano


, 11): (!
subsequente por ano no intervalo
principal = principal * (1 + abr) bar =
0) , principal)) bar . setFill
Rectangle (Point (year , Point (year+1,
("verde") bar.setWidth(2) bar . draw(win)

input("Pressione <Enter> para sair.


") win. perto ()

a Principal()

Observe como os cálculos complicados de coordenadas foram eliminados. Esta


versão também facilita a alteração do tamanho do GraphWin. Alterar o tamanho
da janela para 640 x 480 produz um gráfico de barras maior, mas desenhado
corretamente. No programa original, todos os cálculos teriam que ser refeitos
para acomodar os novos fatores de escala na janela maior.
Obviamente, a segunda versão do nosso programa é muito mais fácil de
desenvolver e entender. Quando estiver fazendo programação gráfica, considere
a escolha de um sistema de coordenadas que tornará sua tarefa o mais simples
possível.
Machine Translated by Google

4.7. Gráficos interativos 107

14.71 Gráficos interativos


Interfaces gráficas podem ser usadas tanto para entrada quanto para saída. Em um ambiente
GUI, os usuários normalmente interagem com seus aplicativos clicando em botões, escolhendo
itens de menus e digitando informações em caixas de texto na tela.
Esses aplicativos usam uma técnica chamada programação orientada a eventos. Basicamente,
o programa desenha um conjunto de elementos de interface (geralmente chamados de
widgets) na tela e espera que o usuário faça algo.
Quando o usuário move o mouse, clica em um botão ou digita uma tecla no teclado, isso
gera um evento. Basicamente, um evento é um objeto que encapsula dados sobre o que
acabou de acontecer. O objeto de evento é então enviado para uma parte apropriada do
programa para ser processado. Por exemplo, um clique em um botão pode produzir um evento
de botão. Esse evento seria passado para o código de manipulação do botão, que executaria
a ação apropriada correspondente a esse botão.
A programação orientada a eventos pode ser complicada para programadores iniciantes,
pois é difícil descobrir "quem está no comando" a qualquer momento. O módulo gráfico oculta
os mecanismos subjacentes de manipulação de eventos e fornece algumas maneiras simples
de obter a entrada do usuário em um GraphWin.

14.7.11 Obtendo cliques do mouse

Podemos obter informações gráficas do usuário através do método getMouse da classe


GraphWin . Quando getMouse é invocado em um GraphWin, o programa pausa e espera que
o usuário clique com o mouse em algum lugar da janela gráfica.
O local onde o usuário clica é retornado ao programa como um Ponto. Aqui está um pouco de
código que relata as coordenadas de dez cliques sucessivos do mouse:

#clique. py
da importação de gráficos *

def main() : win


= GraphWin("Click Me ! ") for i in
range(10) : . getMouse() p = win
p.getX O , p.getY()
print( "Você
) clicou em :",

a Principal()

O valor retornado por getMouse() é um Point pronto. Podemos usá-lo como


Machine Translated by Google

108 Capítulo 4. Objetos e Gráficos

qualquer outro ponto usando acessores como obter X e obter Y ou outros métodos como
desenhar e mover.
Aqui está um exemplo de um programa interativo que permite ao usuário desenhar
um triângulo clicando em três pontos em uma janela gráfica. Este exemplo é totalmente
gráfico, fazendo uso de objetos Text como prompts. Nenhuma interação com uma
janela de texto Python é necessária. Se você estiver programando em um ambiente
Microsoft Windows, poderá nomear esse programa usando uma extensão . extensão
pyw . Então, quando o programa for executado, ele nem exibirá a janela do shell do Python.
#triângulo. pyw da
importação de gráficos *

def main() :
win = GraphWin("Desenha um Triângulo")
win . setCoords (O .O, 0.0 10 .0,
, mensagem
10 . 0) =
Texto (Ponto (5 0.5) , , "Clique em três pontos")
mensagem . empatar (ganhar)

# Pegue e desenhe três vértices do triângulo p1 = win .


getMouse() p1. empate(ganhar) p2 = ganhar. getMouse()
p2 . empate(ganhar) p3 = ganhar. getMouse() p3.
empatar (ganhar)

# Use o objeto Polygon para desenhar o triângulo


triângulo = Polygon (p1 , p2 ,p3) triângulo .
setFill("peachpuff") triângulo. setOutline ("ciano")
triângulo . empatar (ganhar)

# Aguarde outro clique para sair da


mensagem. setText ("Clique em qualquer lugar para
sair. ") win . getMouse()

a Principal()

O triângulo de três cliques ilustra alguns novos recursos do módulo gráfico. Não há
classe de triângulo; no entanto, existe uma classe geral Polygon
Machine Translated by Google

4.7. Gráficos interativos 109

que pode ser usado para qualquer forma fechada de vários lados. O construtor de Polygon
aceita qualquer número de pontos e cria um polígono usando segmentos de linha para
conectar os pontos na ordem fornecida e conectar o último ponto de volta ao primeiro. Um
triângulo é apenas um polígono de três lados. Uma vez que temos três pontos-pi, p2 e p3
--- criar o triângulo é um piscar de olhos:

triângulo = Polígono(p1, p2, p3)

Você também deve estudar como o objeto Text é usado para fornecer prompts. UMA
um único objeto de texto é criado e desenhado próximo ao início do programa:

mensagem = Texto (Ponto (5 , 0,5) , "Clique em três pontos")


mensagem . draw(win)

Para alterar o prompt, não precisamos criar um novo objeto Text ; podemos apenas alterar
o texto que é exibido. Isso é feito perto do final do programa com o método setText :

mensagem.setText("Clique em qualquer lugar para sair.")

Como você pode ver, o método getMouse do Graph Win fornece uma maneira simples
de interagir com o usuário em um programa orientado a gráficos.

14.7.21 Manipulando a Entrada Textual

No exemplo do triângulo, toda a entrada foi fornecida por meio de cliques do mouse.
Frequentemente, queremos permitir que o usuário interaja com uma janela gráfica por
meio do teclado. O objeto Graph Win fornece um método getKey () que funciona de
maneira muito semelhante ao método getMouse . Aqui está uma extensão do programa de
clique simples que permite ao usuário rotular posições em uma janela digitando uma única
tecla após cada clique do mouse:

#clickntype . py

da importação de gráficos *

def main() :
win = GraphWin("Clique e digite ", 400 para i in , 400)
range(10): . getMouse() pt = win . getKey() key
= win
Machine Translated by Google

1 10 Capítulo 4. Objetos e Gráficos

label = Texto (pt , chave)


label . empatar (ganhar)

a Principal()

Observe o que acontece no corpo do loop. Primeiro ele espera por um clique do
mouse, e o Point resultante é salvo como a variável p. Em seguida, o programa espera
que o usuário digite uma tecla no teclado. A tecla pressionada é retornada como uma
string e salva como a chave variável. Por exemplo, se o usuário pressionar g no teclado,
a tecla será a string 'g'. O Point e a string são então usados para criar um objeto de texto
(chamado label) que é desenhado na janela.
Você deve experimentar este programa para ter uma ideia do que o método getKey
faz. Em particular, veja quais strings são retornadas quando você digita algumas das
teclas mais estranhas, como <Shift>, <Ctrl> ou as teclas de movimento do cursor.
Embora o método getKey seja certamente útil, não é uma maneira muito prática
de obter uma string arbitrária de caracteres do usuário (por exemplo, um número ou
um nome). Felizmente, a biblioteca de gráficos fornece um objeto Entry que permite
ao usuário digitar a entrada diretamente em um GraphWin.
Um objeto Entry desenha uma caixa na tela que pode conter texto. Ele entende os
métodos setText e getText da mesma forma que o objeto Text . A diferença é que o
conteúdo de uma Entrada pode ser editado pelo usuário. Aqui está uma versão do
programa de conversão de temperatura do Capítulo 2 com uma interface gráfica do
usuário:

# convert_gui . pyw #
Programa para converter Celsius para Fahrenheit usando uma # interface
gráfica simples .

da importação de gráficos *

def main() :
win = GraphWin( "Celsius Converter" win . , 400 , 300)
setCoords (O .O, 0.0 , 3.0, 4.0)

# Desenha a interface Text


(Point(1,3) , Text (Point"Temperatura Celsius:"). empatar (ganhar)
( 1,1) , inputText = Entry"Temperatura Fahrenheit: "). empate (vitória) 5)
(Point (2 . 25, 3) inputText . setText ("O . ,
O")
Machine Translated by Google

4.7. Gráficos interativos 111

Entrada de texto .
draw(win) outputText = Text (Point (2.25,1) ", ")
outputText . botão draw(win) = Text (Point ( 1 .
5 ,2.0) , "Convert It ") . botão desenhar (ganhar)

Retângulo (Ponto ( 1,1.5), Ponto (2,2.5) ) . empatar (ganhar)

# espera por um clique do mouse


ganhar . getMouse()

# convert input
celsius = float (inputText . getText() ) fahrenheit
= 9.0/5 .0 * celsius + 32

# exibe a saída e altera o botão setText


setText ("Quit")(round(fahrenheit outputText . , 2))
botão .

# espera o click e sai do win


. getMouse()
ganhar . fechar()

a Principal()

Quando executado, isso produz uma janela com uma caixa de entrada para digitar uma
temperatura Celsius e um "botão" para fazer a conversão. O botão é apenas para mostrar.
Na verdade, o programa apenas pausa para um clique do mouse em qualquer lugar da janela.
A Figura 4.9 mostra a aparência da janela quando o programa é iniciado.
Inicialmente, a caixa de entrada de entrada é definida para conter o valor 0,0. O usuário
pode deletar este valor e digitar outra temperatura. O programa pausa até que o usuário clique
no mouse. Observe que o ponto em que o usuário clica nem é salvo; o método getMouse é
usado apenas para pausar o programa até que o usuário tenha a chance de inserir um valor
na caixa de entrada.
O programa então processa a entrada em quatro etapas. Primeiro, o texto na caixa de
entrada é convertido em um número (via float). Este número é então convertido em graus
Fahrenheit. Finalmente, o número resultante é exibido na área de texto de saída . Embora
fahrenheit seja um valor flutuante, o método setText o converte automaticamente em uma
string para que possa ser exibido na caixa de texto de saída.
Machine Translated by Google

1 12 Capítulo 4. Objetos e Gráficos

Figura 4.9: Tela inicial do conversor gráfico de temperatura

A Figura 4.10 mostra a aparência da janela depois que o usuário digitou uma entrada
e clicou com o mouse. Observe que a temperatura convertida aparece na área de saída e
o rótulo do botão mudou para "Sair" para mostrar que clicar novamente sairá do programa.
Este exemplo poderia ser muito mais bonito usando algumas das opções na biblioteca de
gráficos para alterar as cores, tamanhos e larguras de linha dos vários widgets. O código
do programa é deliberadamente espartano para ilustrar apenas os elementos essenciais
do design da GUI.
Embora as ferramentas básicas getMouse, getKey e Entry não forneçam um ambiente
GUI completo, veremos em capítulos posteriores como esses mecanismos simples podem
suportar interações surpreendentemente ricas.

14.81 Referência do Módulo Gráfico


Os exemplos neste capítulo abordaram a maioria dos elementos do módulo de gráficos.
Esta seção fornece uma referência completa aos objetos e funções fornecidos nos gráficos.
O conjunto de objetos e funções fornecidos por um módulo às vezes é chamado de
Interface de Programação de Aplicativos, ou API.
Programadores experientes estudam APIs para aprender sobre novas bibliotecas. Você
provavelmente deve ler esta seção uma vez para ver o que a biblioteca gráfica tem a oferecer.
Machine Translated by Google

4.8. Referência do Módulo Gráfico 1 13

Figura 4.10: Conversor gráfico de temperatura após a entrada do usuário

Depois disso, você provavelmente desejará consultar esta seção com frequência quando
estiver escrevendo seus próprios programas gráficos.
Um dos maiores obstáculos no aprendizado de uma API é se familiarizar com os vários
tipos de dados usados. Ao ler a referência, preste muita atenção aos tipos de parâmetros e
valores de retorno dos vários métodos. Por exemplo, ao criar um círculo, é essencial que o
primeiro parâmetro fornecido seja um objeto Point (para o centro) e o segundo parâmetro seja
um número (o raio). O uso de tipos incorretos às vezes gera uma mensagem de erro imediata,
mas outras vezes os problemas podem não surgir até mais tarde, por exemplo, quando um
objeto é desenhado. Os exemplos no final de cada descrição de método incorporam literais
Python para ilustrar os tipos de dados apropriados para parâmetros.

14.8.11 Objetos GraphWin


Um objeto GraphWin representa uma janela na tela onde as imagens gráficas podem ser
desenhadas. Um programa pode definir qualquer número de GraphWins. Um GraphWin
entende os seguintes métodos:

GraphWin(title , width, height) Constrói uma nova janela gráfica para desenhar na tela. Os
parâmetros são opcionais; o título padrão é "Gráfico-
Machine Translated by Google

1 14 Capítulo 4. Objetos e Gráficos

ics Window", e o tamanho padrão é 200 x 200 pixels.

Exemplo: win = GraphWin(" Crescimento do investimento", 640 , 480)

, y, color) Desenha o pixel em ( x, y) na janela. A cor é opcional; plot (x preto é o padrão.

Exemplo: vitória. enredo (35 , 128 , "azul ")

quaisquer transformações
, y, color) Desenha
de coordenadas
o pixel na
configuradas
posição "raw"
por (x,
setCoords.
y), ignorando plotPixel (x

Exemplo: vitória. plotPixel (35 "azul"), 128 ,

setBackground (color) Define o plano de fundo da janela para a cor fornecida. A cor de fundo
padrão depende do seu sistema. Consulte a Seção 4.8.5 para obter informações sobre
como especificar cores.
Exemplo: vitória. setBackground ("branco")

close () Fecha a janela na tela.

Exemplo: vitória . perto ()

getMouse () Pausa para o usuário clicar com o mouse na janela e retorna


onde o mouse foi clicado como um objeto Point .

Exemplo: clickPoint = win . getMouse()


checkMouse () Semelhante a getMouse, mas não pausa para um clique do usuário. Retorna o
último ponto em que o mouse foi clicado ou None2 se a janela não foi clicada desde a
chamada anterior para checkMouse ou getMouse. Isso é particularmente útil para controlar
loops de animação (consulte o Capítulo 8).

Exemplo: clickPoint = win . checkMouse()


Nota: clickPoint pode ser Nenhum.

getKey() Pausa para o usuário digitar uma tecla no teclado e retorna uma string
representando a tecla que foi pressionada.

Exemplo: keyString = win . getKey()


checkKey O Semelhante a getKey, mas não pausa para o usuário pressionar uma tecla.
Retorna a última tecla que foi pressionada ou " " se nenhuma tecla foi pressionada desde
a chamada anterior para checkKey ou get Key. Isto é particularmente útil para

2None é um objeto especial do Python frequentemente usado para indicar que uma variável não tem valor. Isso é
discutido no Capítulo 6.
Machine Translated by Google

4.8. Referência do Módulo Gráfico 1 15

controlando loops de animação simples (veja o Capítulo 8).


Exemplo: keyString = win . verificar chave()
Nota: keyString pode ser a string vazia ""

setCoords (xll , yll , Xur , yur) Define o sistema de coordenadas da janela.


O canto inferior esquerdo é (xll, yll) e o canto superior direito é (xur, yur).
Os objetos atualmente desenhados são redesenhados e o desenho subsequente é feito
em relação ao novo sistema de coordenadas (exceto para plotPixel).
Exemplo: vitória. setCoords (O , 0, 200 , 100)

14.8.21 Objetos Gráficos


O módulo fornece as seguintes classes de objetos desenháveis: Ponto, Linha, Círculo, Oval,
Retângulo, Polígono e Texto. Todos os objetos são criados inicialmente sem preenchimento
com um contorno preto. Todos os objetos gráficos suportam o seguinte conjunto genérico de
métodos:

setFill (color) Define o interior do objeto para a cor fornecida.


Exemplo: algumObjeto . setFill("vermelho")

setOut line (color) Define o contorno do objeto para a cor especificada.


Exemplo: algumObjeto . linha setOut ("amarelo")

setWidth(pixels) Define a largura do contorno do objeto para o número desejado de


pixels. (Não funciona para Ponto.)
Exemplo: some0bject . setWidth(3)

draw(aGraphWin) Desenha o objeto no GraphWin fornecido e retorna o objeto desenhado.

Exemplo: someObject.draw (someGraphWin)

undraw () Desenha o objeto de uma janela de desenho. Se o objeto não estiver desenhado no
momento, nenhuma ação será tomada.
Exemplo: algumObjeto. abrir()

move (dx,dy) Move o objeto dx unidades na direção x e dy unidades na direção y . Se o objeto


estiver desenhado no momento, a imagem será ajustada para a nova posição.

Exemplo: some0bject . mover ( 10, 15 . 5)


Machine Translated by Google

1 16 Capítulo 4. Objetos e Gráficos

clone () Retorna uma duplicata do objeto. Os clones são sempre criados em um estado
não desenhado. Fora isso, eles são idênticos ao objeto clonado.
Exemplo: objectCopy = someObject . clone ()

Métodos de ponto

Ponto (x , y) Constrói um ponto com as coordenadas dadas.


Exemplo: aPonto = Ponto (3 . 5, 8)

get X () Retorna a coordenada x de um ponto.


Exemplo: xValue = aPoint . getXO

getY() Retorna a coordenada de um ponto.


Exemplo: yValue = aPoint . getY O

Métodos de linha

Linha (ponto! , ponto2) Constrói um segmento de linha a partir do ponto! para ponto2.
Exemplo: aLinha = Linha (Point(1,3) , Ponto (7,4))

setArrow ( endString) Define o status da ponta de seta de uma linha. As setas podem ser
desenhadas no primeiro ponto, no último ponto ou em ambos. Os valores possíveis
de endString são "primeiro", "último",
é "nenhuma"
"ambos" e "nenhum". A configuração padrão
.
Exemplo: aLinha . setArrow("ambos")

get Center() Retorna um clone do ponto médio do segmento de linha.


Exemplo: midPoint = aLine . getCenter()

, getP2() Retorna um clone do endpoint correspondente do seg getP1()


mento.
Exemplo: startPoint = aLine . getP1()

Métodos de círculo

Círculo (centerPoint e , raio) Constrói um círculo com o ponto central dado


radius.
Exemplo: aCírculo = Círculo (Ponto (3 , 4) , 10 . 5)
Machine Translated by Google

4.8. Referência do Módulo Gráfico 1 17

get Center () Retorna um clone do ponto central do círculo.


Exemplo: centerPoint = aCircle . getCenter()

getRadi us () Retorna o raio do círculo.


Exemplo: radius = aCircle . getRadius()

getP1 () do
, getP2
círculo(). Retorna
Estes são
umpontos
clone do
de canto correspondente
opostos de um quadrado
da caixa delimitadora
que circunscreve
o círculo.

Exemplo: cornerPoint = aCircle . getP1()

Métodos Retângulos

(ponto 1 no ponto 1 e ,ponto2.


ponto2) Constrói um retângulo com cantos opostos Retângulo

Exemplo: aRetângulo = Retângulo (Ponto ( 1 , 3) , Ponto (4,7))

get Center () Retorna um clone do ponto central do retângulo.


Exemplo: centerPoint = aRectangle . getCenter()

estruturar ,ogetP2
retângulo.
() Retorna um clone do ponto correspondente usado para con getP1 ()

Exemplo: cornerPoint = aRectangle . getP1()

Métodos ovais

Oval (ponto 1, ponto2) Constrói uma oval na caixa delimitadora determinada pelo ponto
1 e ponto2.
Exemplo: anOval = Oval (Point(1,2) , Point (3,4))

get Center () Retorna um clone do ponto no centro da oval.


Exemplo: centerPoint = anOval . getCenter()

estrutura oval
, getP2
getP1
0 Retorna
0. um clone do ponto correspondente usado para construir a

Exemplo: cornerPoint = an0val . getP1()


Machine Translated by Google

1 18 Capítulo 4. Objetos e Gráficos

Métodos de polígono

Polígono (ponto 1, ponto2, ponto3, . . . ) Constrói um polígono com os pontos


dados como vértices. Também aceita um único parâmetro que é uma lista dos
vértices.

Exemplo: aPolygon - Polygon(Point(1,2) , Ponto (3,4), Ponto (5,6))


Exemplo: aPolygon - Polygon( [Point(1,2) , Ponto (3,4), Ponto (5,6) ] )

getPoints () Retorna uma lista contendo clones dos pontos usados para construir o
polígono.
Exemplo: pointList = aPolygon . Ganhe pontos ()

Métodos de texto

Texto (anchorPoint , text String) Constrói um objeto de texto que exibe o texto String
centralizado em anchorPoint. O texto é exibido horizontalmente.
, 4) ,
Exemplo: mensagem = Texto (Ponto (3 "Olá!")

setText (string) Define o texto do objeto como string.


Exemplo: mensagem. set Text ("Adeus!")

get Text() Retorna a string atual.


Exemplo: msgString = mensagem . getText()

getAnchor() Retorna um clone do ponto de ancoragem.


Exemplo: centerPoint = mensagem . getÂncora()

setFace (família) Altera a face da fonte para a família especificada. Os valores possíveis
são "helvetica", "courier", "times roman" e "arial".
Exemplo: mensagem. setFace(" arial")

set Size (ponto) Altera o tamanho da fonte para o tamanho de ponto fornecido . Tamanhos de 5
a 36 pontos são legais.
Exemplo: mensagem. definirTamanho ( 18)

setStyle (estilo) Altera a fonte para o estilo fornecido. Os valores possíveis são: "normal",
"negrito", " itálico ", e "negrito itálico".
Exemplo: mensagem. setStyle ("negrito")
Machine Translated by Google

4.8. Referência do Módulo Gráfico 1 19

setTextColor (color) Define a cor do texto para colorir. Nota: setFill tem
o mesmo efeito.

Exemplo: mensagem. setTextColor ("rosa")

14.8.31 Objetos de Entrada

Objetos do tipo Entry são exibidos como caixas de entrada de texto que podem ser
editadas pelo usuário do programa. Os objetos de entrada suportam os métodos gráficos
genéricos move 0, draw (graphwin), undraw 0, setFill (color) e clone 0 . Os

métodos específicos de entrada são fornecidos abaixo.

Entry (centerPoint width), Constrói uma entrada com o ponto central e a largura fornecidos.
A largura é especificada em número de caracteres de texto que podem ser exibidos.

Exemplo: inputBox = Entry(Point (3 , 4) , 5)

getAnchor () Retorna um clone do ponto onde a caixa de entrada está centralizada.


Exemplo: centerPoint = inputBox . getÂncora()

get Text() Retorna a string de texto que está atualmente na caixa de entrada.
Exemplo: inputStr = inputBox . getText()

set Text (string) Define o texto na caixa de entrada para a string fornecida.
Exemplo: caixa de entrada. setText ("32. 0")

setFace (família) Altera a face da fonte para a família especificada. Os valores possíveis
são "helvetica", "courier", "times roman" e "arial".
Exemplo: caixa de entrada. setFace( "correio")

set Size (ponto) Altera o tamanho da fonte para o tamanho de ponto fornecido . Tamanhos de 5
a 36 pontos são legais.
Exemplo: caixa de entrada. definir Tamanho (12)

setStyle (estilo) Altera a fonte para o estilo fornecido. Os valores possíveis são: "normal",
"negrito", "itálico" e "negrito itálico".
Exemplo: caixa de entrada. setStyle ("itálico")

setTextColor (color) Define a cor do texto para colorir.


Exemplo: caixa de entrada. setTextColor ("verde")
Machine Translated by Google

120 Capítulo 4. Objetos e Gráficos

14.8.41 Exibindo Imagens


O módulo gráfico também oferece suporte mínimo para exibição e manipulação de imagens em
um GraphWin. A maioria das plataformas suportará pelo menos imagens PPM e GIF. A exibição
é feita com um objeto Image . As imagens suportam os métodos genéricos move ( dx , dy), draw
(graphwin), undraw () e clone ( ) . Os métodos específicos de imagem são fornecidos abaixo.

fornecida ( arquivo ponto ,denome do arquivo)


ancoragem, Constróino
centralizado uma imagem
ponto do conteúdo
de ancoragem da imagem
fornecido. Também
pode ser chamado com parâmetros de largura e altura em vez do nome do arquivo. Neste
caso, uma imagem em branco (transparente) é criada da largura e altura fornecidas (em
pixels).

.gif"), "flor
Exemplo: flowerimage = Image (Point ( 100, 100)
Exemplo: imagem em branco = Imagem (320 , 240)

getAnchor () Retorna um clone do ponto onde a imagem está centralizada.

Exemplo: centerPoint = flowerimage . getÂncora()

getWidthO Retorna a largura da imagem.

Exemplo: widthinPixels = flowerimage . getLargura()


getHeight 0 Retorna a altura da imagem.

Exemplo: heightinPixels = flowerimage . getAltura()


posição (x , y) ., y) Retorna uma lista [red, green, blue] dos valores RGB do getPixel (x pixel na
Cada valor é um número no intervalo de 0-255 que indica
a intensidade da cor RGB correspondente. Esses números podem ser transformados em
uma string de cores usando a função color _rgb (consulte a próxima seção).

Observe que a posição do pixel é relativa à própria imagem, não à janela


onde a imagem pode ser desenhada. O canto superior esquerdo da
, 0).pixel ( 0 Exemplo: red, green, blue = flowerimage .
imagem é sempre
getPixel (32 , 18)

Nota: Esta é uma


, y,operação
color) Define
lenta.
o pixel na posição (x , y) para a cor especificada. setPixel (x

Exemplo: imagem de flor. setPixel (32 , 18 , "azul ")

save (nome do arquivo) Salva a imagem em um arquivo. O tipo do arquivo resultante (por
exemplo, GIF ou PPM) é determinado pela extensão do nome do arquivo.
Exemplo: imagem de flor . save("mypic.ppm")
Machine Translated by Google

4.8. Referência do Módulo Gráfico 121

14.8.51 Gerando Cores


As cores são indicadas por strings. A maioria das cores normais, como "vermelho", "roxo", "verde",
"ciano", etc., devem estar disponíveis. Muitas cores vêm em vários tons, como "red1" "red2" "red3"
"red4" , que são tons cada vez mais escuros de vermelho. Para obter uma lista completa, procure
'
nomes de cores Xl l na web.
' ' '
O módulo gráfico também oferece uma função para misturar suas próprias cores numericamente.
A função color_rgb (vermelho, verde, azul) retornará uma string representando uma cor que é uma
mistura das intensidades de vermelho, verde e azul especificadas. Estes devem ser inteiros no
intervalo de 0 a 255. Assim , a cor _rgb (255, 0, 0) é um vermelho brilhante, enquanto a (130,
cor _rgb
0, 130)
é um magenta médio.
Exemplo: aCircle . setFill (cor _rgb ( 130 , 0, 130) )

14.8.61 Controlando atualizações de exibição (avançado)


Normalmente, a exibição visual de um GraphWin é atualizada sempre que o estado visível de
qualquer objeto gráfico é alterado de alguma forma. No entanto, em algumas circunstâncias, por
exemplo, ao usar a biblioteca de gráficos dentro de alguns shells interativos, pode ser necessário
forçar a atualização da janela para que as alterações sejam vistas.
A função update () é fornecida para fazer isso.

update () Faz com que quaisquer operações gráficas pendentes sejam executadas e os resultados
exibidos.

Por motivos de eficiência, às vezes é desejável desativar a atualização automática de uma


janela toda vez que um dos objetos for alterado. Por exemplo, em uma animação, você pode querer
alterar a aparência de vários objetos antes de mostrar o próximo "quadro" da animação. O construtor
GraphWin inclui um parâmetro extra especial chamado autoflush que controla essa atualização
automática. Por padrão, o autoflush está ativado quando uma janela é criada. Para desativá-lo, o
parâmetro autoflush deve ser definido como False, assim:

win = GraphWin("Minha Animação" , 400 , 400 , autoflush=Falso)


Agora as alterações nos objetos em win só serão mostradas quando o sistema gráfico estiver com
algum tempo ocioso ou quando as alterações forem forçadas por uma chamada para update() .
O método update() também usa um parâmetro opcional que especifica a taxa máxima (por
segundo) na qual as atualizações podem ocorrer. Isso é útil para controlar a velocidade das
animações de forma independente de hardware. Por exemplo, colocar o comando update (30) na
parte inferior de um loop garante
Machine Translated by Google

122 Capítulo 4. Objetos e Gráficos

que o loop irá "girar" no máximo 30 vezes por segundo. O comando de atualização inserirá uma pausa
apropriada a cada vez para manter uma taxa relativamente constante. Obviamente, a limitação de taxa
só funcionará quando o próprio corpo do loop for executado em menos de 1/30 de segundo.

Exemplo: 1000 quadros a 30 quadros por segundo

win = GraphWin("Update Example ", 320 , 200 , autoflush=Falso)


for i in range ( 1000) : # <drawing
command for ith frame> update (30)

14.91 Resumo do Capítulo

Este capítulo introduziu computação gráfica e programação baseada em objetos. Aqui está um resumo
de alguns dos conceitos importantes:

• Um objeto é uma entidade computacional que combina dados e operações.


Objetos sabem coisas e podem fazer coisas. Os dados de um objeto são armazenados em
variáveis de instância e suas operações são chamadas de métodos.

• Todo objeto é uma instância de alguma classe. É a classe que determina quais métodos um
objeto terá. Uma instância é criada chamando um método construtor.

• Os atributos de um objeto são acessados via notação de ponto. Geralmente os cálculos


com objetos são executados chamando os métodos de um objeto. Os métodos de
acesso retornam informações sobre as variáveis de instância de um objeto.
Os métodos mutantes alteram o(s) valor(es) das variáveis de instância.

• O módulo gráfico fornecido com este livro fornece várias classes úteis para programação gráfica.
Um GraphWin é um objeto que representa uma janela na tela para exibir gráficos. Vários objetos
gráficos como Ponto, Linha, Círculo, Retângulo, Oval, Polígono e Texto podem ser desenhados
em um GraphWin. Os usuários podem interagir com um GraphWin clicando com o mouse ou
digitando em uma caixa de entrada .

• Uma consideração importante na programação gráfica é a escolha de um sistema de


coordenadas apropriado. A biblioteca de gráficos fornece uma maneira de automatizar
certas transformações de coordenadas.
Machine Translated by Google

4. 10. Exercícios 123

• A situação em que duas variáveis se referem ao mesmo objeto é chamada de alias. Às vezes,
o alias pode causar resultados inesperados. O uso do método clone na biblioteca de gráficos
pode ajudar a evitar essas situações.

14.10 I Exercícios
Perguntas de revisão

Verdadeiro falso

1. Usando gráficos. py permite que gráficos sejam desenhados em uma janela de shell do Python.

2. Tradicionalmente, o canto superior esquerdo de uma janela gráfica tem coordenadas


(0,0).

3. Um único ponto em uma tela gráfica é chamado de pixel.

4. Uma função que cria uma nova instância de uma classe é chamada de acessador.

5. As variáveis de instância são usadas para armazenar dados dentro de um objeto.

6. A declaração minhaForma . mover ( 10 , 20) move myShape para o ponto (1 0,20).

7. O alias ocorre quando duas variáveis se referem ao mesmo objeto.

8. O método de cópia é fornecido para fazer uma cópia de um objeto gráfico.

9. Uma janela gráfica sempre tem o título "Janela gráfica".

10. O método na biblioteca de gráficos usado para obter um clique do mouse é read.Mouse.

Múltipla escolha

1. Um método que retorna o valor da variável de instância de um objeto é chamado


a(n)
a) modificador b) função c) construtor d) acessador

2. Um método que altera o estado de um objeto é chamado de a(n) a) estator


b) mutador c) construtor d) changor

3. Qual classe gráfica seria melhor para desenhar um quadrado? a)


Quadrado b) Polígono c) Linha d) Retângulo
Machine Translated by Google

124 Capítulo 4. Objetos e Gráficos

4. Qual comando definiria as coordenadas de vitória para ir de (0,0) no canto inferior


esquerdo para (10, 10) no canto superior direito? a) vencer. setcoords (Ponto (O,O) ,
10) ) b) vitória . setcoords((O,O) , ( 10,10)Ponto (10 ., setcoords (O
) c) vitória (Ponto
10) ,( 0,
1010 d) vitória .

,
, 10) , Ponto(O,O))

5. Que expressão criaria uma linha de (2,3) a (4,5)? a) Linha (2 , 3, 4,


5) b) Linha ( (4,5)
(2 5) )) c) Linha (2 , 4, 3, 5) d) Linha (Ponto (2,3) , Ponto
, 3) , (4 ,

6. Qual comando seria usado para desenhar a forma do objeto gráfico na janela de
gráficos ? a) vencer. desenhar (forma) b) ganhar c) forma . empate ()
. mostrar (forma)
d) forma . empatar (ganhar)

7. Qual dos seguintes calcula a distância horizontal entre os pontos


p1 e p2?
a) abs (p1-p2)
b) p2. obter X () - p 1 . get
X() c) abs (p1 . getY O - p2 .
getY() ) d) get
absX()
(p 1) . get X() - p2 .

8. Que tipo de objeto pode ser usado para obter entrada de texto em uma janela gráfica?
a) Texto b) Entrada c) Entrada d) Teclado

9. Uma interface de usuário organizada em torno de elementos visuais e ações do usuário é


chamado
a(n) a) GUI b) aplicativo c) windower d) API

10. Qual é a cor _rgb ( 0, 255 a) amarelo , 255) ?


b) ciano c) magenta d) laranja

Discussão

1. Escolha um exemplo de um objeto interessante do mundo real e descreva-o como um


objeto de programação listando seus dados (atributos, o que ele "sabe") e seus métodos
(comportamentos, o que ele pode "fazer").
Machine Translated by Google

4. 10. Exercícios 125

2. Descreva com suas próprias palavras o objeto produzido por cada uma das
seguintes operações do módulo gráfico. Seja o mais preciso possível. Certifique-
se de mencionar coisas como tamanho, posição e aparência dos vários objetos.
Você pode incluir um esboço se isso ajudar.

a) Ponto ( 130 b) , 130)


c = Círculo (Ponto (30 c . setFill, 40) , 25)
("azul") c . setOutline
("vermelho")
c) r = Retângulo (Ponto (20,20) , Ponto (40,40) ) r . setFill
(color_rgb (0,255 , 150) ) r . setWidth(3)

d) 1 = Linha (Ponto ( 100 , 100) , Ponto (100 , 200))


l. set0utline ("red4") l .
setArrow('primeiro')
e) Oval (Point (50 f) , 50) , Ponto (60 , 100))
shape = Polygon(Point (5 shape . , 5) , Ponto (10 , 10) , Ponto (5 , 10) , Ponto (10 , 5))
setFill ("laranja")) 100) t .
g) t = Texto (Ponto ( 100 , , "Olá Mundo ! ")
setFace (" courier") t . setSize
( 16) t . setStyle ( '' italic'')

3. Descreva o que acontece quando o seguinte programa gráfico interativo


corre:

da importação de gráficos *

def main() :
win = GraphWin()
shape = Circle (Point (50 , 50) , 20)
shape . setOutline ("red")
shape . setFill ("red")
shape . draw(win) for i in
range ( 10): p = win .
getMouse() c = forma .
getCenter() dx = p.getX()
- c.getX()
Machine Translated by Google

126 Capítulo 4. Objetos e Gráficos

dy = p.getY() - c.getY()
perto ()move (dx,dy) forma .
win .
principal()

Exercícios de programação

1. Altere o programa da última pergunta da discussão das seguintes maneiras:

(a) Faça com que desenhe quadrados em vez de círculos.

(b) Faça com que cada clique sucessivo desenhe um quadrado adicional na tela
(em vez de mover o existente).

(c) Imprima uma mensagem na janela "Clique novamente para sair" após o loop e aguarde um
clique final antes de fechar a janela.

2. Um alvo de tiro com arco consiste em um círculo central de amarelo cercado por anéis concêntricos
de vermelho, azul, preto e branco. Cada anel tem a mesma largura, que é igual ao raio do círculo
amarelo. Escreva um programa que desenhe tal alvo. Dica: Objetos desenhados posteriormente
aparecerão em cima de objetos desenhados anteriormente.

3. Escreva um programa que desenhe algum tipo de rosto.

4. Escreva um programa que desenhe uma cena de inverno com uma árvore de Natal e um
boneco de neve.

5. Escreva um programa que tire 5 dados na tela representando uma sequência (1, 2, 3, 4, 5 ou 2, 3,
4, 5, 6).

6. Modifique o programa gráfico de valor futuro para que a entrada (principal e APR) também seja feita
de forma gráfica usando objetos Entry .
Machine Translated by Google

4. 10. Exercícios 127

7. Intersecção do Círculo.

Escreva um programa que calcule a interseção de um círculo com um hori


linha zontal e exibe as informações textualmente e graficamente.

Entrada: Raio do círculo e interceptação da linha.

Saída: Desenhe um círculo centrado em (0, 0) com o raio dado em uma janela com coordenadas
que vão de -10,-10 a 10,10.
Desenhe uma linha horizontal na janela com a interseção y fornecida.
Desenhe os dois pontos de interseção em vermelho.
Imprima os valores de x dos pontos de interseção.

Fórmula: x = ±y'r 2 2e

8. Informações do Segmento de Linha.

Este programa permite ao usuário desenhar um segmento de linha e então exibir


algumas informações gráficas e textuais sobre o segmento de linha.

Entrada: Dois cliques do mouse para os pontos finais do segmento de linha.

Saída: Desenhe o ponto médio do segmento em ciano.


Desenhe a linha.
Imprima o comprimento e a inclinação da linha.

Fórmulas: dx = x2 - x1 dy
= Y2 - Yl
inclinação = dy /
dx comprimento = J dx2 + dy2

9. Informações do retângulo.

Este programa exibe informações sobre um retângulo desenhado pelo usuário.

Entrada: Dois cliques do mouse para os cantos opostos de um retângulo.

Saída: Desenhe o retângulo.


Imprima o perímetro e a área do retângulo. área =

Fórmulas: (comprimento)(largura) perímetro =


2(comprimento + largura)
Machine Translated by Google

128 Capítulo 4. Objetos e Gráficos

10. Informações do Triângulo.

Igual ao problema anterior, mas com três cliques para os vértices de um triângulo.

Fórmulas: Para o perímetro, veja o comprimento do problema do segmento de linha.


área = Js(s - a) (s - b)(s - c) onde a, b e c são os comprimentos
dos lados e s = a+ÿ+c.
1 1. Casa de cinco cliques.

Você deve escrever um programa que permita ao usuário desenhar uma casa
simples usando cinco cliques do mouse. Os dois primeiros cliques serão os cantos
opostos da estrutura retangular da casa. O terceiro clique indicará o centro da borda
superior de uma porta retangular. A porta deve ter uma largura total que seja ÿ da largura
da estrutura da casa. As laterais da porta devem se estender dos cantos da parte superior
até a parte inferior da moldura. O quarto clique indicará o centro de uma janela quadrada.
A janela tem metade da largura da porta. O último clique indicará o pico do telhado.

As bordas do telhado se estenderão do ponto no pico até os cantos da borda superior da


estrutura da casa.

3 [±]

Você também pode gostar