sábado, setembro 24, 2005

Hello World

Este é um minúsculo tutorial de Robert Roebling.

Ele tem a intenção de ajudar as pessoas a fazer uma rápida análise relacionada a sintaxe e aos princípios básicos. O programa Hello Word completo está aqui.

Você tem que incluir os arquivos de cabeçalho, claro. Isto pode ser feito incluindo arquivos arquivo por arquivo, conforme a necessidade como, por exemplo
#include "wx/window.h"
ou usando um include global:
#include "wx/wx.h"


Isto também é útil em plataformas que suportam cabeçalhos pré-compilados tais como todos os principais compiladores da plataforma Windows.

#include "wx/wx.h"


Praticamente todos os aplicativos deveriam definir uma nova classe, derivada de wxApp.Sobrescrevendo o método
OnInit()
de wxApp o programa pode ser iniciado, por exemplo, criando uma nova janela principal.


class MyApp: public wxApp
{
virtual bool OnInit();
};


A janela principal é criada derivando a classe de wxFrame e fornecendo-lhe um menu e uma barra de estado no seu construtor. Além disso, qualquer classe que deseje responder à qualquer evento (tais como os cliques do mouse ou às mensagens do menu ou de um botão) deve declarar uma tabela de eventos usando a macro abaixo.

Finalmente, o modo de reagir a tais eventos deve ser feito em handlers (manipuladores). No nosso exemplo, nós reagimos a dois itens de menu, um para o Quit (sair) e um para a exibição da janela About (sobre). Estes handlers não deveriam ser virtuais.


class MyFrame: public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);

void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);

DECLARE_EVENT_TABLE()
};

Para poder reagir a um comando do menu, deve ser dado um identificador único, como um const ou um enum.

enum
{
ID_Quit = 1,
ID_About,
};
Nós então prosseguimos para realmente implementar uma tabela de eventos na qual os eventos serão roteados para suas respectivas funções handler na classe MyFrame. Há macros pré-definidas para rotear todos os eventos comuns, indo da seleção da entrada de uma list box ao evento de redimensionamento quando o usuário redimensiona uma janela na tela.

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Quit, MyFrame::OnQuit)
EVT_MENU(ID_About, MyFrame::OnAbout)
END_EVENT_TABLE()
Semelhante a todos os programas, deve haver uma função main. No wxWidgets o main é implementado usando-se macro, a qual cria uma instância da aplicação e inicia o programa.

IMPLEMENT_APP(MyApp)


Conforme mencionado acima,
wxApp::OnInit()
é chamado durante a incialização e deveria ser usado para iniciar o programa, talvez exibindo uma tela de splash e criando a janela principal (ou várias janelas). O frame deveria receber barra de título com o texto ("Hello World") e a posição e tamanho iniciais. Um frame também pode ser declarado para ser a janela principal. Retornar TRUE indica sucesso na intialização.


bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame( "Hello World", wxPoint(50,50), wxSize(450,340) );
frame->Show(TRUE);SetTopWindow(frame);
return TRUE;
}

No construtor da janela principal (ou depois) nós criamos um menu com dois itens, bem como uma barra de estado para ser exibida na base da janela principal. Ambas tem que ser anunciadas ao frame com as chamadas respectivas.


MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
{
wxMenu *menuFile = new wxMenu;

menuFile->Append( ID_About, "&About..." );
menuFile->AppendSeparator();
menuFile->Append( ID_Quit, "E&xit" );

wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append( menuFile, "&File" );

SetMenuBar( menuBar );

CreateStatusBar();
SetStatusText( "Welcome to wxWidgets!" );
}
Aqui estão os manipuladores de evento. MyFrame::OnQuit() fecha a janela principal chamando Close(). O parâmetro TRUE indica que outras janelas não tem poder de veto como, por exemplo, perguntar: "Você tem certeza que quer fechar?". Se não há nenhuma outra janela principal, a aplicação irá encerrar.


void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(TRUE);
}
exibirá uma pequena janela contendo algum texto. Neste caso, uma janela "About" típica com informações sobre o programa.


void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox("This is a wxWidgets Hello world sample","About Hello World", wxOK wxICON_INFORMATION, this);
}

Você pode querer compilar o programa. Altere a extensão do arquivo de texto para .cpp, por exemplo, hworld.cpp. Usando o wxGTK e seu sistema de configuração você pode usar as seguintes declarações em qualquer sistema que tenha o g++ (em qualquer lugar que você tenha instalado o GTK+ e o wxGTK e qualquer que seja a opção que você tenha usado durante a instalação). Se você usar outra versão tal como wxMotif ou wxMSW, é recomendado que você adapte um dos makefiles de exemplo ou arquivos de projeto.


g++ hworld.cpp `wx-config --libs` `wx-config --cxxflags` -o hworld

Finalmente, você pode iniciar seu programa assim:
./hworld
Neste ponto o programa está no ar e você pode sair ou exibir o diálogo.

Nota para os usuários wxGTK: se o programa não iniciar e você receber uma mensagem como "hworld: can't load library libwx_gtk.so.1" então você esqueceu de re-executar o linker após a instalação da biblioteca. Faça isto logando como root e executando ldconfig (no Linux e no Solaris).

Se você obteve um erro do seu servidor X e o programa fechou, então você compilou sua biblioteca com suporte a threads apesar do seu sistema não suportá-las. Você terá que configurar --without-threads e recompilar todo o wxGTK após executar o comando make clean.

Para pessoas que não gostam do modo de rotear os eventos para os handlers usando a tabela de eventos e que preferem o modo como é feito no GTK+ or Qt: Também existe o método Connect(), a qual funciona de maneira muito similar ao modo do GTK+. Um argumento contra o uso do Connect() (apesar de ser mais próximo ao C++ e mais curto de se escrever) é que o wxIDE, o ambiente de programação visual do wxWidgets irá utilizar (e modificar) as tabelas de métodos e não as rotinas Connect().

Uma versão do hworld usando o Connect() está aqui.

Quer saber mais? Leia o livro do Julian Smart, principal desenvolvedor do wxWidgets.

Nota
Este artigo foi traduzido. A versão original encontra-se aqui: http://www.wxwidgets.org/hello.htm

Nenhum comentário: