quinta-feira, 22 de outubro de 2015

GTK & PostgreSQL usando C

Vamos Criar uma tela de Login, para tal precisamos de algumas dependências para começar o jogo...

Procure pelas Bibliotecas: libpq-fe, gtk-+3

No caso de estiver usando o Debian entre como root no terminal e Execute:

apt-get install libpq-dev libgtk-3-dev
Para que possamos Testar recomendo a Instalação dos:

apt-get install postgesql pgadmin3
                             ________________________________________


Vamos começar com a GUI do Software.

crie um arquivo teste.c  e adicione os códigos a seguir:
Verificamos se as Bibliotecas foram encontradas.

                             ________________________________________
#include <gtk/gtk.h>
#include <libpq-fe.h>
#include <string.h>
int
main(int argc, char **argv){
    return 0;
}

                             ________________________________________

Crie o Arquivo Makefile que vai ser utilizado para compilar.

FileC = teste
CC = gcc
pgFalgs = -I /usr/include/postgresql -lpq
CFlags = `pkg-config --cflags --libs gtk+-3.0`



all:$(FileC)

$(FileC):$(FileC).o
$(CC) $(FileC).o -o $(FileC) $(CFlags) $(pgFalgs)

$(FileC).o:$(FileC).c
$(CC) -c $(FileC).c $(CFlags) $(pgFalgs)
@echo "O Arquivo $(FileC).o está Pronto"

clean:
rm $(FileC) $(FileC).o

run:$(FileC)
./$(FileC)


 ________________________________________

Para Compilar e rodar abra o terminal na Pasta no arquivo teste.c e Makefile, e rode o comando

$    make run

Agora vamos criar a janela em GTK.

 ________________________________________
/*Arquivo teste.c*/

#include <gtk/gtk.h>
#include <libpq-fe.h>
#include <string.h>

GtkWidget* window;

static void
activate (GtkApplication *app, gpointer user_data){
    /* Construimos a Janela */
    window = gtk_application_window_new (app);
    gtk_window_set_title(GTK_WINDOW(window), "Tela de Login");
    gtk_window_set_default_size (GTK_WINDOW (window), 100, 100);
    gtk_window_set_resizable(GTK_WINDOW(window), FALSE);

    gtk_widget_show_all (window);//mostramos tudo que esta na janela

}

int
main(int argc, char **argv){
    GtkApplication *app;
    int status;
    app = gtk_application_new ("login.teste", G_APPLICATION_FLAGS_NONE);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);
    return status;
}


 ________________________________________

O código acima ira criar uma janela, com o titulo "Tela de Login", do tamanho 100x100.
Agora vamos inserir o resto dos componentes a GUI.



 ________________________________________
/*Arquivo teste.c*/

#include <gtk/gtk.h>
#include <libpq-fe.h>
#include <string.h>

GtkWidget* window;
static GtkWidget
    *password_entry,
    *user_entry;
static void
activate (GtkApplication *app, gpointer user_data){
    GtkWidget *button, *combo_db;
    GtkWidget *conteudo, *conteudo1, *conteudo2;
    GtkWidget *label_user, *label_password;
    /* Construimos a Janela */
    window = gtk_application_window_new (app);
    gtk_window_set_title(GTK_WINDOW(window), "Tela de Login");
    gtk_window_set_default_size (GTK_WINDOW (window), 100, 100);
    gtk_window_set_resizable(GTK_WINDOW(window), FALSE);

    // Container Principal
    conteudo=gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_container_add(GTK_CONTAINER(window), conteudo);

    // Area Do Banco de Dados
    combo_db = gtk_combo_box_text_new ();
    gtk_widget_set_tooltip_text(combo_db, "Banco de Dados.");
 
    gtk_combo_box_set_active (GTK_COMBO_BOX (combo_db), 0);
    gtk_container_add(GTK_CONTAINER(conteudo), combo_db);
 
    // Area do Usuario
    conteudo1=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_container_add(GTK_CONTAINER(conteudo), conteudo1);
    label_user = gtk_label_new("Usuario: ");
    gtk_box_pack_start(GTK_BOX(conteudo1), label_user, FALSE, FALSE, 5);
 
    user_entry=gtk_entry_new();
    gtk_widget_set_tooltip_text(user_entry, "Usuario do Sistema.");
    gtk_entry_set_placeholder_text(GTK_ENTRY(user_entry), "Usuario");
    gtk_box_pack_start(GTK_BOX(conteudo1), user_entry, FALSE, FALSE, 2);
 
    // Area da Senha
    conteudo2=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_container_add(GTK_CONTAINER(conteudo), conteudo2);
    label_password = gtk_label_new("Senha: ");
    gtk_box_pack_start(GTK_BOX(conteudo2), label_password, FALSE, FALSE, 5);
 
    password_entry=gtk_entry_new();
    gtk_entry_set_visibility(GTK_ENTRY(password_entry), FALSE);
    gtk_widget_set_tooltip_text(password_entry, "Senha do Usuario do Sistema.");
    gtk_entry_set_placeholder_text(GTK_ENTRY(password_entry), "Senha");
    gtk_box_pack_start(GTK_BOX(conteudo2), password_entry, FALSE, FALSE, 14);
 
    // Inserir Botão
    button = gtk_button_new_with_label("Entrar");

    gtk_container_add(GTK_CONTAINER(conteudo), button);
    gtk_widget_show_all (window);//mostramos tudo que esta na janela

}

int
main(int argc, char **argv){
    GtkApplication *app;
    int status;
    app = gtk_application_new ("login.teste", G_APPLICATION_FLAGS_NONE);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);
    return status;
}


 ________________________________________


Agora Vamos Inserir os métodos e Funções SQL.



 ________________________________________
/*Arquivo teste.c*/

#include <gtk/gtk.h>
#include <libpq-fe.h>
#include <string.h>
typedef char* String;
/*Objeto de conexão*/
static PGconn *conn = NULL;
/*Ponteiro de resultado*/
static PGresult *result;

static GtkWidget
    *password_entry,
    *user_entry;

GtkWidget* window;
static void
MsgBox(String txt, GtkWindow *window);

int
conexao(String dbName){
    String pghost="localhost",
           pgport="5432",
           pgoptions=NULL,
           pgtty=NULL,
           login="",
           pwd="";
    if (!dbName)
        dbName = "postgres";
    conn = PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName, login, pwd);
    if(PQstatus(conn) == CONNECTION_OK){
        printf("Conexão efetuada com sucesso.\n");
    }else{
        printf("Falha na conexão. Erro: %s\n", PQerrorMessage(conn));
        PQfinish(conn);
        return 1;
    }
    return 0;
}

void
exit_conexao(){
    /*Libera o nosso objeto*/
    if (result)
        PQclear(result);
    /*Verifica se a conexão está aberta e a encerra*/
    if(conn != NULL)
        PQfinish(conn);
}

static void
complet_combo_db(GtkWidget *combo_box){
    if (conexao(NULL))
        return;
    /*Executa o comando*/
    result = PQexec(conn, "select datname from pg_database where datistemplate=False;");
 
    if(!result)
    {
        printf("Erro executando comando. ");
    }
    else
    {
        switch(PQresultStatus(result))
        {
            case PGRES_EMPTY_QUERY:
                printf("Nada aconteceu.\n");
                break;
            case PGRES_TUPLES_OK:
                printf("A query retornou %d linhas.\n", PQntuples(result));
                break;
            case PGRES_FATAL_ERROR:
                printf("Erro na Consulta: %s\n", PQresultErrorMessage(result));
                break;
            case PGRES_COMMAND_OK:
                printf("%s linhas afetadas.\n", PQcmdTuples(result));
                break;
            default:
                printf("Algum outro resultado ocorreu.\n");
                break;
        }
    }
 
    /* Pegamos a Quantidade de campos capturados */
    int campos = PQnfields(result);
    int count  = PQntuples(result);
 
    int i,j;
    for(i = 0; i < count; i++)
    {
        // Percorre todas as colunas
        for (j = 0; j < campos; j++)
        {
            // Imprime o valor do campo
            gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_box), PQgetvalue(result, i, j));
        }
    }
    return exit_conexao();
}

static void
login_action (GtkButton *button,
                gpointer   user_data)
{
    const char *paramValues[2];
 
    int status_conn;
    String senha, usuario;
    senha   = (String) gtk_entry_get_text( GTK_ENTRY( password_entry ) );
    usuario = (String) gtk_entry_get_text( GTK_ENTRY( user_entry     ) );
    /* Verificamos se os campos Login e Senha estão preenchidos */
    if ( strcmp( usuario, "" ) == 0){
        MsgBox("O Campo Usuario Não foi Preenchido...", GTK_WINDOW(window));
        return;
    }
 
    if ( strcmp( senha, "" ) == 0){
        MsgBox("O Campo Senha Não foi Preenchido...", GTK_WINDOW(window));
        return;
    }
 
    /* Agora Abrimos a conexao */
    String dbName = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT(user_data));
    if (conexao(dbName))
        return;
 
    /*Executa o comando*/
    paramValues[0] = usuario;
    paramValues[1] = senha;

    result = PQexecParams(conn,
                       "SELECT count(*) FROM users WHERE login = $1",
                       1,       /* one param */
                       NULL,    /* let the backend deduce param type */
                       paramValues,
                       NULL,    /* don't need param lengths since text */
                       NULL,    /* default to all text params */
                       0);      /* ask for binary results */
    if (PQresultStatus(result) != PGRES_TUPLES_OK)
    {
        printf( "SELECT Falho: %s", PQerrorMessage(conn));
        exit_conexao();
        printf("O sistema Não Foi Instado na Base: %s\n",dbName);
        return;
    }
 
    /* Verificamos se o User Existe*/
    int num_records, i;
    num_records = PQntuples(result);
    for(i = 0 ; i < num_records ; i++)
    {
        if (strcmp(PQgetvalue(result, i, 0),"0" ) == 0){
            MsgBox("Usuario Não existe...", GTK_WINDOW(window));
            exit_conexao();
            return;
        }
    }
 
    /* Verificamos a Senha do Usuario */
    result = PQexecParams(conn,
                       "SELECT count(*) FROM users WHERE login = $1 and password = $2",
                       2,       /* two param */
                       NULL,    /* let the backend deduce param type */
                       paramValues,
                       NULL,    /* don't need param lengths since text */
                       NULL,    /* default to all text params */
                       0);      /* ask for binary results */
    if (PQresultStatus(result) != PGRES_TUPLES_OK)
    {
        printf( "SELECT failed: %s", PQerrorMessage(conn));
        exit_conexao();
    }
    num_records = PQntuples(result);
    for(i = 0 ; i < num_records ; i++)
    {
        if (strcmp(PQgetvalue(result, i, 0),"0" ) == 0){
            MsgBox("Senha Errada...", GTK_WINDOW(window));
            exit_conexao();
            return;
        }
    }
    exit_conexao();
}

static void
activate (GtkApplication *app, gpointer user_data){
    GtkWidget *button, *combo_db;
    GtkWidget *conteudo, *conteudo1, *conteudo2;
    GtkWidget *label_user, *label_password;
    /* Construimos a Janela */
    window = gtk_application_window_new (app);
    gtk_window_set_title(GTK_WINDOW(window), "Tela de Login");
    gtk_window_set_default_size (GTK_WINDOW (window), 100, 100);
    gtk_window_set_resizable(GTK_WINDOW(window), FALSE);

    // Container Principal
    conteudo=gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_container_add(GTK_CONTAINER(window), conteudo);

    // Area Do Banco de Dados
    combo_db = gtk_combo_box_text_new ();
    gtk_widget_set_tooltip_text(combo_db, "Banco de Dados.");
    complet_combo_db(combo_db);// o Encarregado de Preencher o ComboBox
    gtk_combo_box_set_active (GTK_COMBO_BOX (combo_db), 0);
    gtk_container_add(GTK_CONTAINER(conteudo), combo_db);
 
    // Area do Usuario
    conteudo1=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_container_add(GTK_CONTAINER(conteudo), conteudo1);
    label_user = gtk_label_new("Usuario: ");
    gtk_box_pack_start(GTK_BOX(conteudo1), label_user, FALSE, FALSE, 5);
 
    user_entry=gtk_entry_new();
    gtk_widget_set_tooltip_text(user_entry, "Usuario do Sistema.");
    gtk_entry_set_placeholder_text(GTK_ENTRY(user_entry), "Usuario");
    gtk_box_pack_start(GTK_BOX(conteudo1), user_entry, FALSE, FALSE, 2);
 
    // Area da Senha
    conteudo2=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_container_add(GTK_CONTAINER(conteudo), conteudo2);
    label_password = gtk_label_new("Senha: ");
    gtk_box_pack_start(GTK_BOX(conteudo2), label_password, FALSE, FALSE, 5);
 
    password_entry=gtk_entry_new();
    gtk_entry_set_visibility(GTK_ENTRY(password_entry), FALSE);
    gtk_widget_set_tooltip_text(password_entry, "Senha do Usuario do Sistema.");
    gtk_entry_set_placeholder_text(GTK_ENTRY(password_entry), "Senha");
    gtk_box_pack_start(GTK_BOX(conteudo2), password_entry, FALSE, FALSE, 14);
 
    // Inserir Botão
    button = gtk_button_new_with_label("Entrar");
    g_signal_connect (GTK_BUTTON (button),
                    "clicked",
                    G_CALLBACK (login_action),
                    G_OBJECT (combo_db));
    gtk_container_add(GTK_CONTAINER(conteudo), button);
    gtk_widget_show_all (window);//mostramos tudo que esta na janela

}

int
main(int argc, char **argv){
    GtkApplication *app;
    int status;
    app = gtk_application_new ("login.teste", G_APPLICATION_FLAGS_NONE);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);
    return status;
}

static void
on_response (GtkDialog *dialog,
             gint       response_id,
             gpointer   user_data){
  gtk_widget_destroy (GTK_WIDGET (dialog));
}

static void
MsgBox(String txt, GtkWindow *window){
    g_print("%s\n",txt);
    GtkWidget *dialog;
    GtkWidget *content_area;
    GtkWidget *label;

    gint response_id;

    dialog = gtk_dialog_new_with_buttons ("Aviso...",
                                        window,
                                        GTK_DIALOG_MODAL,
                                        GTK_STOCK_OK,
                                        GTK_RESPONSE_OK,
                                        NULL);

    content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
    label = gtk_label_new (txt);
    gtk_container_add (GTK_CONTAINER (content_area), label);
    gtk_widget_show_all (dialog);
    g_signal_connect (GTK_DIALOG (dialog),
                    "response",
                    G_CALLBACK (on_response),
                    NULL);
}
 ________________________________________




Para concluir a brincadeira você precisa criar no PostgreSQL a Tabelas users, com os campos login e password, os dois do tipo varchar.

Nenhum comentário:

Postar um comentário