如何在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

#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界面設計大師設計好的桌面保存到文件)

<?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">李小超版权所有 网站: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">●</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界面設計大師截圖:
程序運行截圖: