这个文章来自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/
时间:2009-08-10 17:15
来源:
作者:blackspace
原文链接