| 用GTK+2编制Linux平台上的定时提醒备忘录 |
| 李炳胜 |
|
《软件报》2008年18期 邮发代号:61-74
在日常生活中,为了怕忘记一些重要的事情,人们通常是带一个备忘录,将重要事情记录在上面,而对于长时间在电脑上工作的朋友,则可以使用定时提醒备忘程序来提醒自己。在Windows平台上,有许多实现这种功能的小软件,可在Linux平台上这方面的软件不多,于是笔者决定自己编制一个这样的小程序。
在Linux平台上,存在两种主流图形化编程技术QT和GTK+,因经常使用GNOME集成桌面环境,而GNOME本身就是基于GTK+开发的,并且GTK+拥有简单易用的图形化开发工具Glade2,所以笔者决定采用GTK+技术,使用Glade2作为主要开发工具来开发定时提醒备忘录程序。操作系统使用流行的Linux发行版Fedora 8,该发行版作为红帽(Redhat)企业级Linux的试验性版本,既与企业版具有良好的兼容性,又加入了一些具前瞻性的技术,且软件包的版本较新,可以使用yum命令自由地安装或更新所需软件包。
编程思路
Linux平台上的定时提醒备忘录程序思路很简单:用Glade2设计器编制一个定时提醒设置窗体,用户可选择或自行设定定时提醒的时间以及提醒的信息,使用定时器函数实现定时提醒功能,提醒用户时弹出的窗体使用开源的libnotify库(http://www.galago-project.org/)来实现。
编程实现
1、 用Glade2设计器编制定时提醒设置窗体
以普通用户身份登录Fedora8系统,进入默认的GNOME集成桌面环境,在菜单“Applications”/“Programming”下找到“Glade Interface Designer”(Glade界面设计器)项,用鼠标单击该项,出现Glade主设计器窗口,点击工具栏上的“New”按钮,将弹出一个对话框,询问创建何种类型的项目,这里我们点击“New GTK+ Project”按钮,创建一个GTK+项目。点击工具栏上的“Save”按钮,在弹出的项目选项(Project Options)对话框中设置项目文件夹的路径(Project Directory)及项目名称,项目名称设定为timer1,保存路径为/home/lbs/Projects/timer1。编程语言(Language)使用默认的“C”,点击“OK”按钮保存项目设置。
因项目中需要一个定时提醒设置窗体,所以,点击设计面板(Platter)上的窗口(window)图标,在桌面右上角将会出现一个新的空白窗体,如图1所示。在构件树面板中,选中“window1”,在构件属性窗口中对“window1”进行设置,设置窗口标题为“定时提醒备忘录”,窗口宽度设为300,高度设为260。GTK+采用称为“盒”的不可视构件来处理窗体的布局,用户可以将可视控件存放在排列的一个个“盒”中来完成界面的制作。为了在窗体上放置子构件,我们用VBOX(Vertical Box)将窗体分成三部分,即从上到下三块区域,第一块区域放置一个标签构件,设置其Label属性值为“定时提醒备忘录”,第二块区域首先放置一个框架构件frame1,然后在其上用VBOX分成八个部分,即八块区域,从上到下分别放置五选项按钮构件,标签构件和文本输入构件。第三块区域为命令按钮区,用HBOX(Horizontal Box)构件分成从左右的三块区域,分别放置三个命令按钮构件button1、button2和button3,命令按钮上显示的文字通过Label属性进行设定,分别设定为“设定”、“退出”和“测试”。
窗体界面设计完成后,首先点击Glade工具栏上的“Save”按钮进行保存,设计的窗体界面以XML格式保存为timer1.glade,然后,点击“Build”按钮,这将生成项目timer1的C源代码框架。包括GNU自动编译工具等。
2、编写程序代码
2.1了解Glade2自动生成文件的结构
Glade2生成的源代码文件放置在项目所在路径的src目录下。包括如下文件:
callbacks.c是用户编写代码最主要的源文件,里面存放了Glade2生成的大部分空的回调函数,函数的代码需要用户根据需要自行添加。callbacks.h 是callbacks.c 的头文件,包含了Glade2生成的回调函数的定义。interface.c是Glade2生成的界面源代码文件,界面构件(类似于VB中的控件)的创建及信号连接函数均放置在该文件中,对应的函数定义头文件为interface.h。main.c为项目的主调函数所在的文件,包含C程序的主函数main()。support.c为项目支持文件,对应的头文件为support.h。
2.2使用libnotify通知库
为了让定时提醒程序在设定的时间到来时提醒用户待办事项,程序需要弹出一个对话框或通知窗体来通知用户,这里我们使用Linux平台上常用的libnotify库来实现弹出的通知窗体。Fedora 8默认已经安装了libnotify库,如果没有安装,可以使用root用户身份输入命令:yum install libnotify-devel 来进行安装。安装好后,在/usr/include/libnotify目录下应能找到libnotify.h头文件。我们将实现弹出通知窗口的代码单独放在一个文件notify.c中,notify.c的程序代码为:
#include
#include
int popup(char *title,gchar *content,int tout)
{
NotifyNotification *n;
notify_init(title);
n = notify_notification_new(title, content, "stock_timer", NULL);
notify_notification_set_timeout(n, tout);
notify_notification_set_hint_int32 (n, "x", 1000);
notify_notification_set_hint_int32 (n, "y", 80);
if ( !notify_notification_show(n, NULL) ) g_warning("Notify Error\n");
return 0;
}
对应的头文件为notify.h,里面有关于popup函数的定义,内容为:
int popup(char *title,char *content,int tout)
popup函数包括三个参数,第一个参数是设定弹出的提醒窗体的标题(类似于一般窗体的标题栏),第二个参数设定在提醒窗体上显示的内容,第三个参数设定提醒窗体在用户没有手动关闭的情况下多长时间自行关闭。notify.c和notify.h文件均要放置到项目所在目录的src子目录下。因在callbacks.c文件中需要调用popup()函数,因而应在callbacks.c文件的头部增加一行:#include “notify.h”。另外还需要在由Glade2自动生成的src/Makefile文件中加入对notify.c源文件支持。用vi或gedit编辑器编辑Makefile,在行“am_timer1_OBJECTS=”最后空一格加上“notify.o”目标文件,在“PACKAGE_LIB=”和“timer1_LDADD=”行最后空一格加上“-lnotify”,在“timer1_SOURCES=”最后加上一行:“notify.c notify.h”。这样,我们就能在src目录直接输入make命令进行编译了。
2.3选项按钮功能的实现
在定时提醒设置窗体中,设定时间是通过选项(单选)按钮来实现的。为了判断用户选择了哪个选项,我们需要捕捉每个选项按钮的触发信号,并编写对应的回调函数来处理触发信号,因选项按钮较多,这里以选项按钮1为例来说明。首先,编辑项目src目录下的interface.c源文件,在新建单选按钮对象的函数之后,为单选按钮radiobutton1添加信号连接函数:
g_signal_connect ((gpointer) radiobutton1, "toggled",
G_CALLBACK (radiobutton1_toggled),
NULL);
处理单选按钮触发信号的回调函数为radiobutton1_toggled。回调函数的代码在callbacks.c文件中,我们在callbacks.h头文件中增加对radiobutton1回调函数的定义:
void radiobutton1_toggled (GtkToggleButton *radiobutton1,
gpointer user_data);
之后,我们就可以在callbacks.c文件写具体的处理代码。为了标识用户点击了选项按钮组中的哪一个选项按钮,在callbacks.c文件定义了一个gint类型的全局变量rb_idx,默认值为1,即选项按钮组中默认选中的选项按钮的索引号为1。当用户单击某个选项按钮后,将赋给该变量对应选项按钮的索引值。当用户点击radiobutton1按钮后,将触发信号“toggled”,对应该信号的回调函数代码如下:
void radiobutton1_toggled (GtkToggleButton *radiobutton1,
gpointer user_data)
{
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radiobutton1)))
{
rb_idx = 1;
}
}
该函数判断选项按钮radiobutton1是否处于选中状态,如是则将其索引值赋给全局变量。其余的四个选项按钮均要按以上过程在interfaces.c、callbacks.h和callbacks.c文件中添加相应的代码。
2.4 设置定时器
为了让提醒窗口在用户设定时间间隔后反复出现,需要使用相应的定时器函数,在GTK+2编程中,使用glib标准函数g_timeout_add()来实现定时的功能,该函数包括三个参数,第一个参数指定定时执行的间隔时间,以秒为单位,第二个参数为定时器执行函数,第三个参数为执行函数的参数。执行函数返回值为gboolean即布尔类型,当其值为TRUE时,则反复执行,否则停止执行。本程序中的定时器执行函数为mytimer(),它接受一个参数,用于传递在弹出的提醒窗体中显示的内容,使用starttimer()函数来触发定时器函数。在callbacks.c中的代码如下。
gboolean mytimer(gpointer data)
{
gchar buf[15]={0};
gchar *body = (gchar *)data;
popup("定时提醒备忘录",body,3000);
return( TRUE );
}
void starttimer(gchar *body,gint timer) {
gint tid;
tid = g_timeout_add(timer,(mytimer),body);
}
2.5 为“设定”按钮编写相应代码
定时提醒程序的关键部分就是为“设定”按钮编写相应的代码,即针对“设定”按钮的单击事件编写相应的回调函数。该函数处理的流程为:检查用户设置的提醒信息是否为空,如不为空则根据用户设定的时间间隔调用定时器启动函数starttimer(),当用户选择自定义时间间隔时,则获取输入的时间信息并对其进行分析后调用定时器启动函数starttimer()。
定时提醒设置窗体上有两个文本输入构件,在按钮“设定”的“clicked”信号处理函数(回调函数)中需要对这两个构件的内容进行处理,但连接信号与回调函数的函数g_signal_connect()只能给回调函数传递一个用户自定义参数,怎么办?这里我们使用自定义的结构体变量来返回多个构件的值。在callbacks.h头文件中定义一个结构体类型EntryData:
typedef struct _EntryData{
GtkWidget *e1;
GtkWidget *e2;
}EntryData;
在interfaces.c中添加如下代码:
EntryData *ped;
ped = g_malloc0(sizeof(EntryData));
以上语句定义一个指向结构体变量的指针,并为结构体变量分配相应的存储空间且置零。然后在文本输入构件Entry1和Entry2的新建函数(gtk_entry_new)之后,将两个构件的指针分别赋给ped的成员变量,并将ped作为“设定”按钮(button1)的回调函数的参数。
在callbacks.c中的button1的回调函数代码如下:
void on_button1_clicked (GtkButton *button,
gpointer user_data)
{
const gchar *mytime;
const gchar *body;
EntryData *ped2 = ( EntryData * )user_data;
guint i_time = 5000;
/*get information from entry 2*/
body = gtk_entry_get_text(GTK_ENTRY( ped2->e2 ));
if( body[0] ) printf("entry2:%s\n",body);
else printf("Notify Message is empty\n");
switch(rb_idx) {
case 1:
starttimer(body,90000);
break;
……(略)
case 5:
mytime = gtk_entry_get_text(GTK_ENTRY( ped2->e1 ));
if( mytime[0] ) {
i_time = parsetime(mytime);
starttimer(body,i_time);
}
else printf("my time is empty\n");
break;
}
}
其中当用户选择自行设定时间时,由parsetime()将设定的时间转换为以毫秒为单位的定时器的间隔时间。Starttimer()函数启动定时器函数并在设定的时间用完后调用popup()函数来弹出提醒窗体,显示相应的提醒信息给用户。
3、 测试定时提醒备忘录程序
因Glade2自动生成项目的目录及部分源代码文件,利用其提供的自动化脚本生成相应的配置脚本及编译脚本。打开一个X终端窗口,进到项目所在目录,输入命令:./autogen.sh,这将生成系统检测配置脚本configure,输入命令:./configure,如系统检查通过,将生成项目的编译脚本文件Makefile,然后输入命令:make,对当前项目的源程序进行编译(也可直接进入src目录执行make命令进行编译),编译成功后将在src目录下生成一个二进制可执行文件(在X终端中以绿色显示),输入命令:src/timer1运行该程序。程序运行界面如图2所示。在“设置提示信息”输入框中输入需定时提醒的信息,点击“设定”按钮,则过90秒钟后,在GNOME集成桌面环境的系统托盘区将出现通知窗体。以后每隔一段时间提醒一次,有了这个小工具,在Linux平台上工作的朋友再也不用担心“忘事”了。
编程小结
1、 在Linux平台上可以利用Glade2高效、快速地设计和开发GTK+2应用程序。
2、 为了更方便地运行定时提醒程序,可考虑将其放置到GNOME桌面的系统托盘区运行。
3、 为了增强提醒的效果,可以考虑增加声音提醒的功能。
4、 本程序只能设置一条提醒信息,感兴趣的读者可在此基础上增加设置多条信息的功能,以进一步完善该程序。
|
|
文章检索
编程>热门文章
|