学习C语言及GTK界面编程经典实例修改: 计算器

来源:互联网 发布:青云志目前网络播放量 编辑:程序博客网 时间:2024/04/26 03:26

推荐到我的邮箱 uunubt@yahoo.cn 00000000 直接去下在源码包,否则按下面步骤来也行哈

第一步,新建文件夹重命名为 :ad

第二步,将下面文件 1: calc.glade  2: callbacks.c  3: callbacks.h  4:  main.c  5: Makefile  6:  Readme.txt  拷贝到ad路径下

第三步,进入ad路径下编译执行(当然该装的工具不能少)  make  ./calc  后结果如图:

    

 

 1:calc.glade

 

       <?xml version="1.0" encoding="UTF-8"?>
<glade-interface>
  <!-- interface-requires gtk+ 2.16 -->
  <!-- interface-naming-policy project-wide -->
  <widget class="GtkWindow" id="window1">
    <property name="title" translatable="yes">计算器</property>
    <property name="resizable">False</property>
    <property name="window_position">center-on-parent</property>
    <property name="default_width">800</property>
    <property name="default_height">600</property>
    <signal name="destroy" handler="gtk_main_quit"/>
    <child>
      <widget class="GtkVBox" id="vbox1">
        <property name="visible">True</property>
        <child>
          <widget class="GtkHBox" id="hbox1">
            <property name="visible">True</property>
            <property name="homogeneous">True</property>
            <child>
              <widget class="GtkButton" id="Backspace_button">
                <property name="label" translatable="yes">Backspace</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="yalign">0.51999998092651367</property>
                <signal name="clicked" handler="on_Backspace_button_clicked"/>
              </widget>
              <packing>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="Clear_button">
                <property name="label" translatable="yes">清空</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="xalign">0.50999999046325684</property>
                <signal name="clicked" handler="on_Clear_button_clicked"/>
              </widget>
              <packing>
                <property name="position">1</property>
              </packing>
            </child>
          </widget>
          <packing>
            <property name="expand">False</property>
            <property name="fill">False</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <widget class="GtkEntry" id="Result_entry">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="editable">False</property>
            <property name="invisible_char">•</property>
          </widget>
          <packing>
            <property name="expand">False</property>
            <property name="fill">False</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <widget class="GtkHBox" id="hbox2">
            <property name="visible">True</property>
            <property name="homogeneous">True</property>
            <child>
              <widget class="GtkButton" id="Seven_button">
                <property name="label" translatable="yes">7</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="Eight_button">
                <property name="label" translatable="yes">8</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="Nine_button">
                <property name="label" translatable="yes">9</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">2</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="Add_button">
                <property name="label" translatable="yes">+</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">3</property>
              </packing>
            </child>
          </widget>
          <packing>
            <property name="expand">False</property>
            <property name="fill">False</property>
            <property name="position">2</property>
          </packing>
        </child>
        <child>
          <widget class="GtkHBox" id="hbox3">
            <property name="visible">True</property>
            <property name="homogeneous">True</property>
            <child>
              <widget class="GtkButton" id="Four_button">
                <property name="label" translatable="yes">4</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="Five_button">
                <property name="label" translatable="yes">5</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="Six_button">
                <property name="label" translatable="yes">6</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">2</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="Minus_button">
                <property name="label" translatable="yes">-</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">3</property>
              </packing>
            </child>
          </widget>
          <packing>
            <property name="expand">False</property>
            <property name="fill">False</property>
            <property name="position">3</property>
          </packing>
        </child>
        <child>
          <widget class="GtkHBox" id="hbox4">
            <property name="visible">True</property>
            <property name="homogeneous">True</property>
            <child>
              <widget class="GtkButton" id="One_button">
                <property name="label" translatable="yes">1</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="Two_button">
                <property name="label" translatable="yes">2</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="Three_button">
                <property name="label" translatable="yes">3</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">2</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="Multiply_button">
                <property name="label" translatable="yes">*</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">3</property>
              </packing>
            </child>
          </widget>
          <packing>
            <property name="expand">False</property>
            <property name="fill">False</property>
            <property name="position">4</property>
          </packing>
        </child>
        <child>
          <widget class="GtkHBox" id="hbox5">
            <property name="visible">True</property>
            <property name="homogeneous">True</property>
            <child>
              <widget class="GtkButton" id="Zero_button">
                <property name="label" translatable="yes">0</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="Sign_button">
                <property name="label" translatable="yes">-/+</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">1</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="Equal_button">
                <property name="label" translatable="yes">=</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">2</property>
              </packing>
            </child>
            <child>
              <widget class="GtkButton" id="Divide_button">
                <property name="label" translatable="yes">/</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </widget>
              <packing>
                <property name="position">3</property>
              </packing>
            </child>
          </widget>
          <packing>
            <property name="expand">False</property>
            <property name="fill">False</property>
            <property name="position">5</property>
          </packing>
        </child>
      </widget>
    </child>
  </widget>
</glade-interface>

 

2,callbacks.c

 

#include <gtk/gtk.h>
#include <glade/glade.h>

#include <stdio.h>
#include <time.h>

#include "callbacks.h"

#define GLADE_FILE "calc.glade"

#define MAX_ENTRY_NUMBER    4 //最大允许数目


//全局变量
MainWindow* mwin;

gint entry_number = 0; //当前输入的数字个数
gint operator     = 5; //当前运算,0表示无运算,1表示“加号”,2表示“减号”,3表示“乘号”,4表示“除号”,5表示“等号”,
gint result       = 0; //上一次运算的结果
gint sign         = 0; //前一个按键是否为操作键


GtkWindow*
create_main_window(void)
{
    mwin = g_new0(MainWindow, 1);//动态分配内存,并清0
    mwin->gxml = glade_xml_new (GLADE_FILE, NULL, NULL); //关联界面
   
    /* This is important */
    glade_xml_signal_autoconnect (mwin->gxml);
   
    mwin->window =
        (GtkWindow*)glade_xml_get_widget(mwin->gxml, "window1");  //关联控件
//关联显示框
    mwin->result_entry =
        (GtkEntry*)glade_xml_get_widget(mwin->gxml, "Result_entry");

//关联符号按钮
    mwin->sign_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Sign_button");

    g_signal_connect(G_OBJECT(mwin->sign_button),"clicked",
                     G_CALLBACK(on_Sign_button_clicked),NULL);
//关联数字按钮
    mwin->zero_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Zero_button");

    g_signal_connect(G_OBJECT(mwin->zero_button),"clicked",
                     G_CALLBACK(on_Num_button_clicked),(gpointer)0);

    mwin->one_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "One_button");

    g_signal_connect(G_OBJECT(mwin->one_button),"clicked",
                     G_CALLBACK(on_Num_button_clicked),(gpointer)1);

    mwin->two_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Two_button");

    g_signal_connect(G_OBJECT(mwin->two_button),"clicked",
                     G_CALLBACK(on_Num_button_clicked),(gpointer)2);

    mwin->three_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Three_button");

    g_signal_connect(G_OBJECT(mwin->three_button),"clicked",
                     G_CALLBACK(on_Num_button_clicked),(gpointer)3);

    mwin->four_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Four_button");

    g_signal_connect(G_OBJECT(mwin->four_button),"clicked",
                     G_CALLBACK(on_Num_button_clicked),(gpointer)4);

    mwin->five_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Five_button");

    g_signal_connect(G_OBJECT(mwin->five_button),"clicked",
                     G_CALLBACK(on_Num_button_clicked),(gpointer)5);

    mwin->six_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Six_button");

    g_signal_connect(G_OBJECT(mwin->six_button),"clicked",
                     G_CALLBACK(on_Num_button_clicked),(gpointer)6);

    mwin->seven_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Seven_button");

    g_signal_connect(G_OBJECT(mwin->seven_button),"clicked",
                     G_CALLBACK(on_Num_button_clicked),(gpointer)7);

    mwin->eight_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Eight_button");

    g_signal_connect(G_OBJECT(mwin->eight_button),"clicked",
                     G_CALLBACK(on_Num_button_clicked),(gpointer)8);

    mwin->nine_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Nine_button");

    g_signal_connect(G_OBJECT(mwin->nine_button),"clicked",
                     G_CALLBACK(on_Num_button_clicked),(gpointer)9);

//关联操作按钮
    mwin->add_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Add_button");

    g_signal_connect(G_OBJECT(mwin->add_button),"clicked",
                     G_CALLBACK(on_operator_button_clicked),(gpointer)1);

    mwin->minus_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Minus_button");

    g_signal_connect(G_OBJECT(mwin->minus_button),"clicked",
                     G_CALLBACK(on_operator_button_clicked),(gpointer)2);

    mwin->multiply_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Multiply_button");

    g_signal_connect(G_OBJECT(mwin->multiply_button),"clicked",
                     G_CALLBACK(on_operator_button_clicked),(gpointer)3);

    mwin->divide_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Divide_button");

    g_signal_connect(G_OBJECT(mwin->divide_button),"clicked",
                     G_CALLBACK(on_operator_button_clicked),(gpointer)4);

    mwin->equal_button =
        (GtkButton*)glade_xml_get_widget(mwin->gxml, "Equal_button");

    g_signal_connect(G_OBJECT(mwin->equal_button),"clicked",
                     G_CALLBACK(on_operator_button_clicked),(gpointer)5);

    return mwin->window;
}

//回退键响应函数
void
on_Backspace_button_clicked(GtkWidget* w, gpointer data)
{
    printf("clicked Backspace button button/n");

    gint i;
    const gchar *str_in;
    gchar str_out[10];

    if(1 == sign)
    {
        entry_number = 0;
        sign = 0;

        str_out[0] = '0';
        str_out[1] = '/0';

        gtk_entry_set_text(mwin->result_entry, str_out);//写入新数据
        return;
    }

    if(0 == entry_number)
        return;
    entry_number--;

    str_in = gtk_entry_get_text(mwin->result_entry);//获得以前输入的数据

    //处理数据
    for(i=0; '/0' != str_in[i]; i++)
        str_out[i] = str_in[i];
    str_out[i-1] = '/0';

    gtk_entry_set_text(mwin->result_entry, str_out);//写入新数据
}

//清除键响应函数
void
on_Clear_button_clicked(GtkWidget* w, gpointer data)
{
    printf("clicked Clear button button/n");

    //清除状态
    operator     = 5;
    result       = 0;

    gchar str_out[10];

    entry_number = 0;

    sign       = 0;
    str_out[0] = '0';
    str_out[1] = '/0';

    gtk_entry_set_text(mwin->result_entry, str_out);//写入新数据
}

//符号键响应函数
void
on_Sign_button_clicked(GtkWidget* w, gpointer data)
{
    printf("clicked Sign button button/n");

    gint i = 0;
    const gchar *str_in;
    gchar str_out[10];

    if(1 == sign)
    {
        entry_number = 0;
        sign = 0;

        str_out[0] = '0';
        str_out[1] = '/0';

        gtk_entry_set_text(mwin->result_entry, str_out);//写入新数据
        return ;
    }


    str_in = gtk_entry_get_text(mwin->result_entry);//获得以前输入的数据

    if('-' == str_in[0])
    {
        for(i=0;'/0' != str_in[i]; i++ )
            str_out[i] = str_in[i+1];
    }
    else
    {
        str_out[0] = '-';
        if('0' != str_in[0])
        {
            for(;'/0' != str_in[i]; i++ )
                str_out[i+1] = str_in[i];
        }
        str_out[i+1] = '/0';
    }

    gtk_entry_set_text(mwin->result_entry, str_out);//写入新数据
}

//数字键响应函数
void
on_Num_button_clicked(GtkWidget* w, gint data)
{
    printf("你按下的是数字键:%d/n",data);

    GtkWidget* dialog; //消息提示对话框
    gchar message[100];//显示的消息内容

    gint i = 0;
    const gchar *str_in;
    gchar str_out[10];

    if(1 == sign)
    {
        entry_number = 0;
        sign = 0;

        str_out[0] = data + '0';
        str_out[1] = '/0';

        gtk_entry_set_text(mwin->result_entry, str_out);//写入新数据
        return;
    }

    str_in = gtk_entry_get_text(mwin->result_entry);//获得以前输入的数据

    if(0 == data)//处理0
    {
        if(('-' == str_in[0]) || ('0' == str_in[0]))
            return;
        else if('/0' == str_in[0])
        {
            str_out[0] = '0';
            str_out[1] = '/0';

            gtk_entry_set_text(mwin->result_entry, str_out);//写入新数据
            return;
        }
    }

    if(MAX_ENTRY_NUMBER == entry_number)//处理超出限制问题
    {
        sprintf(message,"最多允许输入的数字为:%d",MAX_ENTRY_NUMBER);
        dialog = gtk_message_dialog_new(NULL,  //构建对话框
                GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                GTK_MESSAGE_WARNING,
                GTK_BUTTONS_OK,
                message);
        gtk_dialog_run(GTK_DIALOG(dialog)); //运行对话框
        gtk_widget_destroy(dialog);  //销毁对话框
        return;
    }


    //处理数据
    if('0' != str_in[0])
    {
        for(; '/0' != str_in[i]; i++)
            str_out[i] = str_in[i];
    }
    str_out[i] = (gchar)data + '0';
    str_out[i+1] = '/0';

    gtk_entry_set_text(mwin->result_entry, str_out);//写入新数据

    entry_number++;
}

//0表示无运算,1表示“加号”,2表示“减号”,3表示“乘号”,4表示“除号”,5表示“等号”,
//操作键响应函数
void
on_operator_button_clicked(GtkWidget* w, gint data)
{
    printf("你按下的是操作键:%d/n",data);
    printf("其中:1表示“加号”,2表示“减号”,3表示“乘号”,4表示“除号”,5表示“等号”/n");

    gint j,i = 0;
    const gchar *str_in;
    gchar str_out[10];
    gchar str_out1[10];
    gint  input = 0; //本次输入的数值

    GtkWidget* dialog; //消息提示对话框

    str_in = gtk_entry_get_text(mwin->result_entry);//获得以前输入的数据

    if(1 == sign)
    {
        operator = data;
        return;
    }
    if('-' == str_in[0])
    {
        for(i=1;'/0' != str_in[i]; i++ )
            input = (input * 10) + (str_in[i] - '0');
        input = 0 - input;
    }
    else
    {
        for(i=0;'/0' != str_in[i]; i++ )
            input = (input * 10) + (str_in[i] - '0');
    }

    switch(operator)
    {
        case 1:
            result = result + input;
            break;
        case 2:
            result = result - input;
            break;
        case 3:
            result = result * input;
            break;
        case 4:
           
            if(0 == input)
            {
                dialog = gtk_message_dialog_new(NULL,  //构建对话框
                        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                        GTK_MESSAGE_ERROR,
                        GTK_BUTTONS_CLOSE,
                        "除0非法");
                gtk_dialog_run(GTK_DIALOG(dialog)); //运行对话框
                gtk_widget_destroy(dialog);  //销毁对话框

                //清除状态
                operator     = 5;
                result       = 0;
                return;
            }
                        result = result / input;
            break;
        case 5:
            result = input;
            break;
    }


    input=result;
    if(0 == input)
    {
        str_out[0] = '0';
        str_out[1] = '/0';
    }
    else
    {
        j=i=0;
        if(0 > input)
        {
            str_out[j++] = '-';
            input = 0 - input;
        }
        while(0 != input)
        {
            str_out1[i++] = (input % 10) + '0';
            input = input / 10;
        }
        while(i>0)
        {
            str_out[j++] = str_out1[--i];
        }
        str_out[j] = '/0';
    }

    gtk_entry_set_text(mwin->result_entry, str_out);//写入新数据
    operator = data;
    sign = 1;
}

 

3,callbacks.h

 

#include <gtk/gtk.h>
#include <glade/glade.h>

typedef struct _MainWindow MainWindow;

struct _MainWindow {
    GladeXML *gxml;
    GtkWindow *window;

//显示框
    GtkEntry *result_entry;

//符号按钮
    GtkButton *sign_button;

//数字按钮
    GtkButton *zero_button;
    GtkButton *one_button;
    GtkButton *two_button;
    GtkButton *three_button;
    GtkButton *four_button;
    GtkButton *five_button;
    GtkButton *six_button;
    GtkButton *seven_button;
    GtkButton *eight_button;
    GtkButton *nine_button;

//操作按钮
    GtkButton *add_button;
    GtkButton *minus_button;
    GtkButton *multiply_button;
    GtkButton *divide_button;
    GtkButton *equal_button;
};

extern MainWindow* mwin;

GtkWindow* create_main_window(void);


void on_Backspace_button_clicked(GtkWidget* w, gpointer user_data);//回退键响应函数

void on_Clear_button_clicked(GtkWidget* w, gpointer user_data);//清除键响应函数

void on_Sign_button_clicked(GtkWidget* w, gpointer user_data);//符号键响应函数

void on_Num_button_clicked(GtkWidget* w, gint data);//数字键响应函数

void on_operator_button_clicked(GtkWidget* w, gint data);//操作键响应函数

 

4,main.c

 

#include <gtk/gtk.h>
#include <glade/glade.h>

#include "callbacks.h"
//gcc -o hello hello.c `pkg-config --cflags --libs libglade-2.0` -export-dynamic

int main(int argc, char *argv[]) {
    GtkWidget* window;   

    gtk_init(&argc, &argv);

    window = (GtkWidget*)create_main_window();
    gtk_widget_show (window);

    /* start the event loop */
    gtk_main();


    return 0;
}

 

5,Makefile

 

#以#开头表示是注释行,以Tab键开头表示命令行,'/'表示之后一行合并到前一行,其后不能有任何字符
CC=gcc
PROG_NAME=calc
INCS=
SRCS= /
    main.c /
    callbacks.c
#从 xx.c 文件得到 xx.o 文件
OBJS=${SRCS:.c=.o}
#编译 GTK 程序时要用到的库
LIBS=libglade-2.0
#---- 用户修改区域 结束

# -O2
CFLAGS=`pkg-config --cflags ${LIBS}` -g -Wall
LDFLAGS=`pkg-config --libs ${LIBS}`   -g -Wall
all: ${PROG_NAME}
${PROG_NAME}:${OBJS}
    ${CC} -o ${PROG_NAME} ${OBJS} ${LDFLAGS} -export-dynamic
#注意:上边”${CC}" 的前边有一个 TAB 键,而不是空格
#如果有头文件进行修改,则自动编译源文件
${OBJS}:${INCS}
.c.o:
    ${CC} -c $<   ${CFLAGS}
clean:
    rm -f *.o   ${PROG_NAME}
rebuild: clean all

 

6,Readme.txt

 

计算器程序:
使用GTK2.0开发,Glade3设计界面。
包含全部源码,glade文件,Makefile文件,可执行文件
可完整实现带符号的四位是的加减乘除运算,添加大数运算模块可实现任意位数的加减乘除运算,是你学习C语言及GTK界面编程不可不看的案例。

原创粉丝点击