Mostrando postagens com marcador wxWidgets. Mostrar todas as postagens
Mostrando postagens com marcador wxWidgets. Mostrar todas as postagens

segunda-feira, 19 de novembro de 2012

wxAutomationObject – Parte 5 – Contando o número de Workbooks abertos em uma Instância

Hoje vamos criar uma função simples para contar o número de Workbooks abertos na instância do Excel que estamos trabalhando.

Na classe wxAutomationExcel em public digitamos a declaração da função.

int wxAutomationExcel::GetWorkbookCount()

no arquivo mexcel.cpp sua contrução.

int wxAutomationExcel::GetWorkbookCount()
{
     const wxVariant workbooksCountV = this->GetProperty(wxT("Workbooks.Count"));
   
     if (workbooksCountV.IsNull())
    {
        wxLogError(wxT("Problemas ao executar a operação"));
        return 0;
    }

    const long workbooksCount = workbooksCountV;

    return workbooksCount;
}

Aqui estamos trabalhando mais uma vez com propriedades, no caso, chamamos a propriedade Workbooks.Count, ela retornará um long como resultado, veja que se meu wxVariant for igual a nulo, eu retorno o 0, eu faço assim, pois se existirem Workbooks na instância, ele será maior que zero.

Para testar a função:

wxAutomationExcel m_excel;

//Primeiro pegamos a instância do Excel,
//se ela não existir eu retorno Nulo
if(!m_excel.GetExcelInstance())
     return;

//Pego o número de Workbooks abertos...
int getWBCount = m_excel.GetWorkbookCount();

//Exibo uma mensagem com o valor.
wxMessageBox(wxString::Format("Número de Workbooks abertos\n%d", getWBCount));

Lembrando que essa função conta apenas o número de Workbooks que estão abertos na instância que estamos controlando, se tivéssemos 5 instâncias rodando, cada uma com 1 Workbook aberto, o valor retornado seria 1.

Uma imagem com o resultado do teste, veja que tenho 3 Workbooks abertos, todos na instância que eu estou controlando.



sábado, 27 de outubro de 2012

wxAutomationObject – Parte 4 – Exibir ou esconder o Excel

Agora começaremos a trabalhar com propriedades, na classe wxAutomationObject usamos dois métodos para isto, um chamado GetPropert para pegarmos o valor de uma propriedade e PutPropert para alterarmos uma propriedade, note que a partir daqui iremos utilizar com frequência wxVariants, então recomendo que vocês leiam a documentação da mesma.

Primeiro vamos verificar se o Excel está visível ou se está correndo em segundo plano.

Na classe wxAutomationExcel em public digitamos a declaração da função.

bool GetVisible();

no arquivo mexcel.cpp sua contrução.

bool wxAutomationExcel::GetVisible()
{
     if(this == NULL)
         return false;

     wxVariant m_show = this->GetProperty(wxT("Visible"));

     return m_show.GetBool();
}

No código acima, vemos o uso do método GetProperty, passamos para o mesmo o nome da propriedade que queremos pegar o valor e passamos esse para um wxVariant, veja que antes verifico se wxAutomationExcel é nulo, se o Excel estiver visível nossa função retornará verdadeiro, caso contrário, falso...

Agora, vamos alterar essa propriedade, escondendo ou exibindo a instância do Excel que estiver setada em nosso wxAutomationExcel.

Na classe wxAutomationExcel em public digitamos a declaração da função.

bool SetVisible(bool visible);

no arquivo mexcel.cpp sua contrução.

bool wxAutomationExcel::SetVisible(bool visible)
{
     if(this == NULL)
         return false;

    if(!this->PutProperty(wxT("Visible"), visible))
    {
        wxLogError(wxT("Excel não pode ser exibido"));
         return false;
    }

     return true;
}

Nessa função utilizamos o método PutProperty, esse método é utilizado para pegarmos alguma propriedade do objeto setado em nossa classe, passamos primeiro o nome da propriedade e depois o valor que queremos dar para ela, no caso da propriedade Visible passamos um valor booleano.

Vale lembrar que essa classe está trabalhando apenas com o Excel.Application, então todos os métodos e propriedades passados como parâmetros servem apenas para a aplicação em si.

Para testarmos as duas funções apresentadas nesse tutorial:

wxAutomationExcel m_excel;

if(!m_excel.GetExcelInstance())
     return;

//ou
//if(!m_excel.CreateExcelInstance())
//   return;

//Vejo se o Excel está visível...
if(m_excel.GetVisible())//...se sim...
     m_excel.SetVisible(false);//...escondo...
else//...se não...
     m_excel.SetVisible(true);//...exibo o mesmo...

No próximo tutorial iremos iniciar com Workbooks, até.

quarta-feira, 24 de outubro de 2012

wxAutomationObject – Parte 3 – Criando uma nova instância do Excel.

Criaremos agora uma função que executa uma nova instância do Excel, ela  será publica e do tipo booleana também.

Na classe wxAutomationExcel em public digite a função.

bool CreateExcelInstance();

no arquivo mexcel.cpp sua contrução.

bool wxAutomationExcel::CreateExcelInstance()
{
     if(!this->CreateInstance(wxT("Excel.Application")))
     {
         wxLogError(wxT("Não foi possível criar a instância"));
         return false;
     }

     return true;
}

Nesse código utilizamos outro método da classe wxAutomationObject, CreateInstance passando para o mesmo a string "Excel.Application", ela retornará verdadeiro se conseguir criar uma nova instância do Excel passando o ponteiro para nosso wxAutomationExcel, se ocorrer algum problema ela retornará falso e nosso wxAutomationExcel será nulo.

Para testar a função:

wxAutomationExcel m_excel;
if(!m_excel.CreateExcelInstance())
     return;

//Aqui poderíamos seguir...

wxAutomationObject – Parte 2 – Verificando se o Excel está em execução:

Vamos iniciar criando uma função que verifica se o Excel está em execução, ela será pública do tipo booleana, se uma instância do Excel estiver em execução ela retornará verdadeiro, se não, retornará falso.

Na classe wxAutomationExcel em public digite:

bool GetExcelInstance();

no arquivo mexcel.cpp sua construção.

bool wxAutomationExcel::GetExcelInstance()
{
     if(!this->GetInstance(wxT("Excel.Application")))
     {
         wxLogError(wxT("Excel não está em execução"));
         return false;
     }

     return true;
}


No código acima vemos a função GetInstance da classe wxAutomationObject, ela verificará se o Excel está rodando, se o mesmo estiver executando, ele passará o ponteiro da aplicação para nosso wxAutomationExcel e retornará verdadeiro, nesse ponto já podemos trabalhar com a automação, se o Excel não estiver rodando, ele retornará falso e nosso wxAutomationExcel será nulo, ou seja, não estará preparado para executar a automação.

Uma coisa que você deve ter em mente é que, se mais de uma instancia do Excel existir, ele  pegará como ponteiro a primeira instancia criada.

Para testar essa função :

wxAutomationExcel m_excel;

if(!m_excel.GetExcelInstance())
     return;

//Aqui poderíamos prosseguir...

segunda-feira, 22 de outubro de 2012

wxAutomationObject - Excel - Reiniciando

Voltando com os tutoriais sobre wxAutomationObject, como sempre, vou postando as coisas sem muito critério e as elas acabam ficando um pouco complicadas, vou reiniciar do zero pra explicar melhor como as coisas funcionam, e criar classes para gerenciar o conteúdo das explicações.

wxAutomationObject é uma classe que fornece um ponteiro IDispath, que nada mais é que uma referência para um COM/OLE Object, permitindo a execução e automação do Excel, por exemplo.

*Importante: wxAtomationObject é uma classe exclusiva para wxMSW, ou seja, você só conseguirá compilar os exemplos no Sistema Operacional Windows.

Para entendermos a estrutura das classes, vamos entender como é estruturado um arquivo do Excel.


No diagrama podemos ver claramente cada objeto que iremos utilizar:

A instância do programa seria o Excel que está sendo executado na memória naquele momento, seria o Excel.exe sendo executado.

O Workbook é a pasta de trabalho ou o arquivo em si.

Dentro de um Workbook podemos ter uma ou mais planilhas, que no diagrama vemos como Sheet ou Worksheet, por padrão, ao iniciarmos um novo Workbook o mesmo conterá 3 planilhas (Sheet).

E as células, que são os locais onde iremos inserir ou ler os dados que queremos.

Talvez as coisas fiquem mais claras com a imagem abaixo.



Em 1, temos o Excel em execução, é ele que vai gerenciar a automação e execução dos procedimentos e propriedades.

Em 2 temos a pasta de trabalho, é nosso arquivo em si, ele que vai conter todas as nossas planilhas, usaremos o mesmo para salvar o documento ou inserirmos e deletarmos planilhas.

Em 3 temos as planilhas que irão conter as células, podemos alterar seu nome, por exemplo, e gerenciar as células existentes.

Em 4, as células, elas irão conter os valores, como data, textos, números, etc... podemos alterar suas propriedades também, como a cor de fundo, tipo de borda...

Agora que temos de forma clara como é a estrutura de um arquivo Excel, assim como de sua instância, vamos iniciar com os códigos. Criaremos 2 arquivos para armazenar as classes, um chamado mexcel.h e outro mexcel.cpp.

Primeiro iremos trabalhar com uma classe que vai representar o Excel em si, vou chamá-la de wxAutomationExcel e ela será derivada de wxAutomationObject, ele será aqui na nossa estrutura de desenvolvimento, a “Instância”.

No arquivo mexcel.h digite:

#include <wx/wx.h>
#include <wx/msw/ole/automtn.h>

class wxAutomationExcel: public wxAutomationObject
{
public:
          wxAutomationExcel();
          ~wxAutomationExcel();
private:
};

E no arquivo mexcel.cpp:

#include "mexcel.h"

wxAutomationExcel::wxAutomationExcel():wxAutomationObject()
{
}

wxAutomationExcel::~wxAutomationExcel()
{
}

No próximo tutorial vamos iniciar com as funções que irão fazer parte da classe.

sexta-feira, 8 de junho de 2012

wxBrChart - Iniciando

No blog antigo, eu havia comentado sobre a criação de uma biblioteca para criação de gráficos (charts) com wxWidgets, ela se chamava wxBrChart, e eu acabei abandonado o código por um bom tempo, e há duas semanas eu acabei voltando com ela e reescrevi o controle de gráficos em barra, apenas para ver como saía.

São gráficos bem simples, onde você passa cada um dos valores para sua respectiva série, a área do gráfico é plotada em uma imagem que fica posicionada no plano de fundo do componente, seriam gráficos para aplicações bem expecíficas...

O resultado parcial é o que segue:

Chart com barras Verticais



Chart com barras Horizontais


O código para os dois é o mesmo, apenas passo para o contrutor o tipo de gráfico.

O código para a criação é o seguinte:


Assim que o mesmo estiver rodando sem erros, vou compartilhar o fonte da biblioteca, ajudas e idéias serão bem vindas.

quarta-feira, 19 de outubro de 2011

Sequência de vídeos sobre imagens com wxWidgets

Desenhando uma imagem com wxWidgets - Parte 1



Desenhando uma imagem com wxWidgets - Parte 2


Desenhando uma imagem com wxWidgets - Parte3


Plano de fundo em um wxPanel

Dúvidas, postem nos comentários, até a próxima.

quinta-feira, 15 de setembro de 2011

Tutorial wxWidgets e sqlite3 parte 14 - Excluindo registros

Para finalizar o sistema, vamos escrever a função para deletar os registros.

Ela vai funcionar da seguinte maneira:

Vamos criar uma função que vai receber o ID do registro que está sendo editado, vamos passar este ID para um comando SQL, vamos chamar ExecuteUpdate(SQL).

Escreva a função:

sqlf.h
//Função para deletar um registro...
//Passo como parâmetro o ID do registro que será deletado...
void DeleteInDB(wxString ID);

sqlf.cpp
void DeleteInDB(wxString ID)
{
    //Abro o banco de dados
    wxSQLite3Database *db = OpenDB(GetExecPath() + wxT("/agenda.db3"));

    //SQL para deletar o registro...
    wxString SQL = wxT("DELETE FROM contatos WHERE ID=") + ID + wxT(";");

    //ExecuteUpdate para deletar o registro...
    db->ExecuteUpdate(SQL);

    //Fecho db...
    CloseDB(db);
}

Agora vamos chamar esta função no frame principal, na função OnClickDelete.

Nó vamos confirmar com o usuário se ele quer mesmo que delete o registro, depois deletamos o registro.

framep.cpp
//Aqui o evento quando eu clicar no botão deletar...
void wxFramePrincipal::OnClickDeletar(wxCommandEvent& event)
{
    //Vamos verificar também se o registro está em modo de edição...
    //Pois se não estiver, não teremos quem deletar lá no banco de dados...
    if(ID == -1)
        return;

    //Vamos perguntar primeiro se o usuário tem certeza que quer deletar o registro...
    int confirma = wxMessageBox(wxT("Tem certeza que quer deletar o registro?"), wxT("Confirmação"), wxYES_NO);

    //Se o usuário clicar em não, cancelo a função...
    if(confirma == wxNO)
        return;

    //Executo a função para deletar o registro...
    DeleteInDB(wxString::Format(wxT("%d"), ID));

    //Após deletarmos um registro atualizamos o wxGrid lista contatos...
    SelectInDB(lista_contatos);

    //E limpamos os campos de edição...
    LimparCampos();
}

Pronto, o sistema está completo, agora vocês podem refazer o mesmo, adicionando novas funcionalidades, adicionando outros campos, tabelas, etc...

Espero que tenham aproveitado a sequencia de tutoriais sobre wxWidgets e sqlite3 usando a biblioteca wxSqlite3.

Até a próxima.

quarta-feira, 14 de setembro de 2011

Tutorial wxWidgets e sqlite3 parte 13 - Editando valores no banco de dados

A edição de dados vai ser feita com base na função de inserção de dados, para isto criaremos a mesma nos arquivos sqlf.* do projeto.

Como ela irá funcionar:

Nó passaremos como parâmetros, o ID do registro que está sendo editado, para fazermos o controle na cláusula WHERE do SQL, passaremos também o nome que foi editado e a idade.

Antes de executarmos qualquer alteração verificamos se os dados são válidos, se não estão em branco ou se idade é realmente um número.

O comando usado aqui será o ExecuteQuery(), o mesmo usado na inserção dos dados.

Vamos escrever.

No arquivo sqlf.h digite:

sqlf.h
//Aqui a função para editar os dados...
void UpdateDB(wxString ID, wxString nome, wxString idade);

No arquivo sqlf.cpp:

sqlf.cpp
void UpdateDB(wxString ID, wxString nome, wxString idade)
{
    //Primeiro vejo se o nome ou idade estão em branco
    if(nome.IsEmpty() || idade.IsEmpty())
    {
        //Aviso ao usuário que algum dado está em branco:
        wxMessageBox(wxT("Nenhum campo pode estar em branco!"));
        //Cancelo a função...
        return;
    }

    //Agora preciso ver se a idade é um número...
    //Crio um long int
    long int confere_idade;

    //Tento converter a string idade em um número...
    if(!idade.ToLong(&confere_idade))
    {
        //Se não conseguir, significa que ele não é um inteiro...
        //Aviso o usuário...
        wxMessageBox(wxT("O valor da idade (") + idade + wxT(") não é um número"));
        //Cancelo a função...
        return;
    }

    //Se chegamos até aqui, é porque tudo está correto...
    //Vamos abrir o banco de dados:
    wxSQLite3Database *db = OpenDB(GetExecPath() + wxT("/agenda.db3"));

    //Agora vamos montar o sql para editar os dados...
    wxString SQL = wxT("UPDATE contatos \n");
    SQL += wxT("SET NOME = '") + nome + wxT("',\n");
    SQL += wxT("IDADE = ") + idade + wxT("\n");
    SQL += wxT(" WHERE ID = ") + ID + wxT(";");

    //Agora executo a função ExecuteUpdate, que vimos no tutorial inserir, passando como
    //parâmetro a wxString SQL...
    db->ExecuteUpdate(SQL);

    //Fecho db...
    CloseDB(db);
}


Agora vamos chamar a mesma em framep.cpp:

framep.cpp
if(ID == -1)
    {
        //Se a variável ID for = -1, é porque estamos em inserção...
        //E passamos as duas como parâmetros para a função InsertInDB()...
        InsertInDB(get_nome, get_idade);
    }
    else
    {
        //Pegamos o valor do ID...
        wxString get_id = wxString::Format(wxT("%d"), ID);
        //Passamos como parâmetros, para a função...
        UpdateDB(get_id, get_nome, get_idade);
    }


Pequenas alterações que fiz na GUI do sistema.

framep.cpp
//Adicionei um tamanho padrão para a janela...
this->SetSize(wxSize(450, 350));

//Adiciono o box dos botões ao box principal...
//Aqui arrumei o tamanho do sizer dos botões em relação
//a janela e dei um espaço de 10px na base
boxp->Add(box_btns, 0, wxEXPAND|wxBOTTOM, 10);

Estamos quase terminando nosso sistema, falta apenas implementar a função de deletar...

Até a próxima.

Tutorial wxWidgets e sqlite3 parte 12 - Limpando os Campos após alterações e aproveitando para acertar algumas coisas...

Nesta parte do tutorial, iremos implementar a função LimparCampos(), do arquivo framep.cpp.

O que ela irá fazer?

1 – Vai alterar o valor de ID para -1, ou seja, cancelar a edição...
2 – Vai limpar o campo nome.
3 – Vai limpar o campo idade.
4 – Alterar o título da janela para modo de inserção.

O código vai ficar assim:

Digite o seguinte em framep.cpp

framep.cpp
//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()
{
    //A função mais simples de todas...
    //Será usada na criação do frame.
    //Na função OnClickSalvar
    //Na função OnClickLimpar
    //e na função OnClickDeletar

    //Primeiro vamos alterar o valor do ID para -1
    //Para voltarmos ao modo de Inserção...
    ID = -1;

    //Agora limpamos o nome...
    nome->Clear();

    //limpamos o campo idade...
    idade->Clear();

    //Alteramos o valor da janela para modo de Inserção...
    this->SetTitle(wxT("Teste Tutorial Sqlite3 - Modo de Inserção"));
}

Agora vamos chamá-la no final da criação do frame 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();

    //Aqui chamo a função limpar campos...
    LimparCampos();

    //Vamos carregar os dados no grid...
    SelectInDB(lista_contatos);
}

Também no final da função OnClickSalvar

    }

    //Após editarmos um valor, recarregamos os valores no grid...
    SelectInDB(lista_contatos);

    //E também limpamos os valores de edição/inserção...
    LimparCampos();
}

Aproveitamos para implementar a função OnClickLimpar

//Aqui o evento que vai limpar os campos...
void wxFramePrincipal::OnClickLimpar(wxCommandEvent& event)
{
    //Chamamos a função LimparCampos()...
    LimparCampos();
}

E adiantamos algumas coisas na função OnClickDeletar

//Aqui o evento quando eu clicar no botão deletar...
void wxFramePrincipal::OnClickDeletar(wxCommandEvent& event)
{
    //Vamos verificar também se o registro está em modo de edição...
    //Pois se não estiver, não teremos quem deletar lá no banco de dados...
    if(ID == -1)
        return;

    //Após deletarmos um registro atualizamos o wxGrid lista contatos...
    SelectInDB(lista_contatos);

    //E limpamos os campos de edição...
    LimparCampos();
}


Vejam que tínhamos uma função chamada ConfereCampos em framep.h e framep.cpp, por descuido, acabei implementando isto na função de inserir registros de sqlf.cpp, para não enrolarmos a continuidade do tutorial, deletem esta função ConfereCampos dos dois arquivos, o *.h e o *.cpp.

Mais uma parte do tutorial concluída, no próximo iremos finalizar o código do tutorial.

Até a próxima.

Tutorial wxWidgets e sqlite3 parte 11 - Passando os dados do wxGrid para a edição

Hoje vamos escrever a função do duplo click no wxGrid.

O objetivo desta função é:

Ao clicar duas vezes em alguma célula do wxGrid lista_contatos, pegaremos a linha que foi clicada, depois passaremos os valores do ID, NOME e IDADE para seus respectivos valores de edição que são:

A variável ID que vai controlar se estamos em modo de edição ou não, se for em modo de edição qual registro que está sendo editado.

A caixa de texto nome.

A caixa de texto idade.

Vamos ao código:

Em framep.cpp, altere a seguinte parte:

framep.cpp
//Aqui o evento que será executado
//quando eu der 2 cliques em uma célula...
void wxFramePrincipal::OnDoubleClickCell(wxGridEvent& event)
{
    //Primeiro vamos pegar o índice da linha que está sendo clicada:
    int row = event.GetRow();

    //Agora vamos passar os valores desta linha para nossos dados...

    //Primeiro a variável ID
    long int get_id;
    lista_contatos->GetCellValue(row, 0).ToLong(&get_id);

    ID = get_id;
    //Veja que neste momento, a varável ID assume um valor maior que -1
    //Então entramos no modo de edição...

    //Agora pego o valor atual para nome...
    nome->SetValue(lista_contatos->GetCellValue(row, 1));

    //E por último a idade...
    idade->SetValue(lista_contatos->GetCellValue(row, 2));

    //Agora podemos fazer as alterações dos valores, passando como parâmetro
    //o valor do ID...

    //Uma alteração que podemos fazer também é
    //colocar um aviso no título da janela
    //para dizer ao usuário qual a função que ele está executando:

    this->SetTitle(wxT("Teste Tutorial Sqlite3 - Modo de Edição"));
}

Pronto, agora o usuário poderá selecionar qual registro ele quer editar.

No próximo tutorial, implementar a função que limpa os campos após as edições.

Até a próxima.

sexta-feira, 9 de setembro de 2011

Tutorial wxWidgets e sqlite3 parte 9 - Inserindo valores no banco de dados


Hoje vamos ver como inserir valores no banco de dados.

Primeiro, devemos entender como o processo de inserção será feito pelo programa:

Existem dois campos do tipo wxTextCtrl no wxFrame que controla a aplicação, nós pegaremos os valores dessas caixas de texto, veremos primeiro se o nome está em branco e se a idade realmente é um número, se as duas afirmações forem verdadeiras executamos a função que insere os valores no banco de dados, se não, cancelamos a função e avisamos o usuário que os dados estão incompletos ou errados.

Mas vamos lembrar uma coisa, quando clicamos no botão salvar, podemos ter uma ação de inserção ou de edição, para isto, temos a variável de controle chamada ID, que criamos no frame principal, veja que ela inicia com o valor -1, então, sempre que tivermos este valor, a ação será de inserção.

Vamos lembrar como ficaria o código SQL para inserirmos um valor na nossa tabela contatos:

INSERT INTO contatos(ID, NOME, IDADE) VALUES(NULL, 'NOME DO CONTATO', 1);

Vejam que uso apóstrofo entre valores do tipo VARCHAR, e passamos o ID que é chave primária como NULL.

O nome do contato, será o valor que foi digitado na caixa de texto Nome e sua idade será o valor que está na caixa de texto Idade.

Para fazer esta inserção vamos criar uma função que vai pegar estes dois valores e verificar se estão corretos e fazer a inserção, ficará assim:

Em sqlf.h digite:

sqlf.h
//Aqui escrevo uma função que vai receber o nome e a idade como parametros...
void InsertInDB(wxString nome, wxString idade);

Agora vamos implementá-la em sqlf.cpp, digite:

sqlf.cpp
//Vamos Implementá-la
void InsertInDB(wxString nome, wxString idade)
{
    //Primeiro vejo se o nome ou idade estão em branco
    if(nome.IsEmpty() || idade.IsEmpty())
    {
        //Aviso ao usuário que algum dado está em branco:
        wxMessageBox(wxT("Nenhum campo pode estar em branco!"));
        //Cancelo a função...
        return;
    }

    //Agora preciso ver se a idade é um número...
    //Crio um long int
    long int confere_idade;

    //Tento converter a string idade em um número...
    if(!idade.ToLong(&confere_idade))
    {
        //Se não conseguir, significa que ele não é um inteiro...
        //Aviso o usuário...
        wxMessageBox(wxT("O valor da idade (") + idade + wxT(") não é um número"));
        //Cancelo a função...
        return;
    }

    //Se chegamos até aqui, é porque tudo está correto...
    //Vamos abrir o banco de dados:
    wxSQLite3Database *db = OpenDB(GetExecPath() + wxT("/agenda.db3"));

    //Agora vamos montar o sql para inserir os dados...
    wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES(NULL, '");
    SQL += nome + wxT("', ");
    SQL += idade + wxT(");");

    //Reparem que adiciono os apóstrofos apenas nos campos VARCHAR...
    //Tenham muito cuidado quando montarem comandos SQL, para não adicionarem
    //valores incorretos, como virgulas após o ultimo campo
    //esquecerem-se de fechar parenteses, etc...

    //uma maneira simples é fazer o seguinte...
    //Escreva o comando todo SQL...

    //wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES (NULL, 'NOME', IDADE);");

    //Agora adicione as variáveis no lugar dos valores com os sinais de concatenação:

    //wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES (NULL, ' + nome + ', + idade + );");

    //Antes de cada + à esquerda da variável adicione ") e depois de cada + à direita da variável adicione wxT("

    //wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES (NULL, '") + nome + wxT("',") + idade + (");");

    //Agora executo a função ExecuteUpdate, que vimos no tutorial anterior, passando como
    //parâmetro a wxString SQL...
    db->ExecuteUpdate(SQL);

    //Fecho db...
    CloseDB(db);
}

E pra finalizarmos, vamos chamar esta função no evento OnClickSalvar() do frame principal:

Veja que já adicionei a estrutura condicional para sabermos se está em edição ou inserção:

Em framep.cpp digite:

framep.cpp
//Aqui eu inicio a implementação do evento para salvar ou editar um registro...
void wxFramePrincipal::OnClickSalvar(wxCommandEvent& event)
{
    //Vamos, primeiro, verificar qual operação será feita
    //Inserção ou Edição
    if(ID == -1)
    {
        //Se a variável ID for = -1, é porque estamos em inserção...
        //Vamos pegar os valores do campo nome...
        wxString get_nome = nome->GetValue();
        //...agora pegamos a idade...
        wxString get_idade = idade->GetValue();

        //E passamos as duas como parâmetros para a função InsertInDB()...
        InsertInDB(get_nome, get_idade);
    }
    else
    {
    }
}

Vamos testar a função, abrindo o terminal ou o prompt de comando do Windows:

Abra o banco de dados com o comando:
> sqlite3 caminho/para/o/banco_de_dados/agenda.db3


Agora abra o sistema e adicione alguns valores, veja que após inserirmos os valores, os campos continuam preenchidos, iremos alterar isto nos próximos tutoriais.


Agora volte para o terminal e faça uma seleção na tabela contatos:

>SELECT * FROM contatos;


Vejam que os registros já estão lá.


Dúvidas, deixem nos comentários.

Os arquivos alterados completos:

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();

//Aqui escrevo uma função que vai receber o nome e a idade como parametros...
void InsertInDB(wxString nome, wxString idade);

#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);
}

//Vamos Implementá-la
void InsertInDB(wxString nome, wxString idade)
{
    //Primeiro vejo se o nome ou idade estão em branco
    if(nome.IsEmpty() || idade.IsEmpty())
    {
        //Aviso ao usuário que algum dado está em branco:
        wxMessageBox(wxT("Nenhum campo pode estar em branco!"));
        //Cancelo a função...
        return;
    }

    //Agora preciso ver se a idade é um número...
    //Crio um long int
    long int confere_idade;

    //Tento converter a string idade em um número...
    if(!idade.ToLong(&confere_idade))
    {
        //Se não conseguir, significa que ele não é um inteiro...
        //Aviso o usuário...
        wxMessageBox(wxT("O valor da idade (") + idade + wxT(") não é um número"));
        //Cancelo a função...
        return;
    }

    //Se chegamos até aqui, é porque tudo está correto...
    //Vamos abrir o banco de dados:
    wxSQLite3Database *db = OpenDB(GetExecPath() + wxT("/agenda.db3"));

    //Agora vamos montar o sql para inserir os dados...
    wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES(NULL, '");
    SQL += nome + wxT("', ");
    SQL += idade + wxT(");");

    //Reparem que adiciono os apóstrofos apenas nos campos VARCHAR...
    //Tenham muito cuidado quando montarem comandos SQL, para não adicionarem
    //valores incorretos, como virgulas após o ultimo campo
    //esquecerem-se de fechar parenteses, etc...

    //uma maneira simples é fazer o seguinte...
    //Escreva o comando todo SQL...

    //wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES (NULL, 'NOME', IDADE);");

    //Agora adicione as variáveis no lugar dos valores com os sinais de concatenação:

    //wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES (NULL, ' + nome + ', + idade + );");

    //Antes de cada + à esquerda da variável adicione ") e depois de cada + à direita da variável adicione wxT("

    //wxString SQL = wxT("INSERT INTO contatos(ID, NOME, IDADE) VALUES (NULL, '") + nome + wxT("',") + idade + (");");

    //Agora executo a função ExecuteUpdate, que vimos no tutorial anterior, passando como
    //parâmetro a wxString SQL...
    db->ExecuteUpdate(SQL);

    //Fecho db...
    CloseDB(db);
}


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

#include "framep.h"
#include "sqlf.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 ou editar um registro...
void wxFramePrincipal::OnClickSalvar(wxCommandEvent& event)
{
    //Vamos, primeiro, verificar qual operação será feita
    //Inserção ou Edição
    if(ID == -1)
    {
        //Se a variável ID for = -1, é porque estamos em inserção...
        //Vamos pegar os valores do campo nome...
        wxString get_nome = nome->GetValue();
        //...agora pegamos a idade...
        wxString get_idade = idade->GetValue();

        //E passamos as duas como parâmetros para a função InsertInDB()...
        InsertInDB(get_nome, get_idade);
    }
    else
    {
    }
}

//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;
}


No próximo tutorial, vamos exibir os valores inseridos no wxGrid.

Até a próxima.

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.