GTK+20杂项构件2.docx
《GTK+20杂项构件2.docx》由会员分享,可在线阅读,更多相关《GTK+20杂项构件2.docx(24页珍藏版)》请在冰豆网上搜索。
GTK+20杂项构件2
GTK+2.0-----杂项构件
(2)
GTK+2.02008-12-1312:
51:
20阅读386评论0 字号:
大中小 订阅
组合框GtkCombo
GtkCombo(组合框)是极为常见的构件,实际上它仅仅是其他构件的集合。
从用户的观点来说,这个构件是由一个文本输入构件和一个下拉菜单组成的,用户可以从一个预先定义的列表里面选择一个选项,同时,用户也可以直接在文本框里面输入文本。
下面是从定义组合框构件的结构里面摘取出来的,从中可以看到组合框构件是由什么构件组合形成的:
struct_GtkCombo
GtkHBoxhbox;
GtkWidget*entry;
GtkWidget*button;
GtkWidget*popup;
GtkWidget*popwin;
GtkWidget*list;
...};
可以看到,组合框构件有两个主要部分:
一个输入框和一个列表。
用下面的函数创建组合框构件:
GtkWidget*gtk_combo_new(void);
现在,如果想设置显示在输入框部分中的字符串,可以直接操纵组合框构件内部的文本输入构件:
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry),"MyString.");
要设置下拉列表中的值,可以使用下面的函数:
voidgtk_combo_set_popdown_strings(GtkCombo*combo,
GList*strings);
在使用这个函数之前,先得将要添加的字符串组合成一个GList链表。
Glist是一个双向链表,是Glib的一部分。
要做的就是设置一个Glist指针,其值设为NULL,然后用下面的函数将字符串追加到链表当中:
GList*g_list_append(GList*glist,
gpointerdata);
要注意的是:
一定要将Glist链表的初值设为NULL,必须将g_list_append函数返回的值赋给要操作的链表本身。
下面是一段典型的代码,用于创建一个选项列表:
GList*glist=NULL;
glist=g_list_append(glist,"String1");
glist=g_list_append(glist,"String2");
glist=g_list_append(glist,"String3");
glist=g_list_append(glist,"String4");
gtk_combo_set_popdown_strings(GTK_COMBO(combo),glist);
到这里为止,你现在已经可以使用设置的组合框构件了。
有几个行为是可以改变的。
下面是相关的函数:
voidgtk_combo_set_use_arrows(GtkCombo*combo,gintval);
voidgtk_combo_set_use_arrows_always(GtkCombo*combo,gintval);
voidgtk_combo_set_case_sensitive(GtkCombo*combo,gintval);
gtk_combo_set_use_arrows()让用户用上/下方向键改变文本输入构件内的值。
这并没有改变列表的值,只是用列表中的下一个列表项替换了文本输入框中的文本(向上则取上一个值,向下则取下一个值)。
这是通过搜索当前项在列表中的位置并选择前一项/下一项来实现的。
通常,在一个输入框中方向键是用来改变焦点的(也可以用TAB键)。
注意,如果当前项是列表的最后一项,按向下的方向键会改变焦点的位置(这对列表在第一项时按向上方向键也适用)。
如果当前值并不在列表中,则不能使用gtk_combo_set_use_arrows()函数。
同样地,gtk_combo_set_use_arrows_always()允许使用上/下方向键在下拉列表中选取列表项,但是它在列表项中循环,也就是当列表项位于第一个表项时按向上方向键,会跳到最后一个,当列表项位于最后一个表项时按向下方向键,会跳到第一个。
这样可以完全禁止使用方向键改变焦点。
gtk_combo_set_case_sensitive()函数切换GTK是否以大小写敏感的方式搜索其中的列表项。
这一般用在内部文本输入构件中的文本查找组合框构件中的列表值。
可以将其设置为大小写敏感或不敏感。
如果用户同时按下“Alt”和“Tab”键,组合框构件还可以用来完成当前输入。
注意,窗口管理器也要使用这种组合键方式,将会忽略GTK中这个组合键的使用。
注意,我们使用的是组合框构件,它能够为我们从一个下拉列表中选择一个选项。
这一点是很直截了当的。
大多数时候,你可能很关心怎样从其中的文本输入构件中获取数据。
组合框构件内部的文本输入构件可以用GTK_ENTRY(GTK_COMBO(combo)->entry)访问。
一般想要做的两件主要工作一个是连接一个activate,当用户按回车键时能够进行响应,另一个就是读出其中的文本。
第一件工作可以用下面的方法实现:
gtk_signal_connect(GTK_OBJECT(GTK_COMB(combo)->entry),"activate",GTK_SIGNAL_FUNCmy_callback_function),my_data);
可以使用下面的函数在任意时候取得文本输入构件中的文本:
gchar*gtk_entry_get_text(GtkEntry*entry);
具体做法如下:
char*string;
string=gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry));
这就是取得文本输入框中字符串的方法。
voidgtk_combo_disable_activate(GtkCombo*combo);
这个函数禁用组合框构件内部的文本输入构件(GtkEntry)的activate信号。
日历构件GtkCalendar
GtkCalendar(日历构件)显示一个月历视图,可以在上面方便地选择年份、月份和日期。
这样,如果要做与日期相关的编程,不再需要考虑复杂的历法问题。
日历构件本身外观也很漂亮,创建和使用都非常简单。
同时,日历构件GtkCalendar不存在2000年问题。
如果要开发一个日程管理等类的软件,这个构件是一个很好的选择。
创建日历构件的方法和其他构件的类似:
GtkWidget*gtk_calendar_new();
有时候,需要同时对构件的外观和内容做很多的修改。
这时候可能会引起构件的多次更新,导致屏幕闪烁。
可以在修改之前使用一个函数将构件“冻结”,然后在修改完成之后再用一个函数将构件“解冻”。
这样,构件在整个过程中只做一次更新。
这个函数将构件“冻结”:
voidgtk_calendar_freeze(GtkCalendar*Calendar);
这个函数将构件“解冻”:
voidgtk_calendar_thaw(GtkCalendar*Calendar);
这两个函数和其他构件(比如GtkText)的冻结/解冻函数作用完全一样。
日历构件有几个选项,可以用来改变构件的外观和操作方式。
使用下面的函数可以改变这些选项:
voidgtk_calendar_display_options(GtkCalendar*calendar,GtkCalendarDisplayOptionsflags);
函数中的flags参数可以将下面的五种选项中的一个或者多个用逻辑位或(|)操作符组合起来:
GTK_CALENDAR_SHOW_HEADING:
这个选项指定在绘制日历构件时,应该显示月份和年份。
GTK_CALENDAR_SHOW_DAY_NAMES:
这个选项指定用三个字母的缩写显示每一天是星期几(比如MON、TUE等)。
GTK_CALENDAR_NO_MONTH_CHANGE:
这个选项指定用户不应该也不能够改变显示的月份。
如果只想显示某个特定的月份,则可以使用这个选项。
比如,如果在窗口上同时为一年的12个月分别设置一个日历构件时。
GTK_CALENDAR_SHOW_WEEK_NUMBERS:
这个选项指定应该在构件的左边显示每一周在全年的周序号(一年是52个周,元月1日是第1周,12月31日是第52周)。
GTK_CALENDAR_WEEK_START_MONDAY:
这个选项指定在日历构件中每一周是从星期一开始而不是从星期天开始。
缺省设置是从星期天开始。
此选项只影响日期在构件中从左到右的排列顺序。
下面的函数用于设置当前要显示的日期:
gintgtk_calendar_select_month(GtkCalendar*calendar,guintmonth,guintyear);
voidgtk_calendar_select_day(GtkCalendar*calendar,guintday);
gtk_calendar_select_month()的返回值是一个布尔值,指示设置是否成功。
如果设置一个非法值,比如31月,则会返回一个FALSE值。
使用gtk_calendar_select_day()函数,如果day参数指定的日期是合法的,会在日历构件中选中该日期。
如果day参数的值是0,将清除当前的选择。
除了可以选中一个日期以外,在一个月中可以有任意个日期被“标记”。
被“标记”的日期会在日历构件中高亮显示。
下面的函数用于标记日期和取消标记:
gintgtk_calendar_mark_day(GtkCalendar*calendar,guintday);
gintgtk_calendar_unmark_day(GtkCalendar*calendar,guintday);
voidgtk_calendar_clear_marks(GtkCalendar*calendar);
当前标记的日期存储在一个GtkCalendar结构的数组中。
数组的长度是31,这样,要想知道某个特定的日期是否被标记,可以访问数值中相应的元素(注意,在C语言中,数值是从0开始编号的)。
例如:
GtkCalendar*calendar;
calendar=gtk_calendar_new();
...
/*当月7日被标记了吗?
*/
if(calendar->marked_date[7-1])
/*若执行此处的代码,表明7日已经被标记*/
注意,在月份和年份变化时,被标记的日期是不会变化的。
下面的函数用于取得当前选中的年/月/日值:
voidgtk_calendar_get_date(GtkCalendar*calendar,
guint*year,
guint*month,
guint*day);
使用这个函数时,需要先声明几个guint类型的变量—传递给函数的year、month和day参数。
所需要的返回值就存放在这几个变量中。
如果将某一个参数设置为NULL,则不返回该值。
日历构件能够引发许多信号,用于指示日期被选中以及选择发生的变化。
信号的意义很容易理解。
信号名称如下:
month_changed选/择*月份变化*/
day_selected选/择*日期变化*/
day_selected_double_click选中/*日期并以鼠标双击*/
prev_month选/择*前一月*/
next_month选/择*下一月*/
prev_year选/择*前一年*/
next_year选/择*下一年*/
下面是一个日历构件的示例,运用了上面介绍的各项特性。
/*日历构件示例开始calendar.c*/
#include
#include
#include
#include
#defineDEF_PAD10
#defineDEF_PAD_SMALL5
#defineTM_YEAR_BASE1900
typedefstruct_CalendarData{
GtkWidget*flag_checkboxes[5];
gbooleansettings[5];
gchar*font;
GtkWidget*font_dialog;
GtkWidget*window;
GtkWidget*prev2_sig;
GtkWidget*prev_sig;
GtkWidget*last_sig;
GtkWidget*month;
}CalendarData;
enum{
calendar_show_header,
calendar_show_days,
calendar_month_change,
calendar_show_week,
calendar_monday_first
};
/*
*GtkCalendar日历构件
*/
voidcalendar_date_to_string(CalendarData*data,
char*buffer,
gintbuff_len)
{
structtmtm;
time_ttime;
memset(&tm,0,sizeof(tm));
gtk_calendar_get_date(GTK_CALENDAR(data->window),
&tm.tm_year,&tm.tm_mon,&tm.tm_mday);
tm.tm_year-=TM_YEAR_BASE;
time=mktime(&tm);
strftime(buffer,buff_len-1,"%x",gmtime(&time));
}
voidcalendar_set_signal_strings(char*sig_str,
CalendarData*data)
{
gchar*prev_sig;
gtk_label_get(GTK_LABEL(data->prev_sig),&prev_sig);
gtk_label_set(GTK_LABEL(data->prev2_sig),prev_sig);
gtk_label_get(GTK_LABEL(data->last_sig),&prev_sig);
gtk_label_set(GTK_LABEL(data->prev_sig),prev_sig);
gtk_label_set(GTK_LABEL(data->last_sig),sig_str);
}
voidcalendar_month_changed(GtkWidget*widget,
CalendarData*data)
{
charbuffer[256]="month_changed:
";
calendar_date_to_string(data,buffer+15,256-15);
calendar_set_signal_strings(buffer,data);
}
voidcalendar_day_selected(GtkWidget*widget,
CalendarData*data)
{
charbuffer[256]="day_selected:
";
calendar_date_to_string(data,buffer+14,256-14);
calendar_set_signal_strings(buffer,data);
}
voidcalendar_day_selected_double_click(GtkWidget*widget,
CalendarData*data)
{
structtmtm;
charbuffer[256]="day_selected_double_click:
";
calendar_date_to_string(data,buffer+27,256-27);
calendar_set_signal_strings(buffer,data);
memset(&tm,0,sizeof(tm));
gtk_calendar_get_date(GTK_CALENDAR(data->window),
&tm.tm_year,&tm.tm_mon,&tm.tm_mday);
tm.tm_year-=TM_YEAR_BASE;
if(GTK_CALENDAR(data->window)->marked_date[tm.tm_mday-1]==0){
gtk_calendar_mark_day(GTK_CALENDAR(data->window),tm.tm_mday);
}else
gtk_calendar_unmark_day(GTK_CALENDAR(data->window),tm.tm_mday);
}
}
voidcalendar_prev_month(GtkWidget*widget,
CalendarData*data)
{
charbuffer[256]="prev_month:
";
calendar_date_to_string(data,buffer+12,256-12);
calendar_set_signal_strings(buffer,data);
}
voidcalendar_next_month(GtkWidget*widget,
CalendarData*data)
{
charbuffer[256]="next_month:
";
calendar_date_to_string(data,buffer+12,256-12);
calendar_set_signal_strings(buffer,data);
}
voidcalendar_prev_year(GtkWidget*widget,
CalendarData*data)
{
charbuffer[256]="prev_year:
";
calendar_date_to_string(data,buffer+11,256-11);
calendar_set_signal_strings(buffer,data);
}
voidcalendar_next_year(GtkWidget*widget,
CalendarData*data)
{
charbuffer[256]="next_year:
";
calendar_date_to_string(data,buffer+11,256-11);
calendar_set_signal_strings(buffer,data);
}
voidcalendar_set_flags(CalendarData*calendar)
{
ginti;
gintoptions=0;
for(i=0;i<5;i++)
if(calendar->settings[i])
{
options=options+(1<
}
if(calendar->window)
gtk_calendar_display_options(GTK_CALENDAR(calendar->window),options);
}
voidcalendar_toggle_flag(GtkWidget*toggle,
CalendarData*calendar)
{
ginti;
gintj;
j=0;
for(i=0;i<5;i++)
if(calendar->flag_checkboxes[i]==toggle)
j=i;
calendar->settings[j]=!
calendar->settings[j];
calendar_set_flags(calendar);
}
voidcalendar_font_selection_ok(GtkWidget*button,
CalendarData*calendar)
{
GtkStyle*style;
GdkFont*font;
calendar->font=gtk_font_selection_dialog_get_font_name(
GTK_FONT_SELECTION_DIALOG(calendar->font_dialog));
if(calendar->window)
{
font=gtk_font_selection_dialog_get_font(GTK_FONT_SELECTION_DIALOG(calendar-
>font_dialog));
if(font)
{
style=gtk_style_copy(gtk_widget_get_style(calendar