in Uncategorized

一款很简单的计算器程序

学习GTK+2.0,写了一个小计算器程序,发上来,基本上可以用。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
static GtkWidget *entry;
gdouble mm=0.0; /* define mm for storing first number in operation */
gdouble nn=0.0; /* define nn for storing second number in operation */
gint operator=0; /* define an operator symbol for addition, subtrace, dividing, multiplication */
gboolean first=TRUE; /* define a flag for determining if has another operation before current input or not */
gboolean second=FALSE; /* deine a flag for nn if input or not input */
gboolean has_dot=FALSE; /* define a flag for determining if has dot in current input or not */
gboolean has_result=FALSE; /* define a flag for determing if has a result already or not */
gchar number[100]; /* define a buffer for storing number */

void clear()
{
  int i;
  /* This function for purpose of clear all flags and numbers */
  gtk_entry_set_text(GTK_ENTRY(entry), "0");
  mm=0.0;
  nn=0.0;
  first=FALSE;
  second=FALSE;
  has_dot=FALSE;
  has_result=FALSE;
  for (i=0; 100; i++)
    number[i]='';
}

void number_clear()
{
  int i;
  for (i=0; 100; i++)
    number[i]='';
}

void calculate_last_time()
{
  switch (operator)
    {
    case 1:
      /* Define the operation of addition */
      if(second)
	{
	  g_ascii_dtostr(number, 100, mm+nn);
	  gtk_entry_set_text(GTK_ENTRY(entry), number);
	  mm=mm+nn; /* Set the left operand to be result */
	  number_clear();
	  second=FALSE;
	}
      else
	{
	  /* init second operand */
	  nn=0.0;
	  number_clear();
	}
      break;
    case 2:
      /* Define the operation of subtrace */
      if(second)
	{
	  g_ascii_dtostr(number, 100, mm-nn);
	  gtk_entry_set_text(GTK_ENTRY(entry), number);
	  mm=mm-nn;
	  number_clear();
	  second=FALSE;
	}
      else
	{
	  /* init second operand (nn) */
	  nn=0.0;
	  number_clear();
	}
      break;
    case 3:
      /* Define the operation of multiplication */
      if(second)
	{
	  g_ascii_dtostr(number, 100, mm*nn);
	  gtk_entry_set_text(GTK_ENTRY(entry), number);
	  mm=mm*nn;
	  number_clear();
	  second=FALSE;
	}
      else
	{
	  number_clear();
	  nn=0.0;
	}
      break;
    case 4:
      /* Define the operation of dividing */
      if(second)
	{
	  g_ascii_dtostr(number, 100, mm/nn);
	  gtk_entry_set_text(GTK_ENTRY(entry), number);
	  mm=mm/nn;
	  number_clear();
	  second=FALSE;
	}
      else
	{
	  nn=0.0;
	  number_clear();
	}
      break;
    default:
      number_clear();
    }
}

void on_number_button_clicked(GtkWidget *button, gpointer data)
{
  const gchar *num; /* record current input number as char */
  num=gtk_button_get_label(GTK_BUTTON(button));
  g_strlcat(number, num, 100);
  if(has_result)
    clear();

  if(first==FALSE)
    {
      mm=g_strtod(number, NULL);
    }
  else
    {
      nn=g_strtod(number, NULL);
      second=TRUE;
    }

  gtk_entry_set_text(GTK_ENTRY(entry), number); /* display the number user input in entry box */
}

void on_dot_button_clicked(GtkWidget *button, gpointer data)
{
  if(has_dot)
    ; /* Nothing to do if current input has a dot already*/
  else
    {
      has_dot=TRUE;
      g_strlcat(number, ".", 100);
      if(has_result)
	clear();

      if (first==FALSE)
	mm=g_strtod(number, NULL);
      else
	{
	  nn=g_strtod(number, NULL);
	  second=TRUE;
	}
    }
  gtk_entry_set_text(GTK_ENTRY(entry), number);
}

void on_operator_button_clicked(GtkWidget *button, gpointer data)
{

  switch (GPOINTER_TO_INT(data))
    {
    case 1:
      calculate_last_time();
      operator=1;
      has_result=FALSE;
      has_dot=FALSE;
      first=TRUE;
      break;
    case 2:
      calculate_last_time();
      operator=2;
      has_dot=FALSE;
      has_result=FALSE;
      first=TRUE;
      break;
    case 3:
      calculate_last_time();
      operator=3;
      has_dot=FALSE;
      has_result=FALSE;
      first=TRUE;
      break;
    case 4:
      calculate_last_time();
      operator=4;
      has_dot=FALSE;
      has_result=FALSE;
      first=TRUE;
      break;
    }
}

void on_equal_button_clicked(GtkWidget *button, gpointer data)
{
  if (!has_result)
    {
      calculate_last_time();
      operator=0;
      number_clear();
      has_dot=FALSE;
      has_result=TRUE;
    }
}

void on_clear_button_clicked(GtkWidget *button, gpointer data)
{
  clear();
}

int main(int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *vbox;
  GtkWidget *hbox;
  GtkWidget *label;
  GtkWidget *button;

  gtk_init(&argc, &argv);
  window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
  g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
  gtk_window_set_title(GTK_WINDOW(window), "Simple Calculator");
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_MOUSE);
  gtk_container_set_border_width(GTK_CONTAINER(window), 10);

  vbox=gtk_vbox_new(FALSE, 5);
  gtk_container_add(GTK_CONTAINER(window), vbox);

  /* Following content sets up label and clear button on main window */
  hbox=gtk_hbox_new(FALSE, 5);
  label=gtk_label_new("Calculator");
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);

  button=gtk_button_new_with_label("C");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_clear_button_clicked), NULL);
  gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);

  /* Following content sets up entry box in main window */
  hbox=gtk_hbox_new(FALSE, 0);
  entry=gtk_entry_new();
  gtk_widget_set_direction(entry, GTK_TEXT_DIR_RTL);
  gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);

  /* Sets up first line of buttons */
  hbox=gtk_hbox_new(TRUE, 5);
  button=gtk_button_new_with_label("3");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_number_button_clicked), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);

  button=gtk_button_new_with_label("2");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_number_button_clicked), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);

  button=gtk_button_new_with_label("1");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_number_button_clicked), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);

  button=gtk_button_new_with_label("+");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_operator_button_clicked), (gpointer) 1);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
  /* End of setting up first line of buttons */

  /* Sets up second line of buttons */
  hbox=gtk_hbox_new(TRUE, 5);
  button=gtk_button_new_with_label("6");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_number_button_clicked), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);

  button=gtk_button_new_with_label("5");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_number_button_clicked), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);

  button=gtk_button_new_with_label("4");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_number_button_clicked), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);

  button=gtk_button_new_with_label("-");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_operator_button_clicked), (gpointer) 2);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
  /* End of setting up second line of buttons */

  /* Sets up third line of buttons */
  hbox=gtk_hbox_new(TRUE, 5);
  button=gtk_button_new_with_label("9");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_number_button_clicked), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);

  button=gtk_button_new_with_label("8");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_number_button_clicked), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);

  button=gtk_button_new_with_label("7");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_number_button_clicked), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);

  button=gtk_button_new_with_label("*");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_operator_button_clicked), (gpointer) 3);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
  /* End of setting up third line of buttons */

  /* Sets up fourth line of buttons*/
  hbox=gtk_hbox_new(TRUE, 5);
  button=gtk_button_new_with_label("0");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_number_button_clicked), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);

  button=gtk_button_new_with_label(".");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_dot_button_clicked), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);

  button=gtk_button_new_with_label("=");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_equal_button_clicked), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);

  button=gtk_button_new_with_label("/");
  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_operator_button_clicked), (gpointer) 4);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 5);
  /* End of setting up fourth line of buttons */

  clear();
  gtk_widget_show_all(window);
  gtk_main();

  return EXIT_SUCCESS;

}

编译命令

gcc -o calculator calculator.c `pkg-config --libs --clfags gtk+-2.0`

编译后运行,效果如图:
Calculator

Write a Comment

Comment