歡迎您光臨本站 註冊首頁

用GTK+/GTK--widget編寫gnome面板applet

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  翻譯說明:
    這個文章來自http://developer.gnome.org/doc/tutorials/applet/index.html


這個文檔描述如何用libpanel-applet庫編寫GNOME面板applet。這裡假定讀者精通GTK+庫(http://www.gtk.org)或者GTK--庫(http://gtkmm.sourceforge.net)。這個SGML原始文檔可以在這裡得到(http://cactus.rulez.org/doc/articles/panelapplet.sgml)。

介紹

如果你之前用過GNOME(或者看過GNOME的截圖),你一定注意到在屏幕一邊或者屏幕多個邊的GNOME面板。在這些面板你可以加入應用啟動器,菜單和applet。一個面板applet是一個小的程序,它用GNOME面板的一小部分顯示用戶介面。在標準的gnome-panel發行版中有一些基本的applet,例如pager或者聲音混合控制。

我們用來創建applet的庫叫做libpanel-applet。它允許無縫的集成GTK部件到面板中。當然,你需要運行時和編譯時版本(編譯時版本一般在發行版中用-dev或者-devel標記)。



修改普通的GTK

你的普通GTK應用看起來像下面的代碼:
例子1:沒有面板的應用版本:

 #include <gtk/gtk.h>
 int main(int argc, char **argv)
 {
    /* ... we build the user interface ... */
    gtk_init(&argc, &argv); /* #1 */
    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); /* #2 */
    gtk_window_set_title(GTK_WINDOW(window), PACKAGE);
    /* controls is the name of the container all our widgets are in */
    gtk_container_add(GTK_CONTAINER(window), controls); /* #3 */
    gtk_widget_show(window);

    /* Everything's ready to begin our main loop */
    gtk_main(); /* #4 */
    return 0;
 }

我們現在需要改變的是那些有數字標識的行。改變這些行為GNOME面板applet對應需要的行。

例子2:面板版本

#include <applet-widget.h>
 int main(int argc, char **argv)
 {
    applet_widget_init(PACKAGE, VERSION, argc, argv,
                       NULL, 0, NULL); /* #1 */
    GtkWidget* applet = applet_widget_new(PACKAGE); /* #2 */
    applet_widget_add(APPLET_WIDGET(applet), controls); /* #3 */
    gtk_widget_show(applet);
    applet_widget_gtk_main(); /* #4 */
    return 0;
 }

#2和#3行能很好的自我說明:我們用applet容器代替GTK window,用applet容器包裝我們的部件。
#1需要PACKAGE和VERSION信息,這些信息用來註冊目的。argc和argv被用來分析applet註冊機制使用的選項(使用any_applet --help看一個完整的列表)。最後的3個參數(在我們的例子中沒有用到)的描述在popt文檔中。

既然沒有Applet_widget包裝器,當使用GTK--的時候你不得不用下面的例子:

例子3 GTK--修正
    controls.show_all();
        applet_widget_add(APPLET_WIDGET(window),
                      GTK_WIDGET(controls.gtkobj())); /* #3 */
   


自定義菜單

如果你在桌面現在正存在的applet上點擊滑鼠的按鈕3,你將注意到一個有"Remove"和“Move“選擇的stock菜單彈出。一些applet也有自定義的菜單例如“about“或者”Properties“。有一些函數用來操作這個菜單。
void applet_widget_register_callback(AppletWidget *applet, char *name, char *menutext, AppletCallbackFunc func, gpointer data);

void applet_widget_register_stock_callback(AppletWidget *applet, char *name, char *stock_type, char *menutext, AppletCallbackFunc func, gpointer data);

插入一個菜單項到面板菜單。name用來標識菜單項,它也是菜單項的路徑。採用這個路徑的方式你可以說明那個子菜單是新菜單的父菜單。menutext是這個菜單項簡單的label。func是一個返回void的函數的指針(當它被調用時有兩個參數,一個AppletWidget*類型和gpointer類型).

applet_widget_register_stock_callback和applet_widget_register_callback相似,除了stock_type參數被用來指定一個stock圖片(可以從libgnomeui/gnome-stock.h看到一個定義列表)。

void applet_widget_register_callback_dir(AppletWidget *applet, char *name, char *menutext);

void applet_widget_register_stock_callback_dir(AppletWidget *applet, char *name, char *stock_type, char *menutext);

創建一個新的子菜單(譯者註:子菜單用來存放菜單項),此後你可以通過用路徑說明名字的方法用applet_widget_register_callback插入菜單項到這個子菜單中,。同樣applet_widget_register_stock_callback_dir插入一個stock圖片。

void applet_widget_unregister_callback(AppletWidget *applet, char *name);

void applet_widget_unregister_callback_dir(AppletWidget *applet, char *name);

通過名字刪除菜單項或者子菜單。

例子

例子4,菜單示例
    applet_widget_register_stock_callback (APPLET_WIDGET(applet),
                                           "about",
                                           GNOME_STOCK_MENU_ABOUT,
                                           _("About"),
                                           &my_applet_cb_about,
                                           NULL);
                     
        applet_widget_register_callback_dir (APPLET_WIDGET(applet),
                         "submenu",
                         _("Test submenu"));
                  
        applet_widget_register_callback (APPLET_WIDGET(applet),
                     "submenu/window",
                     _("Open window"),
                     &my_applet_cb_showwnd,
                     NULL);
   
    說明:這個_("") 是GNU Gettext支持的簡單的宏,被定義在一個GNOME支持的頭文件中。

如果你用GTK--,這個data參數可以用來調用一個實例的方法,參考下面的例子:

例子4:用data保存一個實例
void my_applet_cb_foo(AppletWidget* caller, gpointer data)
{
    (My_Class*)data->foo();
}

void My_Class::foo()
{
    /* For example, bar could be a member field */
    bar = quux();
   
}

void My_Class::My_Class()
{
    /* ... */
    applet_widget_register_callback (APPLET_WIDGET(applet),
                     "foo",
                     "Update foo",
                     &my_applet_cb_foo,
                     (gpointer)this);
}
說明:如果我們傳遞&My_Class::foo作為這個回調函數,沒有方法從這個成員函數能得到對象實例(當然靜態成員函數沒有這個問題)。

說明:當你用gpointer傳遞this,一定cast成回調函數里的類型,否則數據摧毀會發生(你應該用各種_cast<>函數來作運行時cast)。




編譯applet

編譯一個GNOME面板applet需要一些自定義的編譯標誌。通常gnome-config腳本可以用來自動地包括一些必要的標誌。
     $ gcc `gnome-config --cflags applets` -o my_applet.o -c my_applet.c
          $ gcc `gnome-config --libs applets` -o my_applet my_applet.o
          $ ./my_applet

說明:如果你得到一個錯誤信息,請檢查libpanel_applet是否安裝正確。



附加的文件


在“編譯applet”這一節,你在命令行手動啟動applet。如果你希望你的applet能讓在你的系統上的別的用戶在“Add applet菜單”里訪問,你需要提供兩個信息文件:/etc/CORBA/servers/my_applet.gnorba 和/usr/share/applets/Category/my_applet.desktop。這兩個文件是簡單明了的,下面兩個例子(希望如此)已經很充分了。

例子6 .gnorba文件
    [my_applet]
    type=exe
    repo_id=IDL:GNOME/Applet:1.0
    description=Example panel applet
    location_info=my_applet
例子7 .desktop文件
    [Desktop Entry]
    Name=My very own applet
    Name[hu]=Az én saját kisalkalmazásom
    Comment=An example applet
    Comment[hu]=Egy példa-kisalkalmazás
    Exec=my_applet --activate-goad-server=my_applet
    Icon=my_icon.xpm
    Terminal=0
    Type=Application
說明:
    需要保證傳遞給applet_widget_init函數 的app_id和用在Exec這一行的標識相同(參考“修改普通的GTK”這一節)。

你能在.desktop包含一些不同語言和地區的Name和Comment。



附錄 A :網路資源連接和一些有用的文件


    *      .gnorba 模板文件 http://developer.gnome.org/doc/tutorials/applet/template.gnorba
    *      .desktop 模板文件 http://developer.gnome.org/doc/tutorials/applet/template.desktop
    *      RadioActive, 一個簡單的GTK--面板applet http://cactus.rulez.org/radioactive/

   


[火星人 ] 用GTK+/GTK--widget編寫gnome面板applet已經有621次圍觀

http://coctec.com/docs/program/show-post-71646.html