quinta-feira, 14 de abril de 2011

Um pouco mais sobre eventos

Uma "quase" calculadora
      O exemplo do post anterior retirado do site zetcode onde é montado o "esqueleto" de uma calculadora não faz nada além de nos dar uma idéia de como trabalhar com wxGridSizer. Que tal implementarmos um método para detectar qual botão foi clicado e o que fazer dependendo de qual botão foi clicado? Isso mesmo!! UM método só para todos os botões!
    Para isso vamos atribuir um ID diferente para cada botão e utilizar o método Connect para conectar todos eles ao nosso método OnClick(). O nosso método OnClick() receberá como parâmetro uma referência para um objeto do tipo wxCommandEvent que descende de wxEvent. Este objeto tem um método chamado GetId() que retorna o ID do objeto que originou o evento e é através deste ID que identificamos qual botão foi clicado.
    Abaixo seguem as modificações no código do esqueleto da calculadora que vimos no post anterior.
    No arquivo gridsizer.h vamos declarar um objeto do tipo wxString (veremos mais sobre esta classe em outro post) na declaração da classe, abaixo de wxTextCtrl *display;:
    wxString textodisplay;
    Agora no construtor da classe GridSizer:

    //inicializamos o texto do display como vazio
    textodisplay = "";
   //atribuímos um ID diferente para cada botão (de 1 a 20), tomando cuidado para que nenhum outro widget 
  //tenha o mesmo ID
  gs->Add(new wxButton(this, 1, wxT("Cls")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 2, wxT("Bck")), 0, wxEXPAND);
  gs->Add(new wxStaticText(this, 3, wxT("")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 4, wxT("Close")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 5, wxT("7")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 6, wxT("8")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 7, wxT("9")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 8, wxT("/")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 9, wxT("4")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 10, wxT("5")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 11, wxT("6")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 12, wxT("*")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 13, wxT("1")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 14, wxT("2")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 15, wxT("3")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 16, wxT("-")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 17, wxT("0")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 18, wxT(".")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 19, wxT("=")), 0, wxEXPAND);
  gs->Add(new wxButton(this, 20, wxT("+")), 0, wxEXPAND);

  //No loop for nós conectamos o click nos botões ao método OnClick() (poderia ter qualquer outro nome)
  for(int i = 1; i < 20; i++) {
    Connect(i, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GridSizer::OnClick));     
  }

 Agora, eis o  método que vai tratar o click nos botões da "calculadora":

void GridSizer::OnClick(wxCommandEvent &evt) {
   //criamos um ponteiro para um objeto da classe wxButton e fazemos um cast para que
   //ele receba o objeto que gerou o evento
   wxButton *btn = (wxButton*) evt.GetEventObject();
   //o método GetId() da classe wxCommandEvent retorna o id do objeto que gerou o evento
   if(evt.GetId() != 2)
   //se o botão clicado for diferente de Bck atribuímos o label do mesmo ao objeto wxString textodisplay
      textodisplay += btn->GetLabelText();
   else
      //senão removemos o último caracter da string
      textodisplay.RemoveLast();
     
   if(evt.GetId() == 1)
      //se clicarmos no botão Cls atribuimos uma string vazia ao texto do display
      textodisplay = "";
  
   if(evt.GetId() == 4)
      //fechamos a aplicação
      this->Close(); 
   //setamos o valor do display      
   display->SetValue(textodisplay);  
}

Nenhum comentário:

Postar um comentário