这段时间在学习GTK,综合网上的资料写了个计算器,功能还算完善,但是,除浮点数的时候有点问题,估计是算法设计的不太正确,小弟初学,望有研究过的大侠指教。
#include <gtk/gtk.h>
#include <stdlib.h>
/*创建一个指向GtkWidget类型的指针(创建文本框使用)*/
static GtkWidget *entry;
/*创建全局变量:名为“fnum”(双精度,第一个输入量);
“snum”(双精度,第二个输入量)*/
gdouble fnum = 0;
gdouble snum = 0;
/*创建全局控制变量:名为“num_count”(整型,控制输入位数);
“operator”(整型,控制输入的运算符号);
“first_num”(布尔型,控制输入的次数);
“have_result”(布尔型,为重新进行计算作好准备)*/
gint num_count =0;
gint operator = 0;
gboolean first_num = TRUE;
//gboolean first_num_equal = FALSE;
gboolean have_dot = FALSE; //小数点
gboolean have_result = FALSE;
gchar number[100];
/*........................................................................ */
//清除函数:ClearReset()
//1:清除屏幕上的内容(TURE);2:初始化变量并清屏(FALSE)
void ClearReset(gboolean clear_only)
{
/*初始化number[100]等,分配内存空间*/
gint i = 0;
for(i = 0;i<100;i++)
number[i] = '/0';
fnum = 0;
snum = 0;
operator = 0;
num_count = 0;
first_num = TRUE;
have_dot = FALSE;
have_result = FALSE;
//first_num_equal = FALSE;
/*清除屏幕*/
if(clear_only = TRUE)
gtk_entry_set_text(GTK_ENTRY(entry),"0");
}
/*---------------------------------------------------------------------------------- */
//按下数字时的回调函数:PressNum()
void PressNum(GtkButton *button,gpointer data)
{
/*创建一个指向字符的指针变量:"num"(用来操作输入量)*/
const gchar *num;
int i;
/*控制输入数字的位数*/
if(num_count == 9)
return;
/*输入位数记数*/
num_count++;
/*通过button的label获取每次输入的数值(字符串型)*/
num=gtk_button_get_label(GTK_BUTTON(button));
/*g_strlcat() 可以用来组合每次输入数字(字符串)起到累加作用*/
i=g_strlcat(number,num,100);
/*输入第一个数和第二个数的控制开关,strtod()是把字符串转换为gdouble型*/
if(first_num )
{
/*第一次输入*/
fnum=strtod(number,NULL);
}
else
{
/*第二次输入*/
/*防止除法时除数为0*/
if(num_count == 1);
snum=strtod(number,NULL);
if(num_count == 1 && operator ==4 && snum == 0)
//gtk_entry_set_text(GTK_ENTRY(entry),"ERROR");
return;
}
if (number[0]=='0' && number[1]!='.' &&num_count>=2 )
{
gint i;
for (i =0 ; i<100; i++)
{
number[i] = number[i+1];
}
}
/*把输入的数字显示出来*/
gtk_entry_set_text(GTK_ENTRY(entry),number);
//g_print("F:%f/n",fnum);
//g_print("S:%f/n",snum);
}
/*----------------------------------------------------------------------------------*/
//按下小数点时的回调函数:PressDot()
void PressDot(GtkButton *button,gpointer data)
{
gint i;
/*重复计算的切换开关*/
if(have_result)
ClearReset(FALSE);
/*如果小数点在第一位则不显示*/
if(num_count == 0)
{
ClearReset(TRUE);
return;
}
/*把数加上小数点进行显示.have_dot防止输入两次小数点*/
if(have_dot == FALSE)
{
have_dot = TRUE;
i=g_strlcat(number,".",100);
if(first_num)
/*第一个数字输入*/
fnum=strtod(number,NULL);
else
{
/*第二个数字输入*/
snum=strtod(number,NULL);
/*把输入的数字显示出来*/
gtk_entry_set_text(GTK_ENTRY(entry),number);
}
}
}
/*------------------------------------------------------------------------------------*/
//按下清零键时的回调函数:PressClear()
void PressClear(GtkButton *button,gpointer data)
{
ClearReset(FALSE);
}
/*------------------------------------------------------------------------------------*/
//按下运算符时的回调函数:PressOperator()
void PressOperator(GtkButton *button,gpointer data)
{
gint i;
switch(GPOINTER_TO_INT(data))
{
case 1: operator = 1;//加法
break;
case 2: operator = 2;//减法
break;
case 3: operator = 3;//乘法
break;
case 4: operator = 4;//除法
break;
}
// g_print("F:%f/n",fnum);
// g_print("S:%f/n",snum);
/*切换输入第二个数*/
first_num = FALSE;
num_count = 0;
have_dot =FALSE;
for( i = 0;i<100;i++)
number[i] = '/0';
}
/*-------------------------------------------------------------------------------------*/
//按下等于号时的回调函数:PressEqual()
void PressEqual(GtkButton *button,gpointer data)
{
gdouble numb;
gchar *result;
gchar num[100];
gint e = 0;
g_print("F:%f/n",fnum);
g_print("S:%f/n",snum);
/*进行运算*/
switch(operator)
{
case 1: numb = fnum + snum ;
break;
case 2: numb = fnum - snum;
break;
case 3: numb = fnum * snum;
break;
case 4: numb = fnum / snum;
break;
//防一开始什么也不按,就按一个= 会档机的问题
default: gtk_entry_set_text(GTK_ENTRY(entry),number);
e = 1;
break;
}
if (e==0)
{ /*把结果转换成字符串*/
result = g_ascii_dtostr(num,100,numb);
fnum = numb;
//输出结果
gtk_entry_set_text(GTK_ENTRY(entry),result);
have_result=TRUE;
//first_num_equal = TRUE;
}
/*
result = g_ascii_dtostr(num,100,numb);
fnum = numb;
gtk_entry_set_text(GTK_ENTRY(entry),result);
have_result=TRUE;
first_num_equal = TRUE; */
}
/*-------------------------------------------------------------------------------------*/
//主函数:main()
int main(int argc,char* argv[])
{
/*创建指向GtkWidget类型的指针*/
GtkWidget *window;
GtkWidget *button;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *table;
/*初始化*/
gtk_init(&argc,&argv);
/*创建一个新的主窗口*/
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
/*设置窗口大小*/
gtk_window_set_default_size(GTK_WINDOW(window),500,300);
/*设置边框大小*/
gtk_container_set_border_width(GTK_CONTAINER(window),10);
/*设置主窗口标题*/
gtk_window_set_title(GTK_WINDOW(window),"计算器");
/*设置位置*/
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
/*与“destroy”事件联结执行回掉函数gtk_main_quit(),关闭窗口*/
g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);
/*创建一个横的盒子*/
hbox=gtk_hbox_new(FALSE,0);
/*创建一个竖的盒子*/
vbox=gtk_vbox_new(FALSE,0);
/*把盒子放入主窗口*/
gtk_container_add(GTK_CONTAINER(window),vbox);
/*创建清零键*/
button=gtk_button_new_with_label("C");
gtk_box_pack_start(GTK_BOX(hbox),button,TRUE,TRUE,5);
/*把清零键与回调函数 PressClear()相联结*/
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressClear),NULL);
/*创建一个文本框*/
entry=gtk_entry_new();
gtk_widget_set_size_request(entry, 200, 40);
/*并设置不可以编辑,方向*/
gtk_entry_set_text(GTK_ENTRY(entry),"0");
gtk_editable_set_editable(GTK_EDITABLE(entry),FALSE);
gtk_widget_set_direction(entry,GTK_TEXT_DIR_RTL);
/*放入横盒子里*/
gtk_box_pack_start(GTK_BOX(hbox),entry,TRUE,TRUE,5);
gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,5);
/*创建一个装数字的表,设置大小*/
table = gtk_table_new(4, 4, TRUE);
gtk_widget_set_size_request(table, 450, 220);
gtk_table_set_row_spacings(GTK_TABLE(table), 2);
gtk_table_set_col_spacings(GTK_TABLE(table), 2);
/*将符号按钮按序放入表格中,并与其回调函数相连*/
button = gtk_button_new_with_label("7");
gtk_table_attach_defaults(GTK_TABLE(table), button, 0, 1, 0, 1 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);
button = gtk_button_new_with_label("8");
gtk_table_attach_defaults(GTK_TABLE(table), button, 1, 2, 0, 1 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);
button = gtk_button_new_with_label("9");
gtk_table_attach_defaults(GTK_TABLE(table), button, 2, 3, 0, 1 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);
button = gtk_button_new_with_label("+");
gtk_table_attach_defaults(GTK_TABLE(table), button, 3, 4, 0, 1 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressOperator),(gpointer)1);
button = gtk_button_new_with_label("4");
gtk_table_attach_defaults(GTK_TABLE(table), button, 0, 1, 1, 2 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);
button = gtk_button_new_with_label("5");
gtk_table_attach_defaults(GTK_TABLE(table), button, 1, 2, 1, 2 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);
button = gtk_button_new_with_label("6");
gtk_table_attach_defaults(GTK_TABLE(table), button, 2, 3, 1, 2 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);
button = gtk_button_new_with_label("-");
gtk_table_attach_defaults(GTK_TABLE(table), button, 3, 4, 1, 2 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressOperator),(gpointer)2);
button = gtk_button_new_with_label("1");
gtk_table_attach_defaults(GTK_TABLE(table), button, 0, 1, 2, 3 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);
button = gtk_button_new_with_label("2");
gtk_table_attach_defaults(GTK_TABLE(table), button, 1, 2, 2, 3 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);
button = gtk_button_new_with_label("3");
gtk_table_attach_defaults(GTK_TABLE(table), button, 2, 3, 2, 3 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);
button = gtk_button_new_with_label("*");
gtk_table_attach_defaults(GTK_TABLE(table), button, 3, 4, 2, 3 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressOperator),(gpointer)3);
button = gtk_button_new_with_label("0");
gtk_table_attach_defaults(GTK_TABLE(table), button, 0, 1, 3, 4 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);
button = gtk_button_new_with_label(".");
gtk_table_attach_defaults(GTK_TABLE(table), button, 1, 2, 3, 4 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressDot),NULL);
button = gtk_button_new_with_label("=");
gtk_table_attach_defaults(GTK_TABLE(table), button, 2, 3, 3, 4 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressEqual),NULL);
button = gtk_button_new_with_label("/");
gtk_table_attach_defaults(GTK_TABLE(table), button, 3, 4, 3, 4 );
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressOperator),(gpointer)4);
/*将表格放入竖盒子中*/
gtk_box_pack_start(GTK_BOX(vbox),table,TRUE,TRUE,5);
gtk_widget_show_all(window);
gtk_main();
return 0;
}