Programas Guiados pelo Utilizador (Event driven)

Até agora temos visto programas de batch. Lembra-te que os programas podem ser batch, que são programas que iniciam, executam uma determinada tarefa e depois param. Ou então os programas podem ser event driven, guiados por eventos, por outras palavras, são programas que iniciam, esperam pela chegada de eventos, e só encerram quando recebem uma ordem para tal. Mas como é que criamos um programa desses? Bem vamos analisar esta questão de duas maneiras, primeiro, vamos criar um ambiente para correr esses programas, e depois vamos criar um, ainda que simples, um GUI que irá usar o sistema operativo para gerar eventos.

Simulando um loop de eventos

Todo o programa Guiado por eventos há-de ter um loop algures, que recebe e processa os eventos. Os eventos podem ser gerados pelo sistema operativo, como acontece com virtualmente os programas com GUI, por vezes o que acontece é o próprio programa ir a procura de eventos, como é o caso de de programas das câmaras de vídeo.

Nós vamos criar um programa que irá procurar um tipo de evento em particular - entrada de dados através do teclado - e vamos processar todas as entradas, até que um evento determine o fim do programa. Que no nosso caso será quando for premida a tecla do espaço. Nós vamos processar os dados recebidos de uma forma muito semelhante ao que o "bloco de notas faria"- só que com a lógica oposta, ou seja em vez de imprimir um caracter, vamos imprimir o seu equivalente em código ASCII. Para criar este programa vamos usar o BASIC, porque tem uma função muito a "jeito" para este programa, o INKEY$.

Primeiro vamos criar o body do programa, que irá consistir do no loop que começa o programa e que depois chama as subroutines para lidar com os dados recolhidos.


' Declarar as subroutines que irão lidar com os eventos
DECLARE SUB dokeyevent (keypress AS STRING)
DECLARE SUB doquitevent (keypress AS STRING)

' primeiro limpamos o ecrã e logo a seguir indicamos ao utilizador de como
' proceder em caso qeu queira sair do programa
CLS
PRINT "carregar no space para sair..."
PRINT

' agora crias um loop eterno
WHILE 1
        ky$ = INKEY$
        length = LEN(ky$)
        IF length <> 0 THEN
        ' envia os eventos para as funções que lidam com eventos
            IF ky$ <> " " THEN
                CALL doKeyEvent(ky$)
            ELSE 
                CALL doQuitEvent(ky$)
            END IF
        END IF
WEND

Repara na forma como os dados que não são do interesse do main body, são tratados, eles são simplesmente direccionados para uma das subroutines para que aí sejam processados. Este tipo de independência entre a recolha de dados e o processamento dos mesmos é a chave de todos os programas guiados por eventos.

Agora podemos criar as subroutines que irão processar os dados. A primeira há-de ser doKeyEvent, que simplesmente irá imprimir o valor da tecla premida em ASCII:

SUB doKeyEvent (keypress AS STRING)
    ' apenas para as teclas válidas
    length = LEN(keypress)
    IF length = 1 THEN 'ASCII
       PRINT ASC(keypress)
    ELSE
       IF length = 2 THEN 
          
          PRINT ASC(MID$(keypress, 2, 1))
       END IF
    END IF
END SUB

The doQuitEvent é trivial pois serve para por um STOPs no programa!

SUB doQuitEvent (keypress AS STRING)
    STOP
END SUB

Se estivéssemos a criar este programa, para mais tarde ser utilizado em vários outros projectos, provavelmente teríamos que incluir uma função de inicialização e uma outra função que faria a limpeza no final do programa, mas por forma a deixar que o programador definisse os parâmetros desses loop. Agora vamos fazer o mesmo programa em Python, e ao fazermos isso, vamos explorar em pouco o Tkinter.

Um programa com GUI

Para este exercício vamos utilizar as ferramentas do Tkinter. Que originalmente foi concebido para para ser uma extensão do Tcl, mas agora já esta disponível para o Python e para o Perl. A versão Tk par o Python, é uma framework orientada a objectos, e que na minha opinião é consideravelmente mais fácil de compreender e trabalhar do que a versão original. Mas não vou dar muita atenção aos aspectos do GUI, mas sim focar mais a minha atenção no estilo da programação - e para isso vamos usar o Tkinter para criar o main body e deixar o programador criar o GUI inicial e depois processa-mos os dados a medida que eles vão chegando.

Neste exemplo vamos criar uma aplicação que será o KeysAPP que irá criar um GUI usando o método do __init__ e depois quando a tecla do espaço é carregada ele irá enviar esse evento para uma outra class que será o doQuitEvent que estará definido dentro da class keysApp.

A interface em si não será mais num widget que irá permitir a entrada de texto e por default irá fazer um echo desses mesmos caracteres no ecrã.

Criação de uma aplicação que se baseia em ser uma class, é uma pratica comum, quando se fala em programação orientada a objectos porque existe uma enorme semelhança entre o acto de enviar dados para uma aplicação e o enviar de mensagens para um objecto. Os dois conceitos carregam muitas semelhanças entre si.

O código da aplicação será assim:


# Usa from X import * a preceder tudo
from Tkinter import *

# criar uma aplicação que define o GUI e os metetodos 
# para lidar com os eventos
class KeysApp(Frame):
    def __init__(self):
        Frame.__init__(self)
        self.txtBox = Text(self)
        self.txtBox.bind("", self.doQuitEvent)
        self.txtBox.pack()
        self.pack()

    def doQuitEvent(self,event):
        import sys
        sys.exit()
        

# agora crias uma instance da class por forma a que possas por o loop a funcionar
myApp = KeysApp()
myApp.mainloop()

È claro qu no mesmo programa que fizemos em BASIC, nós em vez de vermos o resultado em números alfanuméricos como vez aqui, vemos o o equivalente em código ASCII. Mas não há nada que nos impeça de fazer o mesmo, para isso basta adicionar esta pequena linha ao método __init__:

self.txtBox.bind("< Key >", self.doKeyEvent)

Nota 1: os valores aqui são guardados no Keycode, mas para descobrir isso eu tive que ir a procura no código to Tkinter. Lembra-te que a curiosidade é um dos factores fundamentais para te tornares num bom programador.

Nota 2: return "break" é um sinal mágico para dizer ao Tkinter para não invocar o método normal para lidar com os eventos. Sem esta linha o que iria parecer como resposta seria código ASCII seguido pelo caracter que tivéssemos digitado, o que não é o nosso objectivo neste caso.

E pronto por agora já chega, isto não é suposto ser um tutorial acerca do Tkinter, vê a pagina das referências para veres uns bons links caso este assunto seja do teu interesse. Contudo ainda havemos de voltar ao Tkinter no estudo que iremos fazer mais a frente.


Anterior Próxima Índice
 

Em caso que tenhas alguma dúvida ou queiras comentar esta página envia-me um e-mail para: babyboy@oninet.pt