quinta-feira, 8 de setembro de 2011

Tutorial wxWidgets e sqlite3 parte 8 - Criando um banco de dados e a tabela contatos


Hoje vamos criar nosso banco de dados pelo sistema e também criaremos a tabela que iremos utilizar, via código.

Primeiro vamos abrir o projeto da agenda.

Lembrem-se que nossa agenda vai possuir apenas 3 campos:

1 – ID Integer Primary Key
2 – Nome Varchar(50)
3 – Idade Integer

Nossa agenda irá trabalhar da seguinte maneira, ao abrir o sistema, vamos verificar se existe o arquivo “agenda.db3”, se ele não existir, iremos executar uma função que criará o banco de dados e a tabela contatos, ou seja, esta função, teoricamente, será usada apenas uma vez.

Vamos ao código:

Em sqlf.h:
//Esta função será usada para criar o nosso banco de dados
//e também para criar a tabela contatos.
//Ela será executada apenas uma vez...
void CreateDBAgenda();

Em sqlf.cpp:
void CreateDBAgenda()
{
    //Primeiro, vamos pegar o diretório da aplicação mais o nome do banco de dados...
    wxString conf_path = GetExecPath() + wxT("/agenda.db3");

    //Agora vamos verificar se o arquivo já existe...
    //Se existir, paro a execução da função...
    if(wxFileExists(conf_path))
    {
        return;
    }

    //Se ele não existir crio um wxSQLite3Database com este caminho...
    wxSQLite3Database *db = OpenDB(conf_path);

    //Ok, agora criamos um sql com o comando de criação da nossa tabela
    //CREATE TABLE contatos(
    //ID INTEGER PRIMARY KEY,
    //NOME VARCHAR(50),
    //IDADE INTEGER
    //);

    //Vamos adicionar isto em uma wxString

    wxString SQL = wxT("CREATE TABLE contatos(\n");
    SQL += wxT("ID INTEGER PRIMARY KEY,\n");
    SQL += wxT("NOME VARCHAR(50),\n");
    SQL += wxT("IDADE INTEGER\n");
    SQL += wxT(");");

    //Agora vamos usar ExecuteUpdate para executar este SQL...
    //Usamos ExecuteUpdate para criarmos tabelas, views, triggers...
    //Inserir registros no banco de dados...
    //Editar registros no banco de dados...
    //Excluir registros no banco de dados...
    //Não use ExecuteUpdate para seleções...
    db->ExecuteUpdate(SQL);

    //Fechamos a conexão com o banco de dados...
    CloseDB(db);
}

Vejam que usamos a função ExecuteUpdate e passamos como parâmetro, o código SQL de criação do banco de dados.

O que fizemos aqui foi basicamente, verificar se existia um arquivo chamado “agenda.db3” dentro do diretório da aplicação (esta função foi explicada aqui), se ele não existir, crio o mesmo, depois executo o código de criação da tabela contatos e fecho o banco de dados.

Agora vamos chamar esta função em OnInit() do arquivo main.cpp, ficará assim:
bool wxAppTutorial::OnInit(void)
{
    //Criamos o banco de dados e a tabela caso não existam...
    CreateDBAgenda();

Hoje aprendemos como criar um banco de dados e uma tabela usando wxSqlite3, lembre-se que para criarmos uma view ou um gatilho, usamos estes mesmos passos.

Os arquivos modificados ficaram assim:

main.cpp

//ARQUIVO DO BLOG - http://wxnewbie.blogspot.com
//TUTORIAL wxWidgets + sqlite3 usando wxSqlite3

#include "main.h"
#include "framep.h"
#include "sqlf.h"

bool wxAppTutorial::OnInit(void)
{
    //Criamos o banco de dados e a tabela caso não existam...
    CreateDBAgenda();

    //Crio o Frame que vai controlar a aplicação
    wxFramePrincipal *frameprincipal = new wxFramePrincipal();

    //Mostro o Frame
    frameprincipal->Show();

    //Passo para wxApp que este frame irá controlar a aplicação...
    //quando ele for fechado, a aplicação também será fechada...
    SetTopWindow(frameprincipal);

    return true;
}

IMPLEMENT_APP(wxAppTutorial)

sqlf.h

//ARQUIVO DO BLOG - http://wxnewbie.blogspot.com
//TUTORIAL wxWidgets + sqlite3 usando wxSqlite3

#ifndef SQLF_H_INCLUDED
#define SQLF_H_INCLUDED

#include <wx/wx.h>
#include <wx/wxsqlite3.h>
#include <wx/stdpaths.h>

wxString GetExecPath();
//Nesta primeira função, iremos abrir um banco de dados indicado pelo
//parâmetro caminho e retornar um ponteiro para wxSQLite3Database...
//Se o banco de dados não existir, será criado um...
wxSQLite3Database *OpenDB(wxString caminho);
//Aqui iremos apenas fechar o mesmo...
//Isto é necessário, pois liberaremos o arquivo para novos acessos...
void CloseDB(wxSQLite3Database* db);

//Esta função será usada para criar o nosso banco de dados
//e também para criar a tabela contatos.
//Ela será executada apenas uma vez...
void CreateDBAgenda();

#endif // SQLF_H_INCLUDED

sqlf.cpp

//ARQUIVO DO BLOG - http://wxnewbie.blogspot.com
//TUTORIAL wxWidgets + sqlite3 usando wxSqlite3

#include "sqlf.h"

//Função para pegar o diretório da aplicação, já explicada no blog...
wxString GetExecPath()
{
 wxString retorno;
 retorno = wxStandardPaths::Get().GetExecutablePath();
 retorno = wxPathOnly(retorno);
 return retorno;
}

//Vamos implementar nossa função OpenDB...
wxSQLite3Database *OpenDB(wxString caminho)
{
    //Aqui eu crio um ponteiro para um wxSQLite3Database chamado db...
    //É ele que nós retornaremos na função...
    wxSQLite3Database *db = new wxSQLite3Database();

    //Aqui uso a função Open, passando como parâmetro o caminho para o banco de dados...
    //O interessante aqui é vermos que se existir um banco de dados neste lugar a função
    //irá abrir o mesmo, se não existir o banco de dados será criado...
    db->Open(caminho);

    //Vocês poderão ter um problema ao executar esta função, dizendo que Open possui mais de
    //um parâmetro, se isto acontecer, basta usá-la desta maneira:

    //db->Open(caminho, wxEmptyString);

    //O segundo parametro seria a senha para o banco de dados,
    //se estivessemos usando criptografia no mesmo...

    //retornamos o db...
    return db;
}

//Aqui vamos fechar a "conexão" com o banco de dados...
void CloseDB(wxSQLite3Database* db)
{
    //Vemos se db é verdadeiro...
    assert(db != NULL);
    //Fechamos db com o comando Close();
    db->Close();

    //Deletamos db da memória...
    delete db;
}

void CreateDBAgenda()
{
    //Primeiro, vamos pegar o diretório da aplicação mais o nome do banco de dados...
    wxString conf_path = GetExecPath() + wxT("/agenda.db3");

    //Agora vamos verificar se o arquivo já existe...
    //Se existir, paro a execução da função...
    if(wxFileExists(conf_path))
    {
        return;
    }

    //Se ele não existir crio um wxSQLite3Database com este caminho...
    wxSQLite3Database *db = OpenDB(conf_path);

    //Ok, agora criamos um sql com o comando de criação da nossa tabela
    //CREATE TABLE contatos(
    //ID INTEGER PRIMARY KEY,
    //NOME VARCHAR(50),
    //IDADE INTEGER
    //);

    //Vamos adicionar isto em uma wxString

    wxString SQL = wxT("CREATE TABLE contatos(\n");
    SQL += wxT("ID INTEGER PRIMARY KEY,\n");
    SQL += wxT("NOME VARCHAR(50),\n");
    SQL += wxT("IDADE INTEGER\n");
    SQL += wxT(");");

    //Agora vamos usar ExecuteUpdate para executar este SQL...
    //Usamos ExecuteUpdate para criarmos tabelas, views, triggers...
    //Inserir registros no banco de dados...
    //Editar registros no banco de dados...
    //Excluir registros no banco de dados...
    //Não use ExecuteUpdate para seleções...
    db->ExecuteUpdate(SQL);

    //Fechamos a conexão com o banco de dados...
    CloseDB(db);
}

Espero que tenha ajudado e até a próxima.

quarta-feira, 7 de setembro de 2011

Tutorial wxWidgets e sqlite3 parte 7 - Comunicando-se com um banco de dados


Hoje vamos iniciar a programação em si da comunicação entre sqlite3 e wxWidgets usando a biblioteca wxSqlite3.

Primeiro vamos inserir a biblioteca do wxSqlite3 que compilamos anteriormente, ao projeto:

Abra o projeto agenda criado anteriormente no Code::Blocks.
Abra o menu Project->Build options...
Vá na aba Linker settings.
Em link libraries clique no botão Add


Selecione a biblioteca do wxSqlite3 que deve estar em /usr/local/lib


Clique em Ok e salve o projeto.


Primeiro vamos criar duas funções bem básicas, uma será responsável por criar ou abrir um banco de dados em Sqlite3 e a outra será apenas para fechar a comunicação com o banco de dados.

Nos dois casos, a classe responsável por isso é a wxSQLite3Database, ela se encontra no arquivo de cabeçalho wxsqlite3.h, usaremos apenas duas de suas funções, Open() e Close().

Abra o projeto “agenda” criado no tutorial anterior e abra os arquivos sqlf.h e sqlf.cpp para edição.

No arquivo sqlf.h digite o seguinte:

sqlf.h
#ifndef SQLF_H_INCLUDED
#define SQLF_H_INCLUDED

#include <wx/wx.h>
#include <wx/wxsqlite3.h>

//Nesta primeira função, iremos abrir um banco de dados indicado pelo
//parâmetro caminho e retornar um ponteiro para wxSQLite3Database...
//Se o banco de dados não existir, será criado um...
wxSQLite3Database *OpenDB(wxString caminho);
//Aqui iremos apenas fechar o mesmo...
//Isto é necessário, pois liberaremos o arquivo para novos acessos...
void CloseDB(wxSQLite3Database* db);

#endif // SQLF_H_INCLUDED

No arquivo sqlf.cpp digite o seguinte:

sqlf.cpp
#include "sqlf.h"

//Vamos implementar nossa função OpenDB...
wxSQLite3Database *OpenDB(wxString caminho)
{
    //Aqui eu crio um ponteiro para um wxSQLite3Database chamado db...
    //É ele que nós retornaremos na função...
    wxSQLite3Database *db = new wxSQLite3Database();

    //Aqui uso a função Open, passando como parâmetro o caminho para o banco de dados...
    //O interessante aqui é vermos que se existir um banco de dados neste lugar a função
    //irá abrir o mesmo, se não existir o banco de dados será criado...
    db->Open(caminho);

    //Vocês poderão ter um problema ao executar esta função, dizendo que Open possui mais de
    //um parâmetro, se isto acontecer, basta usá-la desta maneira:

    //db->Open(caminho, wxEmptyString);

    //O segundo parametro seria a senha para o banco de dados,
    //se estivessemos usando criptografia no mesmo...

    //retornamos o db...
    return db;
}

//Aqui vamos fechar a "conexão" com o banco de dados...
void CloseDB(wxSQLite3Database* db)
{
    //Vemos se db é verdadeiro...
    assert(db != NULL);
    //Fechamos db com o comando Close();
    db->Close();

    //Deletamos db da memória...
    delete db;
}


Um exemplo de como utilizar as funções seria o seguinte, imagine que temos um arquivo em /home/usuario/banco.db e queremos abrí-lo:

//Vamos abrir o banco...
wxSQLite3Database *m_db = OpenDB(wxT(“/home/usuario/banco.db”));
//Aqui executo as operações desejadas, como inserir um dado ou fazer uma seleção...
//Aqui fechamos a conexão com o banco de dados...
CloseDB(m_db);

Bem fácil, não?

No próximo tutorial iremos criar o banco de dados da agenda pelo programa e faremos uma função para selecionarmos os dados do banco de dados.

Até a próxima.

sexta-feira, 2 de setembro de 2011

Firebird – Criando um banco de dados com a ferramenta isql

A ferramenta de linha de comando isql do Firebird é usada para criação e administração de Bancos de Dados.

Hoje vamos ver como criar um banco de dados, abrir um banco de dados, criar uma tabela e executar alguns comandos básicos em SQL.

Primeiro vamos abrir a ferramenta:

Se você estiver no Linux (no meu caso Ubuntu) abra o terminal e faça o login como root:
sudo su

Agora abra a ferramenta isql com o comando:
/usr/bin/isql-fb

No Windows, abra a ferramenta no prompt de comando, ela fica dentro da pasta bin do Firebird, algo como:

C:\Arquivos de programas\Firebird\Firebird_x_x\bin\isql.exe

Onde Firebird_x_x vai depender da versão, pode ser Firebird_2_1 ou Firebird_2_5, etc...

Com o isql aberto, vamos criar um banco de dados chamado “tutorial.fbd”, no caso do Linux temos que lembrar que o diretório onde este banco de dados será criado, deve ter as permissões necessárias, se você não sabe como fazer isto, clique aqui para ver o tutorial anterior.

Digite o comando:

CREATE DATABASE 'diretorio_destino/tutorial.fbd' user 'usuario_do_firebird' password 'senha_usuario_firebird';

No comando acima temos o comando CREATE DATABASE depois o caminho completo para o banco de dados que queremos criar (um exemplo seria: '/home/usuario/tutorial.fbd' no Linux ou 'C:\tutorial.fbd' no Windows) lembre-se que este comando deve estar entre apóstrofos “ ' ”, depois passamos o usuário com user 'usuario', o nome do usuário deve estar entre apóstrofos (o usuário padrão do Firebird é SYSDBA) e por último a senha com password 'senha do usuario' também entre apóstrofos.

Dois exemplos práticos para este comando são:

No Linux:

SQL > CREATE DATABASE '/home/alex/firebird_data/tutorial.fbd' user 'SYSDBA' password '1234';

Onde '/home/alex/firebird_data' é o diretório de destino, 'tutorial.fbd' o banco de dados, 'SYSDBA' o usuário e '1234' senha do usuário SYSDBA.

No Windows:

SQL > CREATE DATABASE 'C:\tutorial.fbd' user 'SYSDBA' password 'masterkey';

Onde “C:\” é o diretório de destino, 'tutorial.fbd' o banco de dados, 'SYSDBA' o usuário e 'masterkey' senha do usuário SYSDBA.

Agora vamos sair da ferramenta digitando o comando:
QUIT;

Vamos reabrir o isql novamente com o comando anterior:

Linux:
/usr/bin/isql-fb
Windows:
C:\Arquivos de programas\Firebird\Firebird_x_x\bin\isql.exe

Vamos abrir o banco de dados usando os diretórios de exemplo que usei anteriormente com o comando:

Linux:
SQL> CONNECT '/home/alex/firebird_data/tutorial.fbd' user 'alex' password '1234';

Windows:
SQL> CONNECT 'C:\tutorial.fbd' user 'SYSDBA' password 'masterkey';

O comando CONNECT abre o banco de dados, e os argumentos passados para ele, são os mesmo usados no comando CREATE DATABASE, ou seja, caminho completo para o banco de dados, usuário e senha, não se esqueça que os valores devem ser passados entra apóstrofos “ ' ”.

Agora vamos criar uma tabela chamada 'TESTE' com o comando SQL:

SQL > CREATE TABLE TESTE(
CON> ID INTEGER NOT NULL PRIMARY KEY,
CON> NOME VARCHAR(50) NOT NULL,
CON> IDADE INTEGER NOT NULL
CON> );


Veja que enquanto não coloco um ' ; ' o comando não é fechado.

Testem outros comandos para se acostumarem com a ferramenta, como os comandos abaixo:

SQL> SELECT * FROM TESTE;
SQL> INSERT INTO TESTE(ID, NOME, IDADE) VALUES(1, 'TESTE' , 50);
SQL> SELECT SUM(IDADE) FROM TESTE;


Por hoje é isto, espero que vocês tenham aproveitado o tutorial e qualquer dúvida deixe nos comentários que tentarei ajudar.

Até a próxima.

Vídeo com a explicação

terça-feira, 30 de agosto de 2011

Tutorial wxWidgets e sqlite3 parte 6 - Criando o Projeto e a Interface do programa


Vamos iniciar com a criação do projeto, aqui vou iniciar um projeto no Linux, para quem estiver usando o Visual C++ 2008 no Windows, veja como fazê-lo nos tutoriais anteriores aqui e aqui.

Crie uma pasta onde o projeto será salvo, aqui estou criando em /home/alex/Documentos/tuto_sqlite e vou chamar meu projeto de “agenda”, no caso vai ser bem simples, o objetivo é exatamente incentivar vocês a criarem um projeto com mais campos, depois de terminarmos com os tutoriais, para fixarem bem o conhecimento.

Abrindo o Code::Blocks vamos iniciar um novo projeto wxWidgets, a única coisa que vocês precisam ficar atentos é nesta parte:


Vamos criar um projeto vazio, sem arquivos, pois criaremos tudo na unha como dizem por aí...

Com o projeto aberto criem 6 novos arquivos:

Arquivos de cabeçalho:

main.h
framep.h
//Neste arquivo vamos criar as funções do wxSqlite3
sqlf.h

Aquivos de implementação:

main.cpp
framep.cpp
//Neste arquivo vamos criar as funções do wxSqlite3
sqlf.cpp

Vamos criar então o Aplicativo e a Interface de controle:

Obs.: A explicação está nos comentários do fonte, tentem escrever o programa linha por linha e passe adiante só depois de ter entendido bem o que cada coisa significa, se não conseguirem, os comentários aí do blog servem pra isso mesmo, tirar dúvidas...

O arquivo main.h ficará assim:
//ARQUIVO DO BLOG - http://wxnewbie.blogspot.com
//TUTORIAL wxWidgets + sqlite3 usando wxSqlite3

#ifndef MAIN_H_INCLUDED
#define MAIN_H_INCLUDED

#include <wx/wx.h>

class wxAppTutorial: public wxApp
{
    public:
        bool OnInit(void);
};

#endif

O arquivo main.cpp
//ARQUIVO DO BLOG - http://wxnewbie.blogspot.com
//TUTORIAL wxWidgets + sqlite3 usando wxSqlite3

#include "main.h"
#include "framep.h"

bool wxAppTutorial::OnInit(void)
{
    //Crio o Frame que vai controlar a aplicação
    wxFramePrincipal *frameprincipal = new wxFramePrincipal();

    //Mostro o Frame
    frameprincipal->Show();

    //Passo para wxApp que este frame irá controlar a aplicação...
    //quando ele for fechado, a aplicação também será fechada...
    SetTopWindow(frameprincipal);

    return true;
}

IMPLEMENT_APP(wxAppTutorial)

O arquivo framep.h (Formulário que vai controlar a aplicação)
//ARQUIVO DO BLOG - http://wxnewbie.blogspot.com
//TUTORIAL wxWidgets + sqlite3 usando wxSqlite3

#ifndef FRAMEP_H_INCLUDED
#define FRAMEP_H_INCLUDED

#include <wx/wx.h>
#include <wx/grid.h>

class wxFramePrincipal: public wxFrame
{
    public:
        wxFramePrincipal();
    private:

        //Campos para pegar o ID na edição
        //Também irei usá-lo para saber se
        //está em modo de edição ou inserção...
        //Se for igual a -1 é inserção...
        //Se for diferente de -1 é edição
        int ID;

        //O grid que vai exibir os dados existentes na tabela...
        wxGrid *lista_contatos;

        //Labels dos campos...
        wxStaticText *label_nome;
        wxStaticText *label_idade;

        //Os campos de texto onde preencheremos os campos...
        wxTextCtrl *nome;
        wxTextCtrl *idade;

        //Os botões onde iremos executar os eventos de edição do banco...
        wxButton *salvar;
        wxButton *limpar;
        wxButton *deletar;

        //Declaro a tabela de eventos...
        DECLARE_EVENT_TABLE()

        //Eventos...
        //Evento para salvar no banco de dados...
        void OnClickSalvar(wxCommandEvent& event);
        //Evento para limpar os campos e cancelar edição...
        void OnClickLimpar(wxCommandEvent& event);
        //Evento para deletar um campo...
        void OnClickDeletar(wxCommandEvent& event);

        //Evento de seleção do registro que será editado...
        void OnDoubleClickCell(wxGridEvent& event);

        //Aqui eu vejo se os campos estão em branco, e também se idade é um número...
        bool ConfereCampos();
        //Aqui escrevo uma função para limpar os campos
        //Está função será usada para cancelar uma edição
        //e após executar alterações...
        void LimparCampos();

        enum{
            //Identificador do botão salvar
            ID_SALVAR = 1000,
            //Identificador do botão limpar
            ID_LIMPAR,
            //Identificador do botão deletar...
            ID_DELETAR,
            //Identificador do grid...
            ID_GRID,
        };
};

#endif // FRAMEP_H_INCLUDED

O arquivo framep.cpp
//ARQUIVO DO BLOG - http://wxnewbie.blogspot.com
//TUTORIAL wxWidgets + sqlite3 usando wxSqlite3

#include "framep.h"

wxFramePrincipal::wxFramePrincipal():wxFrame(NULL, wxID_ANY, wxT("Teste Tutorial Sqlite3"))
{
    //Altero a cor do background do Frame
    this->SetBackgroundColour(*wxWHITE);

    //Meu BoxSizer Principal...
    wxBoxSizer *boxp = new wxBoxSizer(wxVERTICAL);

    //Inicio a construção do grid...
    lista_contatos = new wxGrid(this, ID_GRID);

    //Começo com 0 linhas e 3 colunas, lembre-se que o número de colunas deve ser igual ao numero de campos
    //Da view que iremos carregar ou do comando select que iremos carregar...
    lista_contatos->CreateGrid(0, 3);

    //Aqui altero o valor dos rótulos de cada coluna...
    //Nunca se esqueça, o vetor começa em 0, tanto para colunas como para linhas...
    lista_contatos->SetColLabelValue(0, wxT("ID"));
    lista_contatos->SetColLabelValue(1, wxT("Nome"));
    lista_contatos->SetColLabelValue(2, wxT("Idade"));

    //Altero a largura padrão do rótulo da linha para 25px...
    //Altero a altura padrão do rótulo da coluna para 25px...
    lista_contatos->SetRowLabelSize(25);
    lista_contatos->SetColLabelSize(25);

    //Desabilito a edição dos valores no grid, a alteração de valores será feita
    //pelos wxTextCtrl's
    lista_contatos->EnableEditing(false);

    //Adiciono o grid no BoxSizer principal...
    boxp->Add(lista_contatos, 1, wxEXPAND, 0);

    //Aqui eu adiciono um separador...
    boxp->Add(0, 0, 0, wxALL, 10);

    //Aqui crio um BoxSizer para arranjar os campos de preenchimento de valores...
    wxBoxSizer *box_texts = new wxBoxSizer(wxVERTICAL);

    //o rótulo para o campo nome...
    label_nome = new wxStaticText(this, wxID_ANY, wxT("Nome"));
    //adiciono o rótulo no box dos valores de preenchimento...
    box_texts->Add(label_nome, 0, wxALL, 2);

    //Faço o mesmo que fiz anteriormente para todos os outros campos...
    nome = new wxTextCtrl(this, wxID_ANY, wxEmptyString ,wxDefaultPosition, wxSize(200, -1));
    box_texts->Add(nome, 0, wxALL, 5);

    label_idade = new wxStaticText(this, wxID_ANY, wxT("Idade"));
    box_texts->Add(label_idade, 0, wxALL, 2);

    idade = new wxTextCtrl(this, wxID_ANY, wxEmptyString ,wxDefaultPosition, wxSize(120, -1));
    box_texts->Add(idade, 0, wxALL, 5);

    //Aqui adiciono o box dos campos de preenchimento no box principal...
    boxp->Add(box_texts, 0, wxLEFT, 40);

    //Agora um box para arranjar os botões...
    wxBoxSizer *box_btns = new wxBoxSizer(wxHORIZONTAL);

    //Um separador...
    box_btns->Add(0, 0, 0, wxLEFT, 40);

    //Botão salvar...
    salvar = new wxButton(this, ID_SALVAR, wxT("Salvar"));
    //Adiciono ao box dos botões...
    box_btns->Add(salvar, 0, wxALL, 5);

    limpar = new wxButton(this, ID_LIMPAR, wxT("Limpar Campos"));
    box_btns->Add(limpar, 0, wxALL, 5);

    deletar = new wxButton(this, ID_DELETAR, wxT("Deletar"));
    box_btns->Add(deletar, 0, wxALL, 5);

    //Adiciono o box dos botões ao box principal...
    boxp->Add(box_btns, 1, wxEXPAND, 0);

    //"Digo" ao meu frame que o boxp é o box principal...
    this->SetSizer(boxp);

    //Aqui apenas faço com que tudo seja arranjado de maneira correta...
    this->Layout();

    //Seto o ID como -1 para saber que inicio em modo de inserção...
    ID = -1;
}

//Aqui minha tabela de eventos declarada...
BEGIN_EVENT_TABLE(wxFramePrincipal, wxFrame)
//Veja que digo para cada evento, que o controle que estiver com
//determinado id, é o que será responsável por executá-lo
//No exemplo de salvar:
//Eu digo que é um evento do tipo EVT_BUTTON, ou seja, um evento executado por um botão...
//O botão responsável pelo evento é o que tiver o identificador: ID_SALVAR
//e o evento que ele vai executar é o OnClickSalvar...

//É muito importante o entendimento desta parte para não acontecer nada de errado...
EVT_BUTTON(ID_SALVAR, wxFramePrincipal::OnClickSalvar)
EVT_BUTTON(ID_LIMPAR, wxFramePrincipal::OnClickLimpar)
EVT_BUTTON(ID_DELETAR, wxFramePrincipal::OnClickDeletar)

//Quando você for criar um evento para grid's repare que alguns levam um CMD no nome e outros não...
//Se você estiver criando uma classe derivada de wxGrid, vc não usa o comando que contém o CMD
//Veja que este comando sem CMD como é o caso de EVT_GRID_CELL_LEFT_DCLICK (comando que é executado
//quando dou 2 cliques em uma célula) não recebe ID nenhum como parâmetro...
//agora se eu for executar o mesmo comando usando um wxGrid como controle no meu frame ou dialogo
//eu uso o comando com CMD como é o caso do evento abaixo...
EVT_GRID_CMD_CELL_LEFT_DCLICK(ID_GRID, wxFramePrincipal::OnDoubleClickCell)
END_EVENT_TABLE()

//Aqui eu inicio a implementação do evento para salvar um registro...
void wxFramePrincipal::OnClickSalvar(wxCommandEvent& event)
{
    //...Os comandos que usaremos aqui, será escrito depois...
}

//Aqui o evento que vai limpar os campos...
void wxFramePrincipal::OnClickLimpar(wxCommandEvent& event)
{
    //...Os comandos que usaremos aqui, será escrito depois...
}

//Aqui o evento quando eu clicar no botão deletar...
void wxFramePrincipal::OnClickDeletar(wxCommandEvent& event)
{
    //...Os comandos que usaremos aqui, será escrito depois...
}

//Aqui o evento que será exxecutado
//quando eu der 2 cliques em uma célula...
void wxFramePrincipal::OnDoubleClickCell(wxGridEvent& event)
{
    //...Os comandos que usaremos aqui, será escrito depois...
}

//Esta função eu vou usar para limpar os campos
//como eu precisarei fazer isto sempre que eu completar uma alteração
//vou escrever este código em uma função em separado...
void wxFramePrincipal::LimparCampos()
{
    //...Os comandos que usaremos aqui, será escrito depois...
}

//Aqui vou conferir os campos para ver se o usuário digitou algo errado...
bool wxFramePrincipal::ConfereCampos()
{
    //...Os comandos que usaremos aqui, será escrito depois...
    return true;
}

Estudem o código, já coloquei nele os eventos que serão usados para o controle das ações. O resultado final da Interface é esse:



No próximo tutorial explicarei como executar alguns comandos usando wxSqlite3 e escreveremos os códigos para fazer a agenda funcionar.

Até a próxima.

wxWidgets – Usando argc e argv em wxApp

Continuando com o tutorial básico de wxWidgets, hoje vou explicar como utilizar argc e argv de wxApp.

São valores que são passados na inicialização de programas, onde argc me retorna o número de argumentos passados e argv os valores dos argumentos.

Utilizando o mesmo código anterior de wxApp, vamos ver como funciona:

Vou criar um novo projeto, onde o executável está em /home/alex/Documentos/wxapp_tuto/tuto_wxapp/bin/Debug

Vamos ao código:

//main.h
#include <wx/wx.h>

class wxAppTuto: public wxApp
{
    public:
        bool OnInit(void);
};

//main.cpp
#include “main.h”
bool wxAppTuto::OnInit()
{
    //Aqui eu pego o valor de argc e argv...
    //Lembre-se que eles são membros de wxApp
    int get_argc = argc;
    wxString get_argv = *argv;

    //Aqui mostro estes valores em um wxMessageBox
    wxMessageBox(wxString::Format(wxT("Números de parâmetros - %d \n\n Valores - "), get_argc) + get_argv);
    return false;
}

IMPLEMENT_APP(wxAppTuto)

O resultado da execução do programa será o seguinte:


Vejam que mesmo eu não tendo passado nenhum valor na inicialização ele me retornou um valor, que é o caminho completo para o executável, este valor sempre será apresentado no primeiro valor...

Agora vamos alterar um pouco o código para pegarmos todos os argumentos que possam ser passados:

//main.cpp
#include “main.h”
bool wxAppTuto::OnInit()
{
    int get_argc = argc;

    wxString get_argv;

    //Aqui eu pego o número de argumentos e vou adicionando
    //cada um deles a wxString get_argv...
    for(int i = 0; i < argc; i++)
    {
        get_argv += wxString::Format(wxT("%s\n"), argv[i]);
    }

    wxMessageBox(wxString::Format(wxT("Números de parâmetros - %d \n\n Valores - "), get_argc) + get_argv);
    return false;
}

Agora vou reabrir o programa pela linha de comando da seguinte maneira.

//tuto_wxapp é o nome do executável...
./tuto_wxapp teste1 teste2 teste3

O resultado será o seguinte:


Veja que ele pegou cada um dos valores em um argumento, se fossemos passar uma string com espaços precisaríamos apenas passar este valor entre aspas como em “teste tutorial wxApp”.

./tuto_wxapp “teste tutorial wxApp”


Uma aplicação prática, seria quando abrimos um arquivo usando o “Abrir com...” diretamente pelo nosso programa, quando fazemos isto, o caminho para este arquivo é passado no argumento, se tentarmos abrir vários arquivos de uma vez serão passados vários argumentos, pegaríamos cada um deles e passaríamos para o sistema, isto é útil se tivermos criando um programa para exibir imagens ou um editor de textos por exemplo.

Espero que aproveitem a explicação e até a próxima.

segunda-feira, 29 de agosto de 2011

Instalando e configurando Firebird 2.5 no Ubuntu 11.04


Neste tutorial vou explicar como instalar e configurar o Firebird 2.5 no Ubuntu 11.04

Abra o gerenciador de pacotes Synaptic

Sistema → Administração → Gerenciador de pacotes Synaptic

ou

sudo synaptic

Digite sua senha

No “filtro rápido”, digite firebird

Marque para instalação o pacote

firebird2.5-super



Abrirá um diálogo com os outros pacotes necessário, clique em marcar.


Na janela do Synaptic clique em aplicar e no diálogo que se abre, também clique em aplicar.


Após as alterações terem sido feitas, feche o Synaptic e abra um terminal.

Digite o comando abaixo e sua senha logo em seguida para usar a conta root...

sudo su


Agora vamos reconfigurar o firebird, nesta etapa iniciaremos o servidor e configuraremos uma senha para o usuário SYSDBA.

Digite o comando abaixo:

dpkg-reconfigure firebird2.5-super


Nesta tela selecione sim para ativar o servidor Firebird


Nesta tela selecione OK para configurar a senha do SYSDBA



Digite a nova senha:


Você voltará ao terminal e serão exibidas as mensagens a seguir.



Para iniciarmos o servidor Firebird 2.5 usamos o comando:
sudo /etc/init.d/firebird2.5-super start

Para pararmos o servidor usamos o comando:
sudo /etc/init.d/firebird2.5-super stop

Para reiniciar o servidor usamos o comando:
sudo /etc/init.d/firebird2.5-super restart


Para criarmos novos bancos de dados, o diretório pré configurado com permissões para o firebird é:

/var/lib/firebird/2.5/system

Se vocês tentarem criar um banco de dados em um diretório sem as permissões para o firebird dará erro.

Uma alternativa é criar uma pasta onde vocês querem salvar os arquivos de banco de dados do firebird e dar as devidas permissões.

Um jeito bem simples é o seguinte:

Crie uma pasta onde vocês querem criar o banco de dados, no meu caso, vou criar um diretório no seguinte caminho, /home/alex/firebird_data

Agora vou abrir o Nautilus (o gerenciador de arquivos que estou usando aqui) como root, com o comando:

sudo nautilus



Vou até o local onde criei meu diretório firebird_data e clicando com o botão direito do mouse seleciono Propriedades.


No diálogo que se abre, vá até a aba Permissões e altere os valores como na figura:





Feche o diálogo, o Nautilus e o terminal.

Pronto, esta pasta já está apta para receber bancos de dados do Firebird.

Basicamente, a instalação e configuração do firebird no Ubuntu é isto, se vocês optarem por outra versão do firebird, basta alterar os comandos e caminhos para os mesmos, como por exemplo em “sudo /etc/init.d/firebird2.1-super start” ou “sudo /etc/init.d/firebird2.5-classic start”, etc...

Depois darei um exemplo de como criar um banco de dados no firebird usando o flamerobin e o isql.

Espero que tenha ajudado nesta parte e qualquer dúvida deixem nos comentários que tentarei ajudar.

Até a próxima.

wxWidgets – Pegando o diretório da aplicação em wxWidgets


Um erro comum em wxWidgets é usar wxGetCwd() para pegar o diretório da aplicação, este comando retorna o diretório de trabalho atual, em alguns casos, onde nenhum arquivo fora do diretório da aplicação é acessado, este comando pode até funcionar, mas quando saímos do diretório da aplicação este comando retorna um valor diferente do esperado.

Vejam por exemplo o que este comando retorna quando eu tento abrir um arquivo que está no meu Desktop diretamente em um sistema que está em /home/alex/Documentos/gerbsox/bin/Debug

E se eu tentar executar o mesmo pelo Code::Blocks o resultado será o seguinte:


Para contornar esta situação eu uso uma função bem simples que segue a baixo:


//Primeiro adiciono o arquivo de cabeçalho que contém wxStandardPaths
#include <wx/stdpaths.h>

//Aqui implemento um função chamada GetExecPath() que me retornará uma wxString...

wxString GetExecPath()
{
    //Esta função wxStandardPaths::Get().GetExecutablePath()
    //me retorna um caminho completo para o executável
    //incluindo o nome do executável, o que não é o que nós queremos...
    wxString path_c = wxStandardPaths::Get().GetExecutablePath();

    //Resolvemos o problema usando wxPathOnly(...)
    //que vai retornar apenas o valor do diretório removendo o nome do arquivo...
    wxString path_ok = wxPathOnly(path_c);

    //Agora é só eu retornar o valor correto do diretório da aplicação...
   return path_ok;

    //poderíamos economizar código escrevendo a função inteira assim:
    //return wxPathOnly(wxStandardPaths::Get().GetExecutablePath());
}


Vejam que se eu não usar o wxPathOnly(...), o nome do executável também aparecerá na string
Onde /home/alex/Documentos/gerbsox/bin/Debug é o diretório da minha aplicação e gerbsox é o meu executável...

Vamos repetir o que foi feito anteriormente para ver o que o comando vai nos retornar.

Aqui executando o aplicativo pelo CodeBlocks...


...e aqui abrindo o arquivo que estava na área de trabalho...


Espero ter ajudado em alguma coisa.

Até a próxima...