简单的计算器,通过接受按键或点击事件将用户输入的信息送人完成简单的算术计算。
#include <gtk/gtk.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <math.h> /* --- This is the LCD panel - the results --- */ #define BUF_SIZE 88 #define MAX_SIZE 120 static gdouble num1 = 0; static gchar lastChar = (char) 0; static gchar prevCmd = (char) 0; GtkWidget *label; typedef struct { char *szLabel; /* --- Label display on button --- */ int row; /* --- Row to place the button --- */ int col; /* --- Column to place the button --- */ GtkWidget *widget; /* --- Handle to the button --- */ }typCalculatorButton; typCalculatorButton buttonList [] = { {"C", 1, 0, NULL}, /* --- Clear --- */ {"CE", 1, 1, NULL}, /* --- Clear --- */ {"/", 1, 3, NULL}, /* --- Division --- */ {"7", 2, 0, NULL}, /* --- Digit --- */ {"8", 2, 1, NULL}, /* --- Digit --- */ {"9", 2, 2, NULL}, /* --- Digit --- */ {"*", 2, 3, NULL}, /* --- Multiplication --- */ {"%", 2, 4, NULL}, /* --- Percent --- */ {"4", 3, 0, NULL}, /* --- Digit --- */ {"5", 3, 1, NULL}, /* --- Digit --- */ {"6", 3, 2, NULL}, /* --- Digit --- */ {"-", 3, 3, NULL}, /* --- Subtraction --- */ {"1/x", 3, 4, NULL}, /* --- 1/x --- */ {"1", 4, 0, NULL}, /* --- Digit --- */ {"2", 4, 1, NULL}, /* --- Digit --- */ {"3", 4, 2, NULL}, /* --- Digit --- */ {"+", 4, 3, NULL}, /* --- Addition --- */ {"sqrt",4, 4, NULL}, /* --- Square root --- */ {"+/-", 5, 0, NULL}, /* --- Negate value --- */ {"0", 5, 1, NULL}, /* --- zero --- */ {".", 5, 2, NULL}, /* --- Decimal --- */ {"=", 5, 3, NULL}, /* --- Equals/total --- */ {"x^2", 5, 4, NULL}, /* --- Squared --- */ }; gint CloseAppWindow(GtkWidget *widget, gpointer data) { gtk_main_quit (); return FALSE; } static void trim_trailing_zeros (char *szDigits) { int nIndex; int bDecimal = FALSE; int nPos = -1; for (nIndex = 0; nIndex < strlen (szDigits); nIndex++) { if (szDigits[nIndex] == '.') { bDecimal = TRUE; } if (bDecimal) { if (szDigits[nIndex] == '0') { if (nPos < 0) { nPos = nIndex; } } } } if (nPos > 0) { szDigits[nPos] = (char) 0; if (szDigits[nPos -1] == '.') { szDigits[nPos -1] = (char)0; } } } static void trim_leading_zeros(char *szDigits) { gint nPos; if (szDigits == NULL) return; for (nPos = 0; (szDigits[nPos] && szDigits[nPos] == '0'); nPos++) { if (isdigit(szDigits[nPos+1])) { szDigits[nPos] = ' '; } } } int command (char ch) { switch (ch) { case '+': case '-': case '/': case '*': case '=': return (TRUE); } return (FALSE); } void handle_digit(char *str, char ch) { char *labelText; char buffer[BUF_SIZE] = {0}; char result[MAX_SIZE] = {0}; int len; if (command(lastChar)) { gtk_label_set (GTK_LABEL (label), ""); if (lastChar == '=') { lastChar = (char) 0; prevCmd = (char) 0; } } gtk_label_get(GTK_LABEL (label), &labelText); strcpy (buffer, labelText); len = strlen (buffer); buffer[len] = (gchar)ch; buffer[len+1] = (gchar)0; trim_leading_zeros(buffer); sprintf (result, "<span foreground='blue' font_desc='15'>%s</span>", buffer); gtk_label_set_markup(GTK_LABEL(label), result); //gtk_label_set (GTK_LABEL (label), (char *) buffer); } void maybe_unary_operation (char *str) { gchar *labelText; gchar buffer[BUF_SIZE] = {0}; gchar result[MAX_SIZE] = {0}; gdouble num2; gtk_label_get (GTK_LABEL (label), &labelText); num2 = atof (labelText); if (strcmp (str, "%") == 0) { num2 = num2 / 100; } else if (strcmp (str, "1/x") == 0) { if (num2 == 0) { return; } num2 = 1 / num2; } else if (strcmp (str, "sqrt") == 0) { num2 = sqrt((double) num2); } else if (strcmp (str, "x^2") == 0) { num2 = num2 * num2; } sprintf (buffer, "%f", (gdouble) num2); trim_trailing_zeros (buffer); trim_leading_zeros (buffer); sprintf (result, "<span foreground='blue' font_desc='15'>%s</span>", buffer); gtk_label_set_markup(GTK_LABEL(label), result); //gtk_label_set (GTK_LABEL (label), buffer); } void handle_binary_operation() { gchar buffer[BUF_SIZE] = {0}; gchar result[MAX_SIZE] = {0}; gchar *labelText; gdouble num2; gtk_label_get (GTK_LABEL (label), &labelText); num2 = atof (labelText); switch (prevCmd) { case '+': num1 = num1 + num2; break; case '-': num1 = num1 - num2; break; case '*': num1 = num1 * num2; break; case '/': num1 = num1 / num2; break; case '=': num1 = num2; break; default: num1 = num2; break; } sprintf (buffer, "%f", (gdouble) num1); trim_trailing_zeros(buffer); trim_leading_zeros(buffer); sprintf (result, "<span foreground='blue' font_desc='15'>%s</span>", buffer); gtk_label_set_markup(GTK_LABEL(label), result); } void button_clicked(GtkWidget *widget, gpointer data) { gchar ch = *((gchar *) data); gchar *str = (gchar *)data; if ((isdigit (ch) || ch == '.') && strlen(str) == 1) { handle_digit(str, ch); } else { if (strcmp(str, "CE") == 0) { gtk_label_set_markup(GTK_LABEL(label), "<span foreground='blue' font_desc='15'>0</span>"); return; } else if (strcmp (str, "C") == 0) { prevCmd = (char) 0; lastChar = (char) 0; gtk_label_set_markup(GTK_LABEL(label), "<span foreground='blue' font_desc='15'>0</span>"); return; } else { maybe_unary_operation(str); } handle_binary_operation(); prevCmd = ch; } lastChar = ch; } GtkWidget *create_button (GtkWidget *table, char *szLabel, int row, int column) { GtkWidget *button; button = gtk_button_new_with_label (szLabel); gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (button_clicked), szLabel); gtk_table_attach(GTK_TABLE (table), button, column, column+1, row, row + 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 5); return button; } void create_calculator_buttons (GtkWidget *table) { gint nIndex; for (nIndex = 0; nIndex < sizeof (buttonList)/sizeof (typCalculatorButton); nIndex++) { buttonList[nIndex].widget = create_button(table, buttonList[nIndex].szLabel, buttonList[nIndex].row, buttonList[nIndex].col); } } void key_press(GtkWidget *widget, GdkEventKey *event, gpointer data) { gint nIndex; for (nIndex = 0; nIndex < sizeof (buttonList)/sizeof (typCalculatorButton); nIndex++) { if (strcmp(event->string, buttonList[nIndex].szLabel) == 0) { gtk_widget_grab_focus (buttonList[nIndex].widget); gtk_button_clicked(GTK_BUTTON (buttonList[nIndex].widget)); return; } } } int main (int argc, char *argv[]) { GtkWidget *window; GtkWidget *table; GtkWidget * frame; /* --- GTK initialization --- */ gtk_init (&argc, &argv); /* --- Create the calculator window --- */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); /* --- Give the window a title. --- */ gtk_window_set_title (GTK_WINDOW (window), "Calculator"); /* --- Set the window size. --- */ gtk_widget_set_usize (window, 300, 300); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_container_set_border_width(GTK_CONTAINER(window), 10); /* --- We care if a key is pressed --- */ gtk_signal_connect (GTK_OBJECT (window), "key_press_event", GTK_SIGNAL_FUNC (key_press), NULL); /* --- You should always remember to connect the delete event to the main window. --- */ gtk_signal_connect (GTK_OBJECT (window), "delete_event", GTK_SIGNAL_FUNC (CloseAppWindow), NULL); /* --- Create a 5x5 table for the items in the calculator. --- */ table = gtk_table_new (5, 5, TRUE); /* --- Create the calculator buttons. --- */ create_calculator_buttons (table); /* --- Create the calculator LED --- */ label = gtk_label_new (NULL); gtk_label_set_markup(GTK_LABEL(label), "<span foreground='blue' font_desc='15'>0</span>"); frame = gtk_frame_new(NULL); gtk_container_add(GTK_CONTAINER(frame),label); gtk_misc_set_alignment (GTK_MISC (label), 1, .5); gtk_table_attach_defaults (GTK_TABLE (table), frame, 0, 5, 0, 1); /* --- Make them visible --- */ gtk_container_add (GTK_CONTAINER (window), table); gtk_widget_show_all(window); gtk_main (); return 0; }(2)编译运行
gcc -o calculator calculator_one.c `pkg-config --libs --cflags gtk+-2.0`
/*gcc -o calculator calculator_two.cpp `pkg-config --cflags --libs gtk+-2.0`*/ #include <gtk/gtk.h> #include <stdlib.h> static GtkWidget *entry; gint count = 0; gdouble nn = 0; gdouble mm = 0; gint s = 0; gboolean first = TRUE; gboolean have_dot = FALSE; gboolean have_result = FALSE; gchar number[100]; void clear_all() { gint i; nn = 0; mm = 0; s = 0; count = 0; first = TRUE; have_dot = FALSE; have_result = FALSE; for (i = 0; i < sizeof(number); i++) number[i] = '\0'; gtk_entry_set_text(GTK_ENTRY(entry), ""); } void on_clear_clicked(GtkButton *button, gpointer data) { clear_all(); } void on_num_clicked(GtkButton *button, gpointer data) { const gchar *num; gint i; if (have_result) clear_all(); if (count == 6) return; count++; num = gtk_button_get_label(GTK_BUTTON(button)); i = g_strlcat(number, num, 100); if (first) { nn = g_ascii_strtod(number, NULL); } else mm = g_ascii_strtod(number, NULL); gtk_entry_set_text(GTK_ENTRY(entry), number); } void on_suan_clicked(GtkButton *button, gpointer data) { gint i; s = GPOINTER_TO_INT(data); first = FALSE; count = 0; have_dot = FALSE; gtk_entry_set_text(GTK_ENTRY(entry), ""); for (i = 0; i < sizeof(number); i++) number[i] = '\0'; } void on_dot_clicked(GtkButton *button, gpointer data) { gint i; if (have_result) clear_all(); if (have_dot == FALSE) { have_dot = TRUE; i = g_strlcat(number, ".", 100); gtk_entry_set_text(GTK_ENTRY(entry), number); } } void on_eq_clicked(GtkButton *button, gpointer data) { gdouble numb; gchar num[100]; gchar *result; switch(s) { case 1: numb = nn + mm; break; case 2: numb = nn - mm; break; case 3: numb = nn * mm; break; case 4: numb = nn / mm; break; } result = g_ascii_dtostr(num, 100, numb); have_result = TRUE; gtk_entry_set_text(GTK_ENTRY(entry), result); } int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *vbox; GtkWidget *hbox, *hbox1, *hbox2, *hbox3, *hbox4; GtkWidget *button; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(gtk_main_quit), NULL); gtk_window_set_title(GTK_WINDOW(window), "计算器"); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); //postion gtk_widget_set_usize (window, 230, 230); gtk_container_set_border_width(GTK_CONTAINER(window), 10); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(window), vbox); entry = gtk_entry_new(); gtk_widget_set_direction(entry, GTK_TEXT_DIR_RTL); gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 5); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5); button = gtk_button_new_with_label("CE"); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_clear_clicked), NULL); hbox1 = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox1, FALSE, FALSE, 5); button = gtk_button_new_with_label("3"); gtk_box_pack_start(GTK_BOX(hbox1), button, TRUE, TRUE, 5); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_num_clicked), NULL); button = gtk_button_new_with_label("2"); gtk_box_pack_start(GTK_BOX(hbox1), button, TRUE, TRUE, 5); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_num_clicked), NULL); button = gtk_button_new_with_label("1"); gtk_box_pack_start(GTK_BOX(hbox1), button, TRUE, TRUE, 5); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_num_clicked), NULL); button = gtk_button_new_with_label("+"); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_suan_clicked), (gpointer)1); gtk_box_pack_start(GTK_BOX(hbox1), button, TRUE, TRUE, 5); hbox2 = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 5); button = gtk_button_new_with_label("6"); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_num_clicked), NULL); gtk_box_pack_start(GTK_BOX(hbox2), button, TRUE, TRUE, 5); button = gtk_button_new_with_label("5"); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_num_clicked), NULL); gtk_box_pack_start(GTK_BOX(hbox2), button, TRUE, TRUE, 5); button = gtk_button_new_with_label("4"); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_num_clicked), NULL); gtk_box_pack_start(GTK_BOX(hbox2), button, TRUE, TRUE, 5); button = gtk_button_new_with_label("-"); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_suan_clicked), (gpointer)2); gtk_box_pack_start(GTK_BOX(hbox2), button, TRUE, TRUE, 5); hbox3 = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox3, FALSE, FALSE, 5); button = gtk_button_new_with_label("9"); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_num_clicked), NULL); gtk_box_pack_start(GTK_BOX(hbox3), button, TRUE, TRUE, 5); button = gtk_button_new_with_label("8"); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_num_clicked), NULL); gtk_box_pack_start(GTK_BOX(hbox3), button, TRUE, TRUE, 5); button = gtk_button_new_with_label("7"); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_num_clicked), NULL); gtk_box_pack_start(GTK_BOX(hbox3), button, TRUE, TRUE, 5); button = gtk_button_new_with_label("*"); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_suan_clicked), (gpointer)3); gtk_box_pack_start(GTK_BOX(hbox3), button, TRUE, TRUE, 5); hbox4 = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox4, FALSE, FALSE, 5); button = gtk_button_new_with_label("0"); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_num_clicked), NULL); gtk_box_pack_start(GTK_BOX(hbox4), button, TRUE, TRUE, 5); button = gtk_button_new_with_label("."); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_dot_clicked), NULL); gtk_box_pack_start(GTK_BOX(hbox4), button, TRUE, TRUE, 5); button = gtk_button_new_with_label("="); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_eq_clicked), NULL); gtk_box_pack_start(GTK_BOX(hbox4), button, TRUE, TRUE, 5); button = gtk_button_new_with_label("/"); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_suan_clicked), (gpointer)4); gtk_box_pack_start(GTK_BOX(hbox4), button, TRUE, TRUE, 5); gtk_widget_show_all(window); gtk_main(); return TRUE; }(2)编译并运行
gcc -o calculator calculator_two.c `pkg-config --cflags --libs gtk+-2.0`