计算器Glade3设计界面GTK+实现代码

下载地址:点击打开链接(文件下载)


这个是我以前学习使用glade3时写的一个小程序,其中界面自然是用glade3设计的(很简陋),功能基本的也都还有,实现代码使用c写的调用了一些GTK+库,注释很详细,这个小程序的代码实现部分是参考一篇文章写的,和那篇文章基本一样,算法个人觉得很好,可惜时间太久不记得是在哪里看的了没法标注出处,在这里请求作者原谅另外感谢作者的优秀的算法。

下面奉上代码的部分文件:

glade_counter.c


#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;
GtkBuilder *builder = NULL;
/*初始化*/
gtk_init(&argc,&argv);

builder=gtk_builder_new();
gtk_builder_add_from_file(builder,"counter.glade",NULL);
gtk_builder_connect_signals(builder, NULL);
// 根据 ID 获取子构件
window=GTK_WIDGET(gtk_builder_get_object(builder,"window"));
entry=GTK_ENTRY(gtk_builder_get_object(builder,"entry"));
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);
// text = GTK_LABEL(gtk_builder_get_object(builder, "label-main"));

button=GTK_BUTTON(gtk_builder_get_object(builder, "button1"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressClear),NULL);
button=GTK_BUTTON(gtk_builder_get_object(builder, "button2"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);

button=GTK_BUTTON(gtk_builder_get_object(builder, "button3"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);

button=GTK_BUTTON(gtk_builder_get_object(builder, "button4"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);

button=GTK_BUTTON(gtk_builder_get_object(builder, "button5"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressOperator),(gpointer)1);

button=GTK_BUTTON(gtk_builder_get_object(builder, "button6"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);

button=GTK_BUTTON(gtk_builder_get_object(builder, "button7"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);

button=GTK_BUTTON(gtk_builder_get_object(builder, "button8"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);

button=GTK_BUTTON(gtk_builder_get_object(builder, "button9"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressOperator),(gpointer)2);

button=GTK_BUTTON(gtk_builder_get_object(builder, "button10"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);

button=GTK_BUTTON(gtk_builder_get_object(builder, "button11"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);

button=GTK_BUTTON(gtk_builder_get_object(builder, "button12"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);

button=GTK_BUTTON(gtk_builder_get_object(builder, "button13"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressOperator),(gpointer)3);

button=GTK_BUTTON(gtk_builder_get_object(builder, "button14"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressNum),NULL);
button=GTK_BUTTON(gtk_builder_get_object(builder, "button15"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressDot),NULL);
button=GTK_BUTTON(gtk_builder_get_object(builder, "button16"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressEqual),NULL);
button=GTK_BUTTON(gtk_builder_get_object(builder, "button17"));
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(PressOperator),(gpointer)4);

// 获取到 UI 对象后,GtkBuilder 对象已没有作用,释放了

g_object_unref(G_OBJECT(builder));


gtk_widget_show_all(window);
gtk_main();
return 0;

}

接下来是界面部分文件:这个是我用vim打开的,这是一个glade3设计的(内容则是XML),保存的格式也是 ".glade",如果要copy代码一定要记住保存为 xxxx.glade样式,且需要在上面文件 glade_counter.c中这句代码 gtk_builder_add_from_file(builder,"counter.glade",NULL);中的文件名与你保存的文件名一致才行,最好是用我的这个文件名。我觉得贴出来直观一点,所以有想运行以下的,把它copy下来保存为counter.glade文件名就行了

文件名:counter.glade


<?xml version="1.0"?>
<interface>
<requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window">
<signal name="destroy" handler="gtk_main_quit"/>
<signal name="delete_event" handler="gtk_main_quit"/>
<child>
<object class="GtkVBox" id="vbox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkHBox" id="hbox">
<property name="visible">True</property>
<property name="spacing">10</property>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">C</property>
<property name="width_request">20</property>
<property name="height_request">20</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry">
<property name="width_request">200</property>
<property name="height_request">40</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkTable" id="table">
<property name="visible">True</property>
<property name="n_rows">4</property>
<property name="n_columns">4</property>
<property name="column_spacing">2</property>
<property name="row_spacing">2</property>
<child>
<object class="GtkButton" id="button2">
<property name="label" translatable="yes">7</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
</child>
<child>
<object class="GtkButton" id="button3">
<property name="label" translatable="yes">8</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button4">
<property name="label" translatable="yes">9</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button5">
<property name="label" translatable="yes">+</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button6">
<property name="label" translatable="yes">4</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button7">
<property name="label" translatable="yes">5</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button8">
<property name="label" translatable="yes">6</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button9">
<property name="label" translatable="yes">_</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button10">
<property name="label" translatable="yes">3</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button11">
<property name="label" translatable="yes">2</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button12">
<property name="label" translatable="yes">1</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button13">
<property name="label" translatable="yes">*</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button14">
<property name="label" translatable="yes">0</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button15">
<property name="label" translatable="yes">.</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button16">
<property name="label" translatable="yes">=</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button17">
<property name="label" translatable="yes">/</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

下面是makefile:

文件名:makefile

CC = gcc
all:
$(CC) `pkg-config --cflags --libs gtk+-2.0` -export-dynamic glade_counter.c -o glade_counter
clean:
rm -f glade_counter

以上是整个程序的3个文件的完整代码:glade_counter.c、counter.glade、makefile,装好GTK+库后,直接make就编译成功了,下面是运行的结果:

这个程序仅仅是希望能够给初学者提供一些参考,如果需要我对文章中某些地方详细解释的话或者不想复制,我会看到评论后第一时间处理打包发给你。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值