LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1156|回复: 8

書藉 -- 清華大學出版社,GTK+2.0 編程範例,問題請教

[复制链接]
发表于 2003-8-4 12:44:00 | 显示全部楼层 |阅读模式
本人是編程初哥,只對 Slackware Linux Packaging 略有經驗。

跟據書中的教導,第一章的九個範例,都能成功 compile 和執行,中文也能顯示。

但一進入第二章,菜單與工具欄,便遇上困難。第一個範例中,(全一行)

g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(on_menu_activate), //(gpointer)("剪切")); (gpointer)("Cut"));

compile 出錯,需要修改成(分成兩行,第二行應是注釋)

g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(on_menu_activate), (gpointer)("剪切"));
// (gpointer)("Cut"));

才能成功 compile.

但執行時卻未能顯示中文"剪切",只是全部英文。

第二個範例中,創建菜單的快捷方法中使用了

static GtkItemFactoryEntry menu_items[]

但 compile 成功後卻不能執行呢!(Segmentation Fault)

(是不是菜單中含有中文字的問題呢?)

產生這疑問後,便進入第十一章中的 I18N 和 L10N 部份,輸入範例後

Compile 和成功執行 (英文版本)

跟著建立 inter.po 檔案,?K鍵入相關中文?息後產生 inter.mo 檔案,跟據指示放在相應的位置:
/home_path/gtk_lesson/locale/zh_TW/LC_MESSAGES/

但是到最後還是不能如望的顯示任何中文?息呢?真摩不著頭腦?

望各位指教!
发表于 2003-8-4 15:51:32 | 显示全部楼层

我来回答,但不知道对不对

第一个问题:(gpointer)("剪切")只是要传给回调函数的参数(数据),不知你要在哪里,怎样显示中文”剪切“?
第二个问题:你有没有在gtk_init (&argc,&argv);前加入语句gtk_set_locale(); ??
发表于 2003-8-4 18:19:45 | 显示全部楼层
呵呵,楼主原来是香港同胞,欢迎欢迎!
 楼主| 发表于 2003-8-4 20:35:49 | 显示全部楼层
Linux_Lyb
多謝回?汀

第一个问题:一言驚醒,問題不在這裡,現附上一圖,菜單上出現”文件”中文字是由這句作用

rootmenu = gtk_menu_item_new_with_label(”文件”);

但是,menuitem 要如何顯示中文字形,如書中圖呢?

eg.

menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_CUT, accel_group);
gtk_menu_shell_append(GTK_MENU_SHELL(editmenu), menuitem);
g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(on_menu_activate), (gpointer)("剪切"));
// (gpointer)("Cut"));



第二个问题:

整個榴案是這樣的:

/* 創建選單的快捷方法 itemfact.c */
#include <gtk/gtk.h>
void on_menu_activate (GtkMenuItem *item, gpointer data); //回調函數聲明

static GtkItemFactoryEntry menu_items[] = { //定義選單集
{"/ 文件 (_F) ", NULL, NULL, 0, "<Branch>"},
{"/ 文件 (_F) /新建", NULL, on_menu_activate, "新建", "<StockItem>", GTK_STOCK_NEW},
{"/ 文件 (_F) /打開", NULL, on_menu_activate, "打開", "<StockItem>", GTK_STOCK_OPEN},
{"/ 文件 (_F) /儲存", NULL, on_menu_activate, "儲存", "<StockItem>", GTK_STOCK_SAVE},
{"/ 文件 (_F) /另儲存為", NULL, on_menu_activate, "另儲存為", "<StockItem>", GTK_STOCK_SAVE_AS},
{"/ 文件 (_F) /-", NULL, NULL, 0, "<Separator>"},
{"/ 文件 (_F) /離開", NULL, on_menu_activate, "離開", "<StockItem>", GTK_STOCK_QUIT},
{"/ 編輯 (_E) ", NULL, NULL, 0, "<Branch>"},
{"/ 編輯 (_E) /剪下", NULL, on_menu_activate, "剪下", "<StockItem>", GTK_STOCK_CUT},
{"/ 編輯 (_E) /複製", NULL, on_menu_activate, "複製", "<StockItem>", GTK_STOCK_COPY},
{"/ 編輯 (_E) /貼上", NULL, on_menu_activate, "貼上", "<StockItem>", GTK_STOCK_PASTE},
{"/ 編輯 (_E) /搜尋", NULL, on_menu_activate, "搜尋", "<StockItem>", GTK_STOCK_FIND},
{"/ 幫助 (_H) ", NULL, NULL, 0, "<LastBranch>"},
{"/ 幫助 (_H) /幫助", NULL, on_menu_activate, "幫助", "<StockItem>", GTK_STOCK_HELP},
{"/ 幫助 (_H) /關於...", NULL, on_menu_activate, "關於", NULL}
};

void on_menu_activate (GtkMenuItem* item, gpointer data) {
        //g_print("選單項目");
        //g_print(" %s ", (gchar*)data);
        //g_print("被激活\n");
        g_print("Menu item %s is pressed.\n", (gchar*)data);
}

//主函數
int main(int argc, char *argv[]) {
        GtkWidget *window;
        GtkWidget *box;
        GtkWidget *menubar;
        GtkWidget *menu;
        GtkAccelGroup *accel_group;
        GtkItemFactory *item_factory;

        gint n = 15;
        gtk_init(&argc, &argv);/* 關鍵,如果不寫這行,有時會出問題 */
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(window), "添加選單的快捷方法");
        g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(gtk_main_quit), NULL);
        accel_group = gtk_accel_group_new();
        box = gtk_vbox_new(FALSE, 0);
        gtk_container_add(GTK_CONTAINER(window), box);
        gtk_widget_show(box);
        item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<menu>", accel_group);
        gtk_item_factory_create_items(item_factory, n, menu_items, NULL);
        gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
        menubar = gtk_item_factory_get_widget(item_factory, "<main>");
        gtk_box_pack_start(GTK_BOX(box), menubar, FALSE, FALSE, 0);
        gtk_widget_show(menubar);
        gtk_widget_show(window);
        gtk_main();
        return FALSE;
}

多多指教!!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
发表于 2003-8-4 22:50:55 | 显示全部楼层
这本书我也有,以后有问题多交流。这第二章的问题,好像不是很大,只是注意空格就行了吧。
发表于 2003-8-4 23:38:03 | 显示全部楼层
其实原书的格式是这样的:
g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(on_menu_activate), //(gpointer)("剪切"));
(gpointer)("Cut"));
在C语言中,"//"表示注释直到行尾。在这句里,//(gpointer)("剪切")); 都是注释,而后面(gpointer)("Cut"));才是真正的句尾。
其实,作者是告诉读者,这两种写法都可以。如果按书上写法,当按下此菜单项会显示"Menuitem Cut is pressed.",另一种则会显示"Menuitem 剪切 is pressed."。

"剪切"菜单项是由这句来生成的:
menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_CUT, accel_group);
它是调用GTK系统资源GTK_STOCK_CUT,也就是说如果你的系统是英文,它就显示"CUT",如果是中文就显示"剪切",这样在不同的语言平台下就不用改程序,很方便的。

第二问题:
程序本身应该没有什么问题,我当时是手工敲进去,编译运行一点问题也没有。你可以检查一下是不是哪儿少输了点什么,Segmentation Fault错误一般是由于内存分配语句(如定义一个字符串之类)少写了点东西造成的,一定得仔细检查。

另:GTK程序里的中文一般是UTF-8格式(记不清),建议在GEDIT里写,因为它的默认存盘格式是就是UTF-8。如果是其它格式,就会出问题了
发表于 2003-8-5 02:39:06 | 显示全部楼层
界面建議用glade?斫
发表于 2003-8-6 10:43:37 | 显示全部楼层

第二个问题已经找出

menubar = gtk_item_factory_get_widget(item_factory, "<main>");
改为
menubar = gtk_item_factory_get_widget(item_factory, "<menu>");
就可正常运行了。
  如果有什么不懂,看gtk-demo里的例程吧
 楼主| 发表于 2003-8-9 00:10:45 | 显示全部楼层
Linux_Lyb 兄:

多謝您的指點!令我加添信心。:thank 我也在?兟摼W上找到一個教材,gtk-tutorial.20021027.tar.gz,望能中英互補。最後附上一圖作結。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表