Linux图形界面编程简单教程(附计算器源代码)

时间:2021-08-19 11:42:59

如何在linux下用gtk开发图形界面应用程序

最近爱上了Linux,尤其是在读了我博客转载到一篇文章之后,更加的决定这辈子要和linux做永远的情人。正好博主这学期也学习了Linux操作系统。当然了,在大学里就是随便的教教,我们也在下边随便的打打酱油而已。前天突然心血来潮,何不做一个图形界面的程序来练练手。说做就做,先声明,本人菜鸟,所以这个过程十分的漫长,花了整整一天的时间。
首先,就是搭建gtk开发环境。光是熟悉这个概念就用了好长时间。你可以自己百度或着查阅相关资料。这里我也推荐一些比较好的博文给大家。
http://wenku.baidu.com/view/f996fa563c1ec5da50e27099.html
我使用的是ubuntu,默认的是gnome,装gtk的时候可是花费了不少时间,因为老是提示说依赖关系不正确而安装不了开发环境。后来在一个博客上找到了解决方法,现在分享给大家。如果提示下面到问题:
下列软件包有未满足的依赖关系:
gnome-devel: 依赖: libgdl-1-dev (>= 2.28) 但是它将不会被安装
推荐: gnome-core-devel 但是它将不会被安装
E: 破损的软件包
那么可以使用下面到命令:
sudo aptitude install gnome-core-devel
http://blog.sina.com.cn/s/blog_3fbc1c610100lf91.html

安装好程序后,下面是计算器的源码:

glade_counter.c

Linux图形界面编程简单教程(附计算器源代码)Linux图形界面编程简单教程(附计算器源代码)View Code
#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];



/*........................................................................ */
//清除函数:cb_clean_clicked()
//1:清除屏幕上的内容(TURE);2:初始化变量并清屏(FALSE)

void cb_clean_clicked(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");
            }       



/*---------------------------------------------------------------------------------- */
//按下数字时的回调函数:cb_num_clicked()

void cb_num_clicked(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);

        }



/*----------------------------------------------------------------------------------*/
//按下小数点时的回调函数:cb_dot_clicked()

void cb_dot_clicked(GtkButton *button,gpointer data)
        {
           gint i;
            /*重复计算的切换开关*/
            if(have_result)
                cb_clean_clicked(FALSE);
              
            /*如果小数点在第一位则不显示*/
            if(num_count == 0)
             {
              cb_clean_clicked(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);
                    }
                
                }
        
        }



/*------------------------------------------------------------------------------------*/
//按下清零键时的回调函数:cb_back_clicked()

void cb_back_clicked(GtkButton *button,gpointer data)
        {
            cb_clean_clicked(FALSE);
        }



/*------------------------------------------------------------------------------------*/
//按下运算符时的回调函数:cb_switch_clicked()

void cb_switch_clicked(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';
        }


      
/*-------------------------------------------------------------------------------------*/
//按下等于号时的回调函数:cb_result_clicked()
          
void cb_result_clicked(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(cb_clean_clicked),NULL);
button=GTK_BUTTON(gtk_builder_get_object(builder, "button2")); 
          g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(cb_num_clicked),NULL);

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

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

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

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

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

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

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

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

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

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

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

button=GTK_BUTTON(gtk_builder_get_object(builder, "button14")); 
          g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(cb_num_clicked),NULL);
button=GTK_BUTTON(gtk_builder_get_object(builder, "button15")); 
          g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(cb_dot_clicked),NULL);
button=GTK_BUTTON(gtk_builder_get_object(builder, "button16")); 
          g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(cb_result_clicked),NULL);
button=GTK_BUTTON(gtk_builder_get_object(builder, "button17")); 
          g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(cb_switch_clicked),(gpointer)4);
  
         // 获取到 UI 对象后,GtkBuilder 对象已没有作用,释放了 
  
         g_object_unref(G_OBJECT(builder)); 

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

counter.glade(由glade界面设计大师设计好的桌面保存到文件)

Linux图形界面编程简单教程(附计算器源代码)Linux图形界面编程简单教程(附计算器源代码)View Code
<?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="spacing">2</property>
        <child>
          <object class="GtkVBox" id="vbox1">
            <property name="visible">True</property>
            <child>
              <object class="GtkLabel" id="label1">
                <property name="visible">True</property>
                <property name="label" translatable="yes">&#x674E;&#x5C0F;&#x8D85;&#x7248;&#x6743;&#x6240;&#x6709;   &#x7F51;&#x7AD9;&#xFF1A;www.leeinn.info</property>
              </object>
              <packing>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkHBox" id="hbox1">
                <property name="visible">True</property>
                <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">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkButton" id="button1">
                    <property name="label" translatable="yes">CE</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">1</property>
                  </packing>
                </child>
              </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="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="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="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>
            <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="left_attach">2</property>
                <property name="right_attach">3</property>
                <property name="top_attach">2</property>
                <property name="bottom_attach">3</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

编译命令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

glade界面设计大师截图:

Linux图形界面编程简单教程(附计算器源代码)

 

程序运行截图:

Linux图形界面编程简单教程(附计算器源代码)