GTK图形界面编程计算器的实现.docx
《GTK图形界面编程计算器的实现.docx》由会员分享,可在线阅读,更多相关《GTK图形界面编程计算器的实现.docx(25页珍藏版)》请在冰点文库上搜索。
![GTK图形界面编程计算器的实现.docx](https://file1.bingdoc.com/fileroot1/2023-5/9/9e5b3b1c-7303-445b-b6bc-7cb313bfa5bc/9e5b3b1c-7303-445b-b6bc-7cb313bfa5bc1.gif)
GTK图形界面编程计算器的实现
目录
1引言2
1.1课题背景2
1.2课程设计目的2
1.3课程设计任务3
2系统需求分析3
2.1功能需求分析3
2.2性能需求分析3
3总体设计4
3.1功能模块分析与设计4
3.2系统功能模块设计4
4系统功能测试9
4.1一个Helloworld窗口9
4.2计算器功能测试10
5课程设计总结14
参考文献15
1引言
1.1课题背景
简单的计算器是一种能实现加、减、乘、除等简单运算的工具。
要实现计算功能,可以用C语言的知识和GTK+编写程序来解决此问题。
该计算器大大的降低了数字计算的难度及提高了计算的准确度和精确度。
该计算器使用非常简单和方便,对广大中小学生的学习有巨大帮助作用,也对在职人员的工作有点帮助作用。
GTK+2.0是自由软件,并且是GNU工程的一部分[1]。
GTK+2.0的许可协议LGPL,允许任何开发者使用(包括那些开发中的专利软件)且不收任何费用。
GTK+2.0是当今惟一百分之百零付费的工业级的图形界面开发工具。
本设计就以GTK+2.0为开发工具,全面展示在Linux平台上开发应用程序的各个侧面,也展现在Linux平台上开发图形界面应用程序。
计算机信息管理技术的应用,除了能在相当大的程度上代替人工作业,从而减少人员工作量,减轻工作负担,减少工作中因人为原因而产生的错误从而避免不必要的损失外,更重要的是能建立准确畅通、简便的信息流通渠道,为工作提供所需要的准确、及时的信息以帮助做出正确而及时的选择与决定,从而给采用这门技术的单位带来了巨大的可见或不可见的利益与效益。
1.2课程设计目的
现在大多数的计算器都具备+,-,*,/等四则运算的功能。
用计算器来算数显然比用脑袋或用纸笔计算要来得方便。
讲究高效的我们势必要用到傻瓜设备(就是拿到手看看说明就知道怎样使用的东东)。
当我们看到一个很长很大的表达式需要得到结果时,我们就会想到计算器,这样,本程序就是为解决大家基本四则运算的问题而产生的。
只要你读懂说明,那么你所输入的表达式就一定能得到正确的结果。
本文主要基于对表达式的分析并利用C进行编程进而实现算法的。
与Java和C#等其他高级语言相比,C在程序运行效率、内存使用的可控性和编程的灵活性上均具有较大的优势[2],与汇编语言和C语言更具有面向对象的优点,因此本文采用UbuntuLinux操作系统以及GTK+2.0,以达到算法快速有效地执行。
1.3课程设计任务
本课程设计内容是在Linux平台下开发一个简单的计算器程序,采用GCC编程工具和GTK+2.0工具包等软件为开发工具以及C语言知识实现图形化的计算器程序。
该程序能够实现的对整数的加减乘除和小数的加减乘除。
2系统需求分析
2.1功能需求分析
(1)整数之间的加减乘除运算,如:
1+2、6-5、24/12、90*2等。
(2)小数之间的加减乘除运算,如:
1.2+2.3、3.1-1.2、4.2*1.9、66.1/2.1等。
(3)小数与整数之间的加减乘除运算,如:
1.4+4、2.4*6等。
2.2性能需求分析
(1)硬件环境
处理器:
奔腾4或以上。
内存:
128MB或以上。
硬盘空间:
20M以上。
(2)软件环境
操作系统:
LinuxKernel2.6.20以上版本。
工具软件:
GTK+2.0工具包、GCC编程工具。
(3)技术需求
GCC,即GNUCompilerCollection,GNU编译器套装,是一套由GNU开发的编程语言编译器。
它是一套以GPL及LGPL许可证所发行的自由软件,也是GNU计划的关键部分,亦是自由的类Unix及苹果电脑MacOSX操作系统的标准编译器。
可处理C、C++、Fortran、Pascal、Objective-C、Java,以及Ada与其他语言[3]。
GTK+是一种图形用户界面工具包。
也就是说,它是一个库(或者,实际上是若干个密切相关的库的集合),它支持创建基于GUI的应用程序[4]。
可以把GTK+想像成一个工具包,从这个工具包中可以找到用来创建GUI的许多已经准备好的构造块。
使用GTK+这样的库比起编写自己的GUI代码来有多个优势。
例如,它可以显著节约开发时间,让开发人员把精力集中在项目真正重要和真正独特的地方,而不必重复公共的功能。
对于用户来说,这意味着他们使用的应用程序之间具有更好的一致性:
工具包能在哪使用,应用程序就能跟到哪里。
就像使用LEGO一样,所有的人都使用同一兼容尺寸这一事实,意味着设计可以在使用库的人之间共享,不论他们在哪里使用它。
3总体设计
3.1功能模块分析与设计
本计算器主要是完成整数之间、小数之间、整数和小数之间的加减乘除的运算,使用GTK+完成界面布局。
根据需求分析的结果,总体结构如图3-1所示。
图3-1总体结构图
3.2系统功能模块设计
本课程设计所实现的计算器可以分为以下几个模块实现:
(1)图形界面设计
(2)数字键处理模块
(3)小数点处理模块
(4)加减乘除运算按键处理模块
(5)结果按键,即等号处理模块
(6)清除模块
3.2.1图形界面设计
此程序采用一个纵向盒状容器和多个横向盒状容器来设计界面。
另外在单行输入控件的阅读方向属性上用函数gtk_widget_set_direction设定为GTK_TEXT_DIR_RTL,即从右向左,使此控件的数字显示更像一个计算器的显示屏。
(1)主窗体关键代码:
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);//主窗体
G_CALLBACK(gtk_main_quit),NULL);
gtk_window_set_title(GTK_WINDOW(window),"我的计算器");//窗体名称
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
gtk_container_set_border_width(GTK_CONTAINER(window),10);
vbox=gtk_vbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(window),vbox);
hbox=gtk_hbox_new(FALSE,0);
gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,5);
(2)各个按键布局的关键代码:
label=gtk_label_new("Calculator");//标签名称
gtk_box_pack_start(GTK_BOX(hbox),label,TRUE,TRUE,5);
button=gtk_button_new_with_label("C");//清除按键
gtk_box_pack_start(GTK_BOX(hbox),button,TRUE,TRUE,5);
构建一个hbox1容纳数字“1”、“2”、“3”、“+”四个按键:
hbox1=gtk_hbox_new(FALSE,0);//hbox1的构建
gtk_box_pack_start(GTK_BOX(vbox),hbox1,FALSE,FALSE,5);
button=gtk_button_new_with_label("3");//按键3
gtk_box_pack_start(GTK_BOX(hbox1),button,TRUE,TRUE,5);
G_CALLBACK(on_num_clicked),NULL);
button=gtk_button_new_with_label("2");//按键2
gtk_box_pack_start(GTK_BOX(hbox1),button,TRUE,TRUE,5);
G_CALLBACK(on_num_clicked),NULL);
button=gtk_button_new_with_label("1");//按键1
gtk_box_pack_start(GTK_BOX(hbox1),button,TRUE,TRUE,5);
类似的构建hbox2控件容纳“4”、“5”、“6”和“-”四个按键,hbox3容纳“7”、“8”、“9”和“*”四个按键,hbox4容纳“0”、“.”、“=”和“/”四个按键。
而对于hbox1~hbox4,是控件vbox的子类,布局如下:
gtk_box_pack_start(GTK_BOX(vbox),hbox1,FALSE,FALSE,5);
gtk_box_pack_start(GTK_BOX(vbox),hbox2,FALSE,FALSE,5);
gtk_box_pack_start(GTK_BOX(vbox),hbox3,FALSE,FALSE,5);
gtk_box_pack_start(GTK_BOX(vbox),hbox4,FALSE,FALSE,5);
3.2.2数字键处理模块
数字按钮0~9的功能是向计算器输入数字,通过计算和定位,最后显示出来,所以它们的回调函数都是同一个,只不过传递的参数根据不同的按钮传递不同的数字,关键代码如下:
voidon_num_clicked(GtkButton*button,gpointerdata)
{//当数定键按下时执行
constgchar*num;
ginti;
if(have_result)
clear_all();//有结果则全部清除
if(count==6)return;//够6位数则不能再输入数字
count++;
num=gtk_button_get_label(GTK_BUTTON(button));//取数
i=g_strlcat(number,num,100);//保存
if(first)
nn=strtod(number,NULL);//数一
else
mm=strtod(number,NULL);//数二
gtk_entry_set_text(GTK_ENTRY(entry),number);//显示
}
3.2.3小数点处理模块
小数点按钮的回调函数是较特殊的一个。
首先小数点在一个数中只能出现一次,再按的话则不起作用,小数点按钮在点击后要对所输入的数字做一下处理,使之成为浮点数,并且让后续数字也转换为相应的浮点数字,关键代码如下:
voidon_dot_clicked(GtkButton*button,gpointerdata)
{//当小数点按下时
ginti;
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);
}//如果有小数点则不输出
}
3.2.4运算按键处理模块
本计算器软件只有加减乘除4种运算功能,这4个运算按钮用了同一个回调函数,根据传递的参数设定当前的计算方法。
其关键代码如下:
switch(GPOINTER_TO_INT(data))
{
case1:
//当"+"时
s=1;
gtk_entry_set_text(GTK_ENTRY(entry),"");
first=FALSE;count=0;break;
case2:
//当"-"时
s=2;
gtk_entry_set_text(GTK_ENTRY(entry),"");
first=FALSE;count=0;break;
case3:
//当"*"时
s=3;
gtk_entry_set_text(GTK_ENTRY(entry),"");
first=FALSE;count=0;break;
case4:
//当"/"时
s=4;
gtk_entry_set_text(GTK_ENTRY(entry),"");
first=FALSE;count=0;break;
}
3.2.5等号按键处理模块
等号按钮的回调函数是根据当前的计算方法进行相应的运算,并将运算结果输出到单行输出控件中。
其关键代码如下:
switch(s)//判断四则运算的符号
{
case1:
//当"+"时
numb=nn+mm;
break;
case2:
//当"-"时
numb=nn-mm;
break;
case3:
//当"*"时
numb=nn*mm;
break;
case4:
//当"/"时
numb=nn/mm;
break;
}
3.2.6清除模块
清除按钮的功能是清除当前显示,同时清除所有标记,将标记设为默认等。
关键代码如下:
voidclear_all(void)
{//清除所有相关标记
ginti;
gtk_entry_set_text(GTK_ENTRY(entry),"");
nn=0;//第一个数清零
mm=0;//第二个数清零
s=0;
count=0;
first=TRUE;
have_dot=FALSE;//小数点标记
have_result=FALSE;//结果标记
for(i=0;i<100;i++)
number[i]='\0';
}
4系统功能测试
4.1一个Helloworld窗口
本例子是使用GTK+2.0编写一个helloworld.c的程序,用以显示一个窗口,并且在这个窗口的标题栏上显示字符串“Hello,world!
”。
程序截图如图4-1。
图4-1使用vim编写helloworld.c
运行gcc-Wallhelloworld.c-ohelloworld`pkg-config--cflags--libsgtk+-2.0`命令编译后,执行./helloworld出现窗口,如图4-2所示。
图4-2Helloworld窗口
4.2计算器功能测试
(1)计算器主界面,如图4-3所示。
图4-3计算器主界面
(2)加法运算演示:
55+346=401,如图4-4、4-5、4-6所示。
图4-4输入55
图4-5输入346
图4-6按下等号得出结果
(2)乘法运算演示:
321*22=7062,如图4-7、4-8、4-9所示。
图4-7输入321
图4-8输入22
图4-9按下等号输出结果
(3)除法运算演示:
100/3=33.33333,如图4-10、4-11、4-12所示。
图4-10输入100
图4-11输入3
图4-11按下等号输出结果
5课程设计总结
通过两周周的数据结构课程设计,我顺利的完成了Linux平台下图形界面——计算器设计的课程设计。
感觉在这次课程设计中自己受益匪浅,不仅将以前在课堂上学到的东西从新又巩固了一遍,并且又有所创新,将数据结构的知识与Linux知识相结合,做出了功能丰富的应用程序,还有就是同时发现了以前的不足,及时的弥补!
在课程设计中遇见的课题中的很多技术问题,当然要感谢邓老师能给予认真的指导,并培养我们独立自立的能力,让我们对自学能力有了很高的提高,在各方面,提高了我们的主动积极性。
同时也要谢谢同学们的相互帮助,感谢有了这些,我才能很好的顺利的完成我的这次课程设计。
参考文献
[1]宋国伟.《GTK+2.0编程范例》北京:
清华大学出版社,2002.11
[2]谭诰强.《C程序设计》北京:
清华大学出版社,2004.6
[3]KurtWalletal.GUN/Linux编程指南(第二版)北京:
清华大学出版社,2002.6
[4]严蔚敏,吴伟民.《数据结构》(C语言版)北京:
清华大学出版,2009.4
源程序清单:
#include
#include
staticGtkWidget*entry;//定义单行输入控件来显示输入输出的数字
gintcount=0;//计位
gdoublenn=0;//计数一
gdoublemm=0;//计数二
gints=0;//算法
gbooleanfirst=TRUE;//首次输入
gbooleanhave_dot=FALSE;//是否有小数点
gbooleanhave_result=FALSE;//是否有结果输出
gcharnumber[100];//保存用户输入的数字
voidclear_all(void)
{//清除所有相关标记
ginti;
gtk_entry_set_text(GTK_ENTRY(entry),"");
nn=0;
mm=0;
s=0;
count=0;
first=TRUE;
have_dot=FALSE;
have_result=FALSE;
for(i=0;i<100;i++)
number[i]='\0';
}
voidon_num_clicked(GtkButton*button,gpointerdata)
{//当数定键按下时执行
constgchar*num;
ginti;
if(have_result)
clear_all();//有结果则全部清除
if(count==6)return;//够6位数则不能再输入数字
count++;
num=gtk_button_get_label(GTK_BUTTON(button));//取数
i=g_strlcat(number,num,100);//保存
if(first)
nn=strtod(number,NULL);//数一
else
mm=strtod(number,NULL);//数二
gtk_entry_set_text(GTK_ENTRY(entry),number);//显示
}
voidon_dot_clicked(GtkButton*button,gpointerdata)
{//当小数点按下时
ginti;
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);
}//如果有小数点则不输出
}
voidon_clear_clicked(GtkButton*button,gpointerdata)
{
clear_all();//全部清除
}
voidon_suan_clicked(GtkButton*button,gpointerdata)
{//当计算按钮+,-,*,/按下时
ginti;
switch(GPOINTER_TO_INT(data))
{
case1:
//当"+"时
s=1;
gtk_entry_set_text(GTK_ENTRY(entry),"");
first=FALSE;count=0;break;
case2:
//当"-"时
s=2;
gtk_entry_set_text(GTK_ENTRY(entry),"");
first=FALSE;count=0;break;
case3:
//当"*"时
s=3;
gtk_entry_set_text(GTK_ENTRY(entry),"");
first=FALSE;count=0;break;
case4:
//当"/"时
s=4;
gtk_entry_set_text(GTK_ENTRY(entry),"");
first=FALSE;count=0;break;
}
have_dot=FALSE;
for(i=0;i<100;i++)//清除数字
number[i]='\0';
}
voidon_eq_clicked(GtkButton*button,gpointerdata)
{//当等号键按钮按下时
doublenumb;
gcharnum[100];
gchar*result;
switch(s)
{
case1:
//当"+"时
numb=nn+mm;
break;
case2:
//当"-"时
numb=nn-mm;
break;
case3:
//当"*"时
numb=nn*mm;
break;
case4:
//当"/"时
numb=nn/mm;
break;
}
result=g_ascii_dtostr(num,100,numb);
gtk_entry_set_text(GTK_ENTRY(entry),result);
have_result=TRUE;
}
intmain(intargc,char*argv[])
{
GtkWidget*window;
GtkWidget*vbox;
GtkWidget*hbox,*hbox1,*hbox2,*hbox3,*hbox4;
GtkWidget*button;
GtkWidget*label;
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);