terça-feira, setembro 26, 2006

Curso de wxWidgets, post 4: Posicionando com sizers

Se você tentou adicionar novos widgets no frame do nosso "Hello, world!", possa ser que tenha tido problemas para posicioná-los. É isto que vamos fazer agora!

Bem, no wxWidgets, você não precisa especificar as coordenadas de cada widget (nem deve). Ao invés disso, usamos os sizers, que são objetos do wxWidgets que auxiliam no posicionamento dos widgets. Funciona mais ou menos como uma tabela, você adiciona sizers horizontais ou verticais e vai inserindo os widgets nas "células" deles.

No post de hoje, vamos fazer a seguinte janela para demonstrar o uso de sizers:



Para que você entenda o funcionamento dos sizers, vou mostrar como ela foi divida por eles:



Nesta janela foram usados dois sizers: um vertical (vermelho) e um horizontal (azul). O sizer horizontal tem dois widgets: um wxTextCtrl e um wxButton. O sizer vermelho tem um wxStaticText e o sizer horizontal. O sizer horizontal vai ficar dentro do vertical, de forma a fazer esta arrumação.

Para fazer esta janela, vamos modificar o nosso "Hello, world!". Na definição da classe do frame, declare os widgets que vamos usar:

class MeuFrame: public wxFrame
{
public:
MeuFrame(void);

private:
wxStaticText *lb_hello;
wxTextCtrl *txt_name;
wxButton *btn_say;
};


E no construtor do frame, vamos criar os sizers, os widgets e posicioná-los:

MeuFrame::MeuFrame(void)
:wxFrame(NULL, wxID_ANY, wxT("Meu Programa"))
{
// Criação dos sizers
wxBoxSizer *sizer_v = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *sizer_h = new wxBoxSizer(wxHORIZONTAL);

// Criação dos widgets
lb_hello = new wxStaticText(this, wxID_ANY, wxT("Digite seu nome na caixa:"));
txt_name = new wxTextCtrl(this, wxID_ANY);
btn_say = new wxButton(this, wxID_ANY, wxT("Hello!"));

// Posicionamento dos widgets
sizer_h->Add(txt_name, 1, wxALL, 5);
sizer_h->Add(btn_say, 0, wxALL, 5);

sizer_v->Add(lb_hello, 0, wxALL, 5);
sizer_v->Add(sizer_h, 0, wxALL | wxEXPAND, 5);

SetSizerAndFit(sizer_v);
}


Vamos entender melhor os sizers. No início do construtor, criamos os dois sizers que vamos utilizar. No wxBoxSizer, você insere os widgets nas "células" e ele os encaixa usando o tamanho mínimo necessário por aquele widget. Como parâmetro do wxBoxSizer, passamos sua orientação, que pode ser wxHORIZONTAL ou wxVERTICAL.

Em seguida, criamos os widgets normalmente, chamando os construtores de cada um deles.

Por último, os widgets são inseridos nos sizers com o método wxSizer::Add(). Neste método, passamos os seguintes parâmetros:

txt_name: o widget a ser inserido.

1: a proporção (se ele deve se esticar na orientação do sizer e em que proporção de acordo com os outros widgets no mesmo sizer).

wxALL | wxEXPAND: flags deste elemento. wxALL diz que deve haver um espaçamento em todas as direções do widget e wxEXPAND diz que esse widget deve expandir para usar todo o espaço dado a ele. Outras flags podem ser encontradas na documentação do wxSizer.

5: o tamanho da borda que será usada com wxALL.

Por último, devemos dizer ao frame qual o sizer principal e que ele deve ser usado como base para o tamanho da janela. Para isso, chamamos o método wxWindow::SetSizerAndFit() e passamos o sizer vertical como parâmetro, já que ele contém todos os widgets e sizers dentro dele.

O uso de sizers é bastante fácil. Basta criar os sizers, criar os widgets e adicionar os widgets nos sizers. Experimente adicionar outros widgets junto com mais sizers, criando arrumações diferentes.

Leia também a documentação do wxWidgets para ver os outros sizers e veja o tópico "Sizer overview", esta página contém informações úteis na utilização de sizers.

PS.: Caso tenha dúvida em qualquer assunto de algum post do curso, deixe um comentário com sua pergunta. Se os leitores participarem no blog, outras pessoas também aprenderão.

2 comentários:

Fabio disse...

Caramba muito bom os seus tutoriais, eu estou postando pra pedir, que por favor continue com eles :) , são de gramde serventia.
Obrigado

Zeh Ortigoza disse...

Material raro e de ótima qualidade, parabéns.