Guia de Programação em C/GTK 2 - Construindo uma Calculadora Completa

Neste guia, você aprenderá os princípios básicos de GTK, como posicionar os elementos na interface e entender a teoria de sinais. Ao longo do guia, iremos construir uma calculadora completa em C/GTK 2 com botões numéricos, entrada para texto, cálculos com valores flutuantes e negativos, múltiplos operadores e muito mais.

[ Hits: 12.584 ]

Por: Mateus Moutinho em 17/03/2020


Construindo as Funções - Finalizando o Programa



O código desta página será iniciado a partir do arquivo da aula anterior calculadora4.c, caso não esteja com ele, baixe-o e renomeie para "calculadora.c".

Compile com o seguinte comando:

gcc calculadora.c -o calculadora.out `pkg-config --cflags --libs gtk+-2.0`

Execute com:

./calculadora.out

Criando as Funções

Nesta página criaremos todas as funções de nossa calculadora e, ao final dela, nosso programa estará totalmente finalizado. O conteúdo será bem denso, então se não tem um café em mãos, a primeira coisa que deve fazer é ir preparar um. Posteriormente, pegue o código da última página e troque o nome para "calculadora.c" e vamos começar.

Função Quantifica Números Totais

Por motivos estruturais de compilação, essa função deverá ser a primeira, já que ela será usada por todas as outras, então, acima da função "insere_numeros_validos" inicie uma função com retorno "int" que exige uma "string" como argumento, ficando dessa forma:

int quantifica_numeros_totais(const char *entrada_de_texto){}

Dentro da função criaremos um contador que servirá como incremento para nossa própria instrução, então:

int contador = 0;

Logo após, criaremos uma chamada de laço "for", com o os seguintes argumentos:
  • contador como condição inicial 0.
  • a "entrada_de_texto[contador]" diferente de 0 (0 na tabela ASCII é = NULL para caracteres).
  • +1 de incremento no contador a cada ciclo.

O código fica assim:

for (contador = 0; entrada_de_texto[contador] != 0; ++contador){}

Dessa forma, o nosso contador vai parar exatamente no ponto que a entrada de texto do nosso programa está vazia. Agora, faremos a chamada de retorno da função:

return (contador);

A função completa fica assim:
Linux: Guia de Programação em C / GTK 2 (Construindo uma Calculadora Completa)

Função Insere Numero na Entrada

Para a começar a função, apague o "printf" que fizemos na última aula.

A primeira constante que teremos que declarar será a "entrada_de_texto", para isso faremos com que ela receba o retorno da função "gtk_entry_get_text", ficando assim:

const char *entrada_de_texto =  gtk_entry_get_text(GTK_ENTRY(entrada));

A segunda constante será a "quantidade_de_numeros_totais", que será obtida pelo retorno da função "quantifica_numeros_totais", ficando assim:

const int quantidade_de_numeros = quantifica_numeros_totais(entrada_de_texto);

Agora iremos criar a primeira das 5 estruturas condicionais que nosso código terá. Ela será responsável por retornar a "main", caso a quantidade de números na entrada seja superior a 8 caracteres, ficando assim:

if (quantidade_de_numeros > 8){return ;}

Agora iremos criar nosso vetor de saída, que iremos usar para concatenar com o conteúdo do nosso ponteiro que recebemos como argumento.

char vetor_de_saida[9];

Há uma grande polêmica quando o assunto é concatenação vetores em C (essa briga é pior que pizza com ketchup), cada programador tem sua gambiarra favorita eu particularmente uso o "sprintf", mas caso essa não seja a sua, basta trocar o código pela sua.

O código abaixo concatena a "entrada_de_texto" com o conteúdo do ponteiro "numero" e insere no "vetor_de_saida[9]":

sprintf(vetor_de_saida,"%s%c",entrada_de_texto,*(char *)numero);

Agora criamos a "string_de_saida" e apontamos ela para o endereço do "vetor_de_saida", assim:

const char *string_de_saida = &vetor_de_saida[0];

Depois basta chamar a função "gtk_entry_set_text" e passar a "string_de_saida", como argumento:

gtk_entry_set_text(GTK_ENTRY(entrada),string_de_saida);

A função completa fica assim:
Linux: Guia de Programação em C / GTK 2 (Construindo uma Calculadora Completa)
Compile e execute o código, se tudo der certo, todos os números serão inseridos na entrada quando clicados.
Linux: Guia de Programação em C / GTK 2 (Construindo uma Calculadora Completa)

Função Registra Operador

Para começar a fazer a função, apague o "printf" feito na aula anterior e crie as mesmas duas constantes inicias que criamos na função anterior:

const char *entrada_de_texto =  gtk_entry_get_text(GTK_ENTRY(entrada));

const int quantidade_de_numeros = quantifica_numeros_totais(entrada_de_texto);

Após isso, iremos criar a segunda condicional do nosso código. Ela servirá para determinar se a quantidade de caracteres da entrada é igual a 0 e se o operador clicado é o de subtração. Se for, ela chama a função "inseri_numero_na_entrada" passando a estrutura de widgets que recebemos como argumento para a função "inseri_numero_na_entrada" e após isso, damos o comando "return" para voltar para a "main", ficando assim:

if
   (quantidade_de_numeros == 0 && *(char*)operador == '-')
   {inseri_numero_na_entrada(botao,operador);
   return;}

A segunda condicional será caso a entrada for igual a zero, a função deve parar e voltar para a "main". Como o operador já foi capturado pela condicional anterior, não há necessidade de adicionar um "!= -".

Então, o código fica assim:

if(quantidade_de_numeros == 0){return;}

Agora que terminamos o tratamento de exceções e erros, devemos fazer a captura do "num1". Como a entrada da calculadora está em formato de string, para fazer a conversão para formato numérico real, devemos usar a seguinte função:

num1 = atof(entrada_de_texto);

E, posteriormente, registramos o operador com:

operador_final = *(char *)operador;

E, finalmente, limpamos a tela do usuário através da função (sim, as aspas estão vazias, indicando que a entrada não estará vazia):

gtk_entry_set_text(GTK_ENTRY(entrada),"");

A função completa fica assim:
Linux: Guia de Programação em C / GTK 2 (Construindo uma Calculadora Completa)

Função Imprime Resultado Nn Entrada

Para começar a fazer a função, apague o "printf" feito na aula anterior e crie as mesmas duas constantes inicias que criamos na função anterior:

const char *entrada_de_texto =  gtk_entry_get_text(GTK_ENTRY(entrada));

const int quantidade_de_numeros = quantifica_numeros_totais(entrada_de_texto);

Colocamos uma condicional para caso a entrada for igual a zero, ele volta para a "main" dessa forma:

if (quantidade_de_numeros == 0){return;}

Agora, convertemos o número 2 através da função:

num2 = atof(entrada_de_texto);

Logo em seguida, criamos uma "double" para armazenar o resultado:

double resultado;

E criamos também o nosso vetor para a concatenação:

char resultado_em_vetor [20];

Em seguida, criaremos um "switch" para determinar o resultado de acordo com o "char operador_final":

switch (operador_final) {

  case '+':
  resultado = num1 + num2;
  break;

  case '-':
  resultado = num1 - num2;
  break;

  case '*':
  resultado = num1 * num2;
  break;

  case '/':
  resultado = num1 / num2;
  break;

}

Posteriormente, fazemos a concatenação com a "double", enviando ela para o nosso vetor:

sprintf(resultado_em_vetor,"%lf",resultado);

Criamos a nossa "string_de_saída" e apontamos ela para o vetor:

const char *resultado_de_saida = &resultado_em_vetor[0];

E por último chamamos, a função "gtk_entry_set_text" e passamos como argumento a "string_de_saida":

gtk_entry_set_text(GTK_ENTRY(entrada),resultado_de_saida);

A função completa fica dessa forma:
Linux: Guia de Programação em C / GTK 2 (Construindo uma Calculadora Completa)

Função Limpa

A função limpa é a mais simples de todas, basta zerar todas as variáveis dessa forma:

operador_final = 0;
num1 = 0;
num2 = 0;

E acionar a função "gtk_entry_set_text" deixando o campo de texto vazio:

gtk_entry_set_text(GTK_ENTRY(entrada),"");

A função completa fica assim:
Linux: Guia de Programação em C / GTK 2 (Construindo uma Calculadora Completa)

Programa Finalizado

Compile e execute o código e se tudo deu certo, tudo já deve estar funcionando corretamente. Caso queira ter uma imersão maior e usar sua própria calculadora, basta logar como root e mover o binário "calculadora.out" para "/bin" e depois definir um lançador para ela na sua interface gráfica.

O programa finalizado está anexado como calculadorapronta.c.

Compile com:

gcc calculadorapronta.c -o calculadora.out `pkg-config --cflags --libs gtk+-2.0`

Execute com:

./calculadora.out

Página anterior    

Páginas do artigo
   1. Introdução
   2. Construindo a Interface - Parte 1: Criando a Janela
   3. Construindo a Interface - Parte 2: Entendendo a estrutura de tabelas
   4. Construindo a Interface - Parte 3: Redigindo o código da interface
   5. Entendendo a Teoria de Sinais GTK
   6. Entendendo o Funcionamento do Programa
   7. Conectando os Botões
   8. Construindo as Funções - Finalizando o Programa
Outros artigos deste autor

DoTheWorld - Biblioteca completa para manipulação de Arquivos e Pastas em C

Leitura recomendada

Tutorial SDL

Linguagem C - Listas Duplamente Encadeadas

Dicas para aprender programação

Linguagem C - Árvores Binárias

Otimização de algoritmos

  
Comentários
[1] Comentário enviado por fabio em 17/03/2020 - 00:10h

Ótimo trabalho, parabéns!

[2] Comentário enviado por mateusmoutinho em 17/03/2020 - 01:29h

opa muito obrigado amigo , logo menos publicarei vários conteúdos sobre programação em C e C++

[3] Comentário enviado por hiperjohn em 28/03/2020 - 19:49h

Mateus, gostei muito do tutorial. Parabéns!

Gostaria de sugerir, caso fosse possível, que vc faça um tutorial sobre como utilizar o Glade para criar a interface gráfica.

Obrigado por compartilhar seu conhecimento!

[4] Comentário enviado por mateusmoutinho em 29/03/2020 - 22:00h


[3] Comentário enviado por hiperjohn em 28/03/2020 - 19:49h

Mateus, gostei muito do tutorial. Parabéns!

Gostaria de sugerir, caso fosse possível, que vc faça um tutorial sobre como utilizar o Glade para criar a interface gráfica.

Obrigado por compartilhar seu conhecimento!


Opa amigo , futuramente posso fazer sim , mas se me permite vou dar te dar uma sugestão, o glade é um ótimo facilitador , porém com ele dificilmente você entenderá a essencia de como funciona a lógica por trás do gtk , então recomendo que para começar estude GTK puro, mas sim irei fazer tutoriais usando o glade sim

[5] Comentário enviado por matheusxreis em 23/09/2021 - 00:50h

Ufa! É extremamente difícil de encontrar bom conteúdo sobre na net. Muito feliz de ter encontrado esse guia aqui.

MUITO obrigado!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts