引用自:
http://blog.chinaunix.net/u2/81187/showart_1855688.html
学习 GTK 也有一段时间了,但总是深入不下去,究其原因,是因为没有实际的处理过问题,没有完整的去自已实现过编程。
因此就萌发了自已写一个软件工具的想法,想来想去,决定从写一个记事本开始,以后慢慢再开发一些比较复杂的。
首先做好规划,安排工作进度 , 防止半途而废 ( 个人的不良习惯,做事有始无终,一定要好好克服 )
第一步是界定功能,也就是列出想要实现的功能,虽然是个人练习,也得有个需求分析。
目前能想到的 feature list 如下:
1. 基本的新建、打开、保存文件;
2. 编辑选项有复制、拷贝功能;
3. 语法高亮,
4. 搜索、替换功能;
第二步是界面搭建 , 由于不像 win 开发 VB 、 VC 那样有一个 IDE ,决定先用 glade 将界面搭建起来,代码后实现。其实界面本身也没有什么东西,不用画草图也可以想得出来如何实现。
主要部件:菜单栏、工具栏、文本区、状态栏顺序搭起来就可以了,不多述了。
第三步 code 实现。对于我来说 ,glade 只是一个参考,界面我还是用代码 code 出来的。但这个不是重点,重点是如何编写相应的 callback function, 这才是实现功能的重点。目前来讲,也是遇到问题比较多的地方。
以下是我目前的实现代码,给大家参考。当然,后续还是会再添加,修改,完善的。毕竟目前还只是个半成品:
/*
===============================================================================
*
* Filename: notebook.c
*
* Description: notebook test programe
*
* Version: 1.0
* Revision: none
* Compiler: gcc
*
* Author: Dr.Wp (mn),
* Company: SunLinux
*
* =========================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include "gtk/gtk.h"
//#include "notebook.h"
//#include "interface.h"
//#include "callbacks.h"
void menu_item_open_file(GtkWidget *widget,gpointer data);
void menu_item_response(GtkWidget *widget,gpointer data);
gint
delete_event(GtkWidget *widget,
GdkEvent *event,
gpointer data)
{
g_print("delete event\n");
return TRUE;
}
void
destroy_event(GtkWidget *widget,
gpointer data)
{
gtk_main_quit();
}
int
main(int argc,
char* argv[])
{
GtkWidget *notebk_win;
GtkWidget *vbox1;
GtkWidget *textArea;
GtkWidget *statusBar;
GtkWidget *menuBar;
GtkWidget *menu;
//GtkWidget *button;
GtkWidget *item;
GtkWidget *openItem,*saveItem,*quitItem;
GtkWidget *copyItem,*pasteItem,*cutItem;
GtkWidget *aboutItem,*helpItem;
GtkWidget *toolbar;
GtkToolItem *new;
GtkToolItem *open;
GtkToolItem *save;
GtkToolItem *sep;
GtkToolItem *exit;
//init window for receive Natuils event
gtk_init(&argc,&argv);
//create notebook main window
notebk_win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position (GTK_WINDOW(notebk_win), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(notebk_win),
800,
600);
gtk_window_set_icon_from_file(GTK_WINDOW(notebk_win),"tux.ico",NULL);
g_signal_connect(G_OBJECT(notebk_win),"delete_event",
G_CALLBACK(delete_event),NULL);
g_signal_connect(G_OBJECT(notebk_win),"destroy",
G_CALLBACK(destroy_event),NULL);
//create vbox,and put menubar,textarea,status bar into it;
vbox1 = gtk_vbox_new(FALSE,0);
gtk_container_set_border_width(GTK_CONTAINER(vbox1),0);
//1.create menu for notebook
menuBar = gtk_menu_bar_new();
gtk_box_pack_start(GTK_BOX(vbox1),menuBar,FALSE,FALSE,0);
gtk_widget_show(menuBar);
//1.1 create "File" of menu
menu = gtk_menu_new();
//create image icon item "new"
openItem = gtk_image_menu_item_new_from_stock(GTK_STOCK_OPEN,NULL);
gtk_menu_append(GTK_MENU(menu),openItem);
gtk_widget_show(openItem);
//create image icon item "save"
saveItem = gtk_image_menu_item_new_from_stock(GTK_STOCK_SAVE,NULL);
gtk_menu_append(GTK_MENU(menu),saveItem);
gtk_widget_show(saveItem);
//create image icon item "quit"
quitItem = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT,NULL);
gtk_menu_append(GTK_MENU(menu),quitItem);
gtk_widget_show(quitItem);
//add menu item to menu Bar
item = gtk_menu_item_new_with_label("File");
gtk_widget_show(item);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item),menu);
gtk_menu_bar_append(GTK_MENU_BAR(menuBar),item);
//callbace for every sub menu item
g_signal_connect_swapped (G_OBJECT (quitItem), "activate",
G_CALLBACK (menu_item_response),
NULL);
g_signal_connect_swapped (G_OBJECT (openItem), "activate",
G_CALLBACK (menu_item_open_file),
NULL);
//1.2 creat "Edit"
menu = gtk_menu_new();
copyItem = gtk_image_menu_item_new_from_stock(GTK_STOCK_COPY,NULL);
gtk_menu_append(GTK_MENU(menu),copyItem);
gtk_widget_show(copyItem);
pasteItem = gtk_image_menu_item_new_from_stock(GTK_STOCK_PASTE,NULL);
gtk_menu_append(GTK_MENU(menu),pasteItem);
gtk_widget_show(cutItem);
cutItem = gtk_image_menu_item_new_from_stock(GTK_STOCK_CUT,NULL);
gtk_menu_append(GTK_MENU(menu),cutItem);
gtk_widget_show(cutItem);
item = gtk_menu_item_new_with_label("Edit");
gtk_widget_show(item);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item),menu);
gtk_menu_bar_append(GTK_MENU_BAR(menuBar),item);
//1.3 creat "Help"
menu = gtk_menu_new();
aboutItem = gtk_image_menu_item_new_from_stock(GTK_STOCK_HELP,NULL);
gtk_menu_append(GTK_MENU(menu),aboutItem);
gtk_widget_show(aboutItem);
helpItem = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT,NULL);
gtk_menu_append(GTK_MENU(menu),helpItem);
gtk_widget_show(helpItem);
item = gtk_menu_item_new_with_label("Help");
gtk_widget_show(item);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item),menu);
gtk_menu_bar_append(GTK_MENU_BAR(menuBar),item);
//2.create toolbar
toolbar = gtk_toolbar_new();
gtk_toolbar_set_style(GTK_TOOLBAR(toolbar),GTK_TOOLBAR_ICONS);
gtk_container_set_border_width(GTK_CONTAINER(toolbar),2);
new = gtk_tool_button_new_from_stock(GTK_STOCK_NEW);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar),new,-1);
gtk_widget_show(new);
open = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar),open,-1);
gtk_widget_show(open);
save = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar),save,-1);
gtk_widget_show(save);
sep = gtk_separator_tool_item_new();
gtk_toolbar_insert(GTK_TOOLBAR(toolbar),sep,-1);
gtk_widget_show(sep);
exit = gtk_tool_button_new_from_stock(GTK_STOCK_QUIT);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar),exit,-1);
gtk_widget_show(exit);
//add toolbar to vbox
gtk_box_pack_start(GTK_BOX(vbox1),toolbar,FALSE,FALSE,5);
gtk_widget_show(toolbar);
//3.add text area to box
textArea = gtk_text_view_new();
gtk_box_pack_start(GTK_BOX(vbox1),textArea,TRUE,TRUE,1);
gtk_widget_show(textArea);
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea));
//4.add status bar to box
statusBar = gtk_statusbar_new();
gtk_box_pack_start(GTK_BOX(vbox1),statusBar,FALSE,TRUE,0);
gtk_widget_show(statusBar);
//5.show main frame of notebook
gtk_container_add(GTK_CONTAINER(notebk_win),vbox1);
gtk_widget_show(vbox1);
gtk_widget_show(notebk_win);
gtk_main();
return 0;
}
void menu_item_response(GtkWidget *widget,gpointer data)
{
g_print("button pressed\n");
gtk_main_quit();
}
void menu_item_open_file(GtkWidget *widget,gpointer data)
{
GtkWidget *dialog;
GtkTextBuffer *text_buffer;
GtkTextIter iter;
dialog = gtk_file_chooser_dialog_new("Open file",
widget,
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN,GTK_RESPONSE_ACCEPT,
NULL);
//there is not create text tags
text_buffer = gtk_text_buffer_new(NULL);
gtk_text_buffer_get_iter_at_offset(text_buffer,&iter,0);
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
{
char *filename;
FILE* fd;
gchar *content;
gsize bytes;
GError *error = NULL;
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
if(filename)
{
g_file_get_contents(filename,&content,&bytes,&error);
gtk_text_buffer_set_text(text_buffer,content,-1);
}
g_free(filename);
}
gtk_widget_destroy(dialog);
}
static gint button_pressed(GtkWidget *widget,
GdkEvent *event)
{
if(event->type == GDK_BUTTON_PRESS)
{
GdkEventButton *bevent = (GdkEventButton*)event ;
gtk_menu_popup(GTK_MENU(widget),NULL,NULL,NULL,NULL,
bevent->button,bevent->time);
return TRUE;
}
return FALSE;
}
目前遇到的问题是如何打开一个文件,在gtk_text_view中显示它,这是下一步要做的工作。