注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

一滴瀑布

祝愿父母和兄弟姐妹身体健康,快乐幸福,直到永远!

 
 
 

日志

 
 
关于我

愿赌服输! ——Ilana

网易考拉推荐

【引用】GTK+2.0-----杂项构件(1)  

2011-10-14 15:42:27|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |


标签构件GtkLabel
G t k L a b e l (标签构件)是G T K中最常用的构件,实际上它很简单。因为没有相关联的X窗口,标签构件不能引发信号。如果需要引发信号,可以将它放在一个事件盒构件中,或放在按钮构件里面。
用以下函数创建新标签构件:
GtkWidget *gtk_label_new(char *str );
唯一的参数是要由标签显示的字符串。
创建标签构件后,要改变标签内的文本,用以下函数:
void gtk_label_set_text( GtkLabel *lacbel,char *str );
第一参数是前面创建的标签构件(用G T K _ L A B E L ( )宏转换),并且第二个参数是新字符串。
如果需要,新字符串需要的空间会做自动调整。在字符串中放置换行符,可以创建多行标签。
用以下函数取得标签的当前文本:
void gtk_label_get( GtkLabel *Label,char **str );
第一个参数是前面创建的标签构件,并且第二个参数是要返回的字符串。不要释放返回的字符串,因为G T K内部要使用它。
标签的文本可以用以下函数设置对齐方式:
void gtk_label_set_justify( GtkLabel *Label,GtkJustification jtype );
j t y p e的值可以是:
GTK_JUSTIFY_LEFT 左对齐
GTK_JUSTIFY_RIGHT 右对齐
GTK_JUSTIFY_CENTER 居中对齐(默认)
GTK_JUSTIFY_FILL 充满
标签构件的文本会自动换行。用以下函数激活“自动换行”:
void gtk_label_set_line_wrap (GtkLabel *Label, gboolean wrap);
w r a p参数可取T R U E或FA L S E,对应于自动换行和不自动换行。
如果想要使标签构件加下划线,可以在标签构件中设置显示模式:
void gtk_label_set_pattern (GtkLabel *Label,const gchar *pattern);
p a t t e r n参数指定下划线的外观。它由一串下划线和空格组成。下划线指示标签的相应字符应该加一个下划线。例如, “— —”将在标签的第1、第2个字符和第8、第9个字符加下划线。
下面是一个说明这些函数的短例子。这个例子用框架构件能更好地示范标签的风格。
/* GtkLabel示例开始label.c */
#include <gtk/gtk.h>
int main( int argc,
char *argv[] )
{
static GtkWidget *window = NULL;
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *frame;
GtkWidget *label;
/* 初始化GTK */
gtk_init(&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
G T K _ S I G N A L _ F U N C ( g t k _ m a i n _ q u i t ) ,
N U L L ) ;
gtk_window_set_title (GTK_WINDOW (window), "Label");
vbox = gtk_vbox_new (FALSE, 5);
hbox = gtk_hbox_new (FALSE, 5);
gtk_container_add (GTK_CONTAINER (window), hbox);
gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (window), 5);
frame = gtk_frame_new ("Normal Label");
label = gtk_label_new ("This is a Normal label");
gtk_container_add (GTK_CONTAINER (frame), label);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
frame = gtk_frame_new ("Multi-line Label");
label = gtk_label_new ("This is a Multi-line label.\nSecond line\nThird line");
gtk_container_add (GTK_CONTAINER (frame), label);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
frame = gtk_frame_new ("Left Justified Label");
label = gtk_label_new ("This is a Left-Justified\n" \
"Multi-line label.\nThird line");
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
gtk_container_add (GTK_CONTAINER (frame), label);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
frame = gtk_frame_new ("Right Justified Label");
label = gtk_label_new ("This is a Right-Justified\nMulti-line label.\n" \
"Fourth line, (j/k)");
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
gtk_container_add (GTK_CONTAINER (frame), label);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
vbox = gtk_vbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
frame = gtk_frame_new ("Line wrapped label");
label = gtk_label_new ("This is an example of a line-wrapped label. It " \
"should not be taking up the entire "
/* 一大段空格,用来测试间距* / \
"width allocated to it, but automatically " \
"wraps the words to fit. " \
"The time has come, for all good men, to come to " \
"the aid of their party. " \
"The sixth shei’ks six shee’p s sick.\n" \
" It supports multiple paragraphs correctly, " \
"and correctly adds "\
"many extra spaces. ");
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_container_add (GTK_CONTAINER (frame), label);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
frame = gtk_frame_new ("Filled, wrapped label");
label = gtk_label_new ("This is an example of a line-wrapped, filled label
" \
"It should be taking "\
"up the entire width allocated to it. "
\
"Here is a sentence to prove "\
"my point. Here is another sentence. "\
"Here comes the sun, do de do de do.\n"\
" This is a new paragraph.\n"\
" This is another newer, longer, better " \
"paragraph. It is coming to an end, "\
" u n f o r t u n a t e l y . " ) ;
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_FILL);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_container_add (GTK_CONTAINER (frame), label);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
frame = gtk_frame_new ("Underlined label");
label = gtk_label_new ("This label is underlined!\n"
"This one is underlined in quite a funky fashion");
gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
gtk_label_set_pattern (GTK_LABEL (label),
"_________________________ _ _________ _ \
______ __ _______ ___");
gtk_container_add (GTK_CONTAINER (frame), label);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show_all (window);
gtk_main ();
r e t u r n ( 0 ) ;
}
/* 示例结束* /
图9 - 1是上面代码的运行结果。这个例子展示了G t k L a b e l构件的各种属性。

GTK+2.0-----杂项构件(1) - 垒 - jiangbowen1_qd的博客
图9-1 标签构件


箭头构件GtkArrow
G t k A r r o w (箭头构件)画一个箭头,面向几种不同的方向,并有几种不同的风格。在许多应用程序中,常用于创建带箭头的按钮。和标签构件一样,它不能引发信号。
只有两个函数用来操纵箭头构件:
GtkWidget *gtk_arrow_new( GtkArrowType arrow_type,GtkShadowType shadow_type );
void gtk_arrow_set( GtkArrow *arrow, GtkArrowType arrow_type,GtkShadowType shadow_type );
第一个函数创建新的箭头构件,指明构件的类型和外观;第二个函数用来改变箭头构件类型和外观。
a r r o w _ t y p e参数指示箭头指向哪个方向,可以取下列值:
GTK_ARROW_UP 向上
GTK_ARROW_DOWN 向下
GTK_ARROW_LEFT 向左
G T K _ A R R O W _ R I G H T 向右
s h a d o w _ t y p e参数指明箭头的投影的类型,可以取下列值:
GTK_SHADOW_IN
GTK_SHADOW_OUT (缺省值)
GTK_SHADOW_ETCHED_IN
G T K _ S H A D O W _ E T C H E D _ O U T
下面是说明这些类型和外观的例子。
/* GtkArrow示例arrow.c */
#include <gtk/gtk.h>
/* 用指定的参数创建一个箭头构件并将它组装到按钮中* /
GtkWidget *create_arrow_button( GtkArrowType arrow_type,GtkShadowType shadow_type )
{
GtkWidget *button;
GtkWidget *arrow;
button = gtk_button_new();
arrow = gtk_arrow_new (arrow_type, shadow_type);
gtk_container_add (GTK_CONTAINER (button), arrow);
g t k _ w i d g e t _ s h o w ( b u t t o n ) ;
g t k _ w i d g e t _ s h o w ( a r r o w ) ;
r e t u r n ( b u t t o n ) ;
}
int main( int argc,
char *argv[] )
{
/* 构件的存储类型是GtkWidget */
GtkWidget *window;
GtkWidget *button;
GtkWidget *box;
/* 初始化Gtk */
gtk_init (&argc, &argv);
/* 创建一个新窗口* /
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Arrow Buttons");
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
/* 设置窗口的边框的宽度* /
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* 创建一个组装盒以容纳箭头/按钮* /
box = gtk_hbox_new (FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (box), 2);
gtk_container_add (GTK_CONTAINER (window), box);
/* 组装、显示所有的构件* /
g t k _ w i d g e t _ s h o w ( b o x ) ;
button = create_arrow_button(GTK_ARROW_UP, GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 3);
button = create_arrow_button(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 3);
button = create_arrow_button(GTK_ARROW_LEFT, GTK_SHADOW_ETCHED_IN);
gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 3);
button = create_arrow_button(GTK_ARROW_RIGHT, GTK_SHADOW_ETCHED_OUT);
gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 3);
gtk_widget_show (window);
/* 进入主循环,等待用户的动作* /
gtk_main ();
r e t u r n ( 0 ) ;
}
/* 示例结束* /
上面代码的运行效果见图9 - 2。在窗口上创建了四个带箭头的按钮。


工具提示对象GtkTooltips
工具提示对象( G t k To o l t i p s)就是当鼠标指针移到按钮或其他构件上并停留几秒时,弹出的文本串。工具提示对象很容易使用,所以在此仅仅对它们进行解释,不再举例。本书的其他示例里面有很多都用到了工具提示对象。不接收事件的构件(没有自己的X窗口的构件)不能和工具提示对象一起工作。
可以使用g t k _ t o o l t i p s _ n e w ( )函数创建工具提示对象。因为G t k To o l t i p s对象可以重复使用,一般在应用程序中仅需要调用这个函数一次。
GtkTooltips *gtk_tooltips_new(void);
一旦已创建新的工具提示,并且希望在某个构件上应用它,可调用以下函数设置它:
void gtk_tooltips_set_tip( GtkTooltips *tooltip,
GtkWidget *widget,const gchar *tip_text,const gchar *tip_private );
第一个参数是已经创建的工具提示对象,其后第二个参数是希望弹出工具提示的构件,第三个参数是要弹出的文本。最后一个参数是作为标识符的文本串,当用G t k Ti p s Q u e r y实现上下文敏感的帮助时要引用该标识符。目前,你可以把它设置为N U L L .
下面有个短例子:
GtkTooltips *tooltips;
GtkWidget *button;

.
.
tooltips = gtk_tooltips_new ();
button = gtk_button_new_with_label ("button 1");
.
.
gtk_tooltips_set_tip (tooltips, button, "This is button 1", NULL);

GTK+2.0-----杂项构件(1) - 垒 - jiangbowen1_qd的博客
图9-2 GtkArrow构件


还有其他与工具提示有关的函数,下面仅仅列出一些函数的简要描述。
void gtk_tooltips_enable( GtkTooltips *tooltip);
激活已经禁用的工具提示对象。
void gtk_tooltips_disable( GtkTooltips *tooltip);
禁用已经激活的工具提示对象。
void gtk_tooltips_set_delay( GtkTooltips *tooltip, gint delay);
设置鼠标在构件上停留多少毫秒后弹出工具提示,默认是5 0 0毫秒(半秒)。
void gtk_tooltips_set_colors( GtkTooltips *tooltips,
GdkColor *background,
GdkColor *foreground );
设置工具提示的前景色和背景色。
上面是所有与工具提示有关的函数,实际上比你想要知道的还多。


进度条构件GtkProgressBar
进度条用于显示正在进行的操作的状态。它相当容易使用,在下面的代码中可以看到。下面的内容从创建一个新进度条开始。
有两种方法创建进度条,简单的方法不需要参数,另一种方法用一个调整对象作为参数。如果前者使用,进度条创建它拥有的调整对象。
GtkWidget *gtk_progress_bar_new(void);
GtkWidget *gtk_progress_bar_new_with_adjustment( GtkAdjustment *adjustment);
第二种方法的优势是我们能用调整对象明确指定进度条的范围参数。
进度条的调整对象能用下面的函数动态改变:
void gtk_progress_set_adjustment( GtkProgress *progress,GtkAdjustment *adjustment);
既然进度条已经创建,那就可以使用它了。
void gtk_progress_bar_update( GtkProgressBar *pbar, gfloat percentage);
更新进度条时,第一个参数是希望操作的进度条,第二个参数是“已完成”的百分比,意思是进度条从0~1 0 0 %已经填充的数量。它以0~1范围的实数传递给函数。
GTK 1.2版已经给进度条添加了一个新的功能,那就是允许它以不同的方法显示其值,并通知用户它的当前值和范围。
进度条可以用以下函数设置它的移动方向:
void gtk_progress_bar_set_orientation( GtkProgressBar *pbar,GtkProgressBarOrientation orientation);
o r i e n t a t i o n参数可以取下列值之一,以指示进度条的移动方向:
G T K _ P R O G R E S S _ L E F T _ TO _ R I G H T 从左向右
G T K _ P R O G R E S S _ R I G H T _ TO _ L E F T 从右向左
G T K _ P R O G R E S S _ B O T TO M _ TO _ TOP 从下向上
G T K _ P R O G R E S S _ TO P _ TO _ B O T TO M 从上向下
进度条可以以连续和间断的方式显示进度处理的数值。在连续的方式下,进度条每个值都会更新;在间断方式下,进度条以不连续的方式更新。更新的次数是可配置的。
进度条的式样可以用以下函数进行更新:
void gtk_progress_bar_set_bar_style( GtkProgressBar *pbar,GtkProgressBarStyle style);
s t y l e参数取以下两种值:
GTK_PROGRESS_CONTINUOUS 连续更新
G T K _ P R O G R E S S _ D I S C R E T E 间断更新
间断更新的次数可以用以下函数设置:
gtk_progress_bar_set_discrete_blocks( GtkProgressBar *pbar,guint blocks);
除了指示进度已经发生的数量以外,进度条还可以设置为仅仅指示有活动在继续。这些设置在进度无法按数值度量的情况下很有用。进度条的活动模式不会受进度条的s t y l e参数的影响,并且会覆盖它的设置。其方式只能是T R U E或者FA L S E,可以用下列函数确定:
void gtk_progress_set_activity_mode( GtkProgress *progress,guint activity_mode );
活动指示的步数和活动的块数由以下函数设置:
void gtk_progress_bar_set_activity_step( GtkProgressBar *pbar, guint step);
void gtk_progress_bar_set_activity_blocks( GtkProgressBar *pbar, guint b l o c k s ) ;
在连续的方式下,进度条可以用下列函数在滑槽内显示一个可配置的文本串:
void gtk_progress_set_format_string( GtkProgress *progress, gchar *format);
其中,f o r m a t参数与C语言中的p r i n t f函数的格式参数相似。
下列格式可以用于格式化串:
%p 百分比
%v 值
% l 低范围值
%u 高限范围值
是否显示文本串可以用以下函数开/关:
void gtk_progress_set_show_text( GtkProgress *progress, gint show_text );
s h o w _ t e x t参数是布尔型的,可取值为T R U E / FA L S E。
文本的外观能做进一步的修改,如下所示:
void gtk_progress_set_text_alignment( GtkProgress *progress,gfloat x_align, gfloat y_align );
x _ a l i g n和y _ a l i g n参数取0 . 0和1 . 0之间的值。这些值指定文本串在滑槽内的位置。两个值都取为0 . 0将把文本串放在左上角;取值0 . 5 (默认)让文本居于滑槽中心;设为1 . 0则将文本串置于右下角。
进度条对象的当前文本设置能由下列两个函数从当前文本或从指定的调整对象中取得。
这些函数返回的字符串应该由应用程序释放(用g _ f r e e ( )函数)。这些函数返回要显示在滑槽内的格式化字符串。
gchar *gtk_progress_get_current_text( GtkProgress *progress );
gchar *gtk_progress_get_text_from_value( GtkProgress *progress, gfloat value );
还有另一种改变进度条对象的范围和取值的方法。使用下列函数:
void gtk_progress_configure( GtkProgress *progress, gfloat value, gfloat min,gfloat max);
这个函数提供了相当简单的使用进度条对象的范围和取值的接口。
其余的函数可以以各种类型和格式获得或设置当前进度条对象的值:
void gtk_progress_set_percentage( GtkProgress *progress, gfloat percentage);
void gtk_progress_set_value( GtkProgress *progress, gfloat value);
gfloat gtk_progress_get_value( GtkProgress *progress);
gfloat gtk_progress_get_current_percentage( GtkProgress *progress);
gfloat gtk_progress_get_percentage_from_value( GtkProgress *progress,gfloat value);
这些函数从字面上就可以了解它的含义。最后一个函数使用指定进度条的调整对象计算给定范围值的百分比。
进度条通常和t i m e o u t或其他函数同时使用,使应用程序就像是多任务一样。一般都用同样的方式使用g t k _ p r o g r e s s _ b a r _ u p d a t e函数。
下面是一个进度条的例子,用t i m e o u t函数更新进度条的值。代码也演示了怎样复位进度条。
/* GtkProgressBa示r例progressbar.c */
#include <gtk/gtk.h>
typedef struct _ProgressData {
GtkWidget *window;
GtkWidget *pbar;
int timer;
} ProgressData;
/* 更新进度条,这样就能够看到进度条的移动* /
gint progress_timeout( gpointer data )
{
gfloat new_val;
GtkAdjustment *adj;
/* 使用在调整对象中设置的取值范围计算进度条的值* /
new_val = gtk_progress_get_value( GTK_PROGRESS(data) ) + 1;
adj = GTK_PROGRESS (data)->adjustment;
if (new_val > adj->upper)
new_val = adj->lower;
/* 设置进度条的新值* /
gtk_progress_set_value (GTK_PROGRESS (data), new_val);
/* 这是一个t i m e o u t函数,返回T R U E,这样它就能够继续调用* /
r e t u r n ( T R U E ) ;
}
/* 回调函数,切换在进度条内的滑槽上的文本显示* /
void toggle_show_text( GtkWidget *widget,ProgressData *pdata )
{
gtk_progress_set_show_text (GTK_PROGRESS (pdata->pbar),GTK_TOGGLE_BUTTON (widget)->active);
}
/* 回调函数,切换进度条的活动模式* /
void toggle_activity_mode( GtkWidget *widget,ProgressData *pdata )
{
gtk_progress_set_activity_mode (GTK_PROGRESS (pdata->pbar),GTK_TOGGLE_BUTTON (widget)->active);
}
/* 回调函数,切换进度条的连续模式* /
void set_continuous_mode( GtkWidget *widget,ProgressData *pdata )
{
gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),G T K _ P R O G R E S S _ C O N T I N U O U S ) ;
}
/* 回调函数,切换进度条的间断模式* /
void set_discrete_mode( GtkWidget *widget,ProgressData *pdata )
{
gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),G T K _ P R O G R E S S _ D I S C R E T E ) ;
}
/* 清除分配的内存,删除t i m e o u t函数* /
void destroy_progress( GtkWidget *widget,ProgressData *pdata)
{
gtk_timeout_remove (pdata->timer);
pdata->timer = 0;
pdata->window = NULL;
g _ f r e e ( p d a t a ) ;
g t k _ m a i n _ q u i t ( ) ;
}
int main( int argc,
char *argv[])
{
ProgressData *pdata;
GtkWidget *align;
GtkWidget *separator;
GtkWidget *table;
GtkAdjustment *adj;
GtkWidget *button;
GtkWidget *check;
GtkWidget *vbox;
gtk_init (&argc, &argv);
/* 为传递到回调函数中的数据分配内存* /
pdata = g_malloc( sizeof(ProgressData) );
pdata->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_policy (GTK_WINDOW (pdata->window), FALSE, FALSE, TRUE);
gtk_signal_connect (GTK_OBJECT (pdata->window), "destroy",GTK_SIGNAL_FUNC (destroy_progress),p d a t a ) ;
gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
vbox = gtk_vbox_new (FALSE, 5);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
gtk_container_add (GTK_CONTAINER (pdata->window), vbox);
g t k _ w i d g e t _ s h o w ( v b o x ) ;
/* 创建一个居中对齐的对象* /
align = gtk_alignment_new (0.5, 0.5, 0, 0);
gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 5);
g t k _ w i d g e t _ s h o w ( a l i g n ) ;
/* 创建一个调整对象,以保持进度条的范围值* /
adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, 150, 0, 0, 0);
/* 使用前面创建的调整对象创建一个进度条* /
pdata->pbar = gtk_progress_bar_new_with_adjustment (adj);
/* 设置能显示在进度条的滑槽内的字符串的格式
* %p - 百分比
* %v - 值
* %l - 底限范围值
* %u - 上限范围值* /
gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),"%v from [%l-%u] (=%p%%)");
gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
g t k _ w i d g e t _ s h o w ( p d a t a - > p b a r ) ;
/* 添加一个计时的回调函数,以更新进度条的值* /
pdata->timer = gtk_timeout_add (100, progress_timeout, pdata->pbar);
separator = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0);
g t k _ w i d g e t _ s h o w ( s e p a r a t o r ) ;
/* 行数、列数、同质性* /
table = gtk_table_new (2, 3, FALSE);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0);
g t k _ w i d g e t _ s h o w ( t a b l e ) ;
/* 添加一个检查按钮,以选择显示在滑槽内的文本* /
check = gtk_check_button_new_with_label ("Show text");
gtk_table_attach (GTK_TABLE (table), check, 0, 1, 0, 1,GTK_EXPAND | GTK_FILL, GTK_EXPAND | TK_FILL,5, 5);
gtk_signal_connect (GTK_OBJECT (check), "clicked",GTK_SIGNAL_FUNC (toggle_show_text),p d a t a ) ;
g t k _ w i d g e t _ s h o w ( c h e c k ) ;
/* 添加一个检查按钮,切换活动状态* /
check = gtk_check_button_new_with_label ("Activity mode");
gtk_table_attach (GTK_TABLE (table), check, 0, 1, 1, 2,GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
5, 5);
gtk_signal_connect (GTK_OBJECT (check), "clicked",GTK_SIGNAL_FUNC (toggle_activity_mode),p d a t a ) ;
g t k _ w i d g e t _ s h o w ( c h e c k ) ;
separator = gtk_vseparator_new ();
gtk_table_attach (GTK_TABLE (table), separator, 1, 2, 0, 2,GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
5, 5);
g t k _ w i d g e t _ s h o w ( s e p a r a t o r ) ;
/* 添加一个无线按钮,以选择连续选择模式* /
button = gtk_radio_button_new_with_label (NULL, "Continuous");
gtk_table_attach (GTK_TABLE (table), button, 2, 3, 0, 1,GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,5, 5);
gtk_signal_connect (GTK_OBJECT (button), "clicked",GTK_SIGNAL_FUNC (set_continuous_mode),p d a t a ) ;
gtk_widget_show (button);
/* 添加一个无线按钮,以选择间断模式* /
button = gtk_radio_button_new_with_label(gtk_radio_button_group (GTK_RADIO_BUTTON (button))," D i s c r e t e " ) ;
gtk_table_attach (GTK_TABLE (table), button, 2, 3, 1, 2,GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
5, 5);
gtk_signal_connect (GTK_OBJECT (button), "clicked",GTK_SIGNAL_FUNC (set_discrete_mode),p d a t a ) ;
gtk_widget_show (button);
separator = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0);
g t k _ w i d g e t _ s h o w ( s e p a r a t o r ) ;
/* 添加一个按钮,用来退出应用程序* /
button = gtk_button_new_with_label ("close");
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",(GtkSignalFunc) gtk_widget_destroy,GTK_OBJECT (pdata->window));
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
/* 将按钮设置为缺省的* /
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
/* 将按钮冻结为缺省按钮,只要按回车键
* 就相当于点击了这个按钮* /
gtk_widget_grab_default (button);
g t k _ w i d g e t _ s h o w ( b u t t o n ) ;
gtk_widget_show (pdata->window);
gtk_main ();
r e t u r n ( 0 ) ;
} /* 示例结束* /
将上面的代码保存为p r o g r e s s b a r. c,编译后的运行效果见图9 - 3。其中演示了进度条的不同更新方式,你还可以设置是否显示文本,以及是否处于获得模式。


对话框构件
对话构件非常简单,事实上它仅仅是一个预先组装了几个构件到里面的窗口。
对话框是如下定义的:
struct GtkDialog { GtkWindow window;GtkWidget *vbox; GtkWidget *action_area; };
从上面可以看到,对话框只是简单地创建一个窗口,并在顶部组装一个G t k V B o x,然后在G t k V B o x中组装一个分隔线,再加一个称为“活动区”的G t k H B o x .对话框构件可以用于弹出消息,或者其他类似的任务。它只有一个函数:
GtkWidget *gtk_dialog_new(void);
要创建对话框,可以使用如下所示的函数:
GtkWidget *window;
window = gtk_dialog_new ();
你还可以在活动区中组装一个按钮:
button = ...
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
button,TRUE,TRUE, 0);
gtk_widget_show (button);
还可以在v b o x里面组装一个标签构件,像下面那样:
label = gtk_label_new ("XXXXX");
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox),label,
TRUE,TRUE, 0);

gtk_widget_show (label);

GTK+2.0-----杂项构件(1) - 垒 - jiangbowen1_qd的博客

图9-3 进度条构件

作为一个例子,可以在对话框里面组装两个按钮:一个“确定”按钮和一个“取消”按钮,以便向用户提出疑问,或显示一个错误信息。然后可以把不同信号连接到每个按钮,对用户的选择进行响应。如果由对话框提供的垂直和水平组装盒的简单功能不能满足你的需要,可以简单地在组装盒中添加其他外观构件。例如,可以在其中添加一个表格构件。因为G t k D i a l o g 太简单,不能满足快速开发应用程序的要求,所以建议你使用G n o m e D i a l o g及其子构件。G n o m e D i a l o g将在后面文章中介绍。


pixmap
p i x m a p s是包含图像的数据结构。这些图像可以用于不同的地方,但是最常见的是X桌面的图标,或用作鼠标指针。仅有2种颜色的p i x m a p称为位图,另外有一些例程用于处理这种特殊情况。了解p i x m a p有助于了解X窗口系统如何工作。在X系统下,与用户交互的应用程序不一定要在同一台计算机上运行。不同的应用程序,称为“客户”同时与一个显示图像和处理键盘和鼠标的程序通讯。这个直接与用户交互的程序被称为“显示服务器”或“ X服务器”。既然通信可能发生在网络上,那么,与X服务器保持一些信息是非常重要的。例如p i x m a p,就是储存在X服务器的内存中的。这意味着一旦设置了p i x m a p的值,它们就不再需要通过网络传输,而是传送一个“在此处显示编号为X Y Z的p i x m a p”。即使你目前没有在X系统下使用G T K,使用像p i x m a p这样的结构也会使应用程序在X下工作得更好。p i x m a p能从内存中的数据创建,或者用从文件中读出的数据创建。这里我们将介绍每种创建p i x m a p的方法。
GdkPixmap *gdk_bitmap_create_from_data( GdkWindow *window,gchar *data, gint width, gint height );
这个函数使用从内存读取的数据创建单个位平面的pixmap (2种颜色)。数据的每位分别代表像素是打开或关闭。宽和高是以像素度量的。G d k Wi n d o w指针指向当前窗口,因为p i x m a p的资源指的是它要显示的屏幕的场合。
GdkPixmap *gdk_pixmap_create_from_data( GdkWindow *window,
gchar *data,
gint width,
gint height,
gint depth,
GdkColor *fg,
GdkColor *bg );
这个函数用于从指定的位图数据创建给定深度(颜色数)的p i x m a p图片。f g和b g是要用到的前景和背景色。
GdkPixmap *gdk_pixmap_create_from_xpm_d( GdkWindow *window,
GdkBitmap **mask,
GdkColor *transparent_color,
gchar **data );
X P M格式是X窗口系统中一种可读的p i x m a p图形表示,它得到了广泛的应用。有许多实用程序可以用来创建这种格式的图片。由f i l e n a m e参数指定的文件必须包含X P M格式的图形,这种图形会被加载到p i x m a p结构中。M a s k参数指定在一个p i x m a p中哪一位是不透明的。所有的其他位都使用由t r a n s p a r e n t _ c o l o r所指定的颜色着色。下面是一个例子:
GdkPixmap *gdk_pixmap_create_from_xpm_d( GdkWindow *window,
GdkBitmap **mask,
GdkColor *transparent_color,
gchar **data );
小图像能以X P M格式合并到程序里面,一个p i x m a p格式的图片能够用这些数据创建,而不是从文件中读进来。下面是这种数据的例子。
/* XPM */
static const char * xpm_data[] = {
"16 16 3 1",
" c None",
". c #000000000000",
"X c #FFFFFFFFFFFF",
" ",
" ...... ",
" .XXX.X. ",
" .XXX.XX. ",
" .XXX.XXX. ",
" .XXX..... ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" ......... ",
" ",
" "};
当已经用完p i x m a p,并且不太可能再次使用它时,最好用g d k _ p i x m a p _ u n r e f ( )函数将这些资源释放。p i x m a p应该被看作是宝贵的资源,因为它们占据了终端用户的X服务器进程的内存。即使开发应用程序时所用的计算机是一台功能强劲的“服务器”,最终用户使用的却可能是速度较慢的P C,因而释放不再使用的资源是一件很重要的工作。
一旦我们创建了p i x m a p,就能将它作为G t k构件显示。我们必须创建一个G t k P i x m a p构件以包含GDK pixmap图片。用下面的函数实现:
GtkWidget *gtk_pixmap_new( GdkPixmap *pixmap, GdkBitmap *mask );
其他的相关函数是:
guint gtk_pixmap_get_type(void);
void gtk_pixmap_set( GtkPixmap *pixmap, GdkPixmap *val, GdkBitmap *mask);
void gtk_pixmap_get( GtkPixmap *pixmap, GdkPixmap **val, GdkBitmap **mask);
g t k _ p i x m a p _ s e t函数一般用于正在管理的构件的p i x m a p图片。v a l是用G D K创建的p i x m a p图片。
下面的例子是在一个按钮上使用p i x m a p图片。
/* pixmap示例开始pixmap.c */
#include <gtk/gtk.h>
/* XPM 数据,用于"打开文件"图标* /
static const char * xpm_data[] = {
"16 16 3 1",
" c None",
". c #000000000000",
"X c #FFFFFFFFFFFF",
" ",
" ...... ",
" .XXX.X. ",
" .XXX.XX. ",
" .XXX.XXX. ",
" .XXX..... ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" ......... ",
" ",
" "};
/* 调用这个函数时(通过d e l e t e _ e v e n t信号),终止应用程序* /
void close_application( GtkWidget *widget, GdkEvent *event, gpointer data ) {
g t k _ m a i n _ q u i t ( ) ;
}
/ *点击按钮时调用这个函数,并打印一条信息* /
void button_clicked( GtkWidget *widget, gpointer data ) {
printf( "button clicked\n" );
}
int main( int argc, char *argv[] )
{
/* 构件的存储格式是GtkWidget */
GtkWidget *window, *pixmapwid, *button;
GdkPixmap *pixmap;
GdkBitmap *mask;
GtkStyle *style;
/* 创建主窗口,为d e l e t e _ e v e n t信号设置回调函数以终止应用程序* /
gtk_init( &argc, &argv );
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_signal_connect( GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (close_application), NULL );
gtk_container_set_border_width( GTK_CONTAINER (window), 10 );
gtk_widget_show( window );
/* 现在用g d k创建Pixmap */
style = gtk_widget_get_style( window );
pixmap = gdk_pixmap_create_from_xpm_d( window->window, &mask,
& s t y l e - > b g [ G T K _ S T A T E _ N O R M A L ] ,
(gchar **)xpm_data );
/* 用一个P i x m a p构件包含这个p i x m a p图片* /
pixmapwid = gtk_pixmap_new( pixmap, mask );
gtk_widget_show( pixmapwid );
/* 将p i x m a p构件放在一个按钮中* /
button = gtk_button_new();
gtk_container_add( GTK_CONTAINER(button), pixmapwid );
gtk_container_add( GTK_CONTAINER(window), button );
gtk_widget_show( button );
gtk_signal_connect( GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(button_clicked), NULL );
/* 显示主窗口* /
gtk_main ();
return 0;
}
/ *示例结束* /
如果要从当前目录的i c o n 0 . x p m中加载图片,我们可以用下面的方法创建p i x m a p图片:
/* 从文件加载p i x m a p图片* /
pixmap = gdk_pixmap_create_from_xpm( window->window, &mask,
& s t y l e - > b g [ G T K _ S T A T E _ N O R M A L ] ,
"./icon0.xpm" );
pixmapwid = gtk_pixmap_new( pixmap, mask );
gtk_widget_show( pixmapwid );
gtk_container_add( GTK_CONTAINER(window), pixmapwid );
使用p i x m a p图片的不利之处是它显示的对象总是矩形的,而不管图片内容如何。我们可以用具有自然形状的图片来创建应用程序和桌面程序。例如,对游戏软件的界面,我们希望有一个圆角按钮,那么可以用“有形窗口”来做到这一点。
一个有形窗口实际上就是p i x m a p图像,它的背景颜色是透明的。这样,当背景图片有多种颜色时,我们就不会用不匹配的图标矩形边界来覆盖它。下面的例子在桌面上显示一个完整的独轮手推车。
/ *示例开始—独轮手推车wheelbarrow.c */
#include <gtk/gtk.h>
/* XPM */
static char * WheelbarrowFull_xpm[] = {
"48 48 64 1",
" c None",
". c #DF7DCF3CC71B",
"X c #965875D669A6",
"o c #71C671C671C6",
"O c #A699A289A699",
"+ c #965892489658",
"@ c #8E38410330C2",
"# c #D75C7DF769A6",
"$ c #F7DECF3CC71B",
"% c #96588A288E38",
"& c #A69992489E79",
"* c #8E3886178E38",
"= c #104008200820",
"- c #596510401040",
"; c #C71B30C230C2",
": c #C71B9A699658",
"> c #618561856185",
", c #20811C712081",
"< c #104000000000",
"1 c #861720812081",
"2 c #DF7D4D344103",
"3 c #79E769A671C6",
"4 c #861782078617",
"5 c #41033CF34103",
"6 c #000000000000",
"7 c #49241C711040",
"8 c #492445144924",
"9 c #082008200820",
"0 c #69A618611861",
"q c #B6DA71C65144",
"w c #410330C238E3",
"e c #CF3CBAEAB6DA",
"r c #71C6451430C2",
"t c #EFBEDB6CD75C",
"y c #28A208200820",
"u c #186110401040",
"i c #596528A21861",
"p c #71C661855965",
"a c #A69996589658",
"s c #30C228A230C2",
"d c #BEFBA289AEBA",
"f c #596545145144",
"g c #30C230C230C2",
"h c #8E3882078617",
"j c #208118612081",
"k c #38E30C300820",
"l c #30C2208128A2",
"z c #38E328A238E3",
"x c #514438E34924",
"c c #618555555965",
"v c #30C2208130C2",
"b c #38E328A230C2",
"n c #28A228A228A2",
"m c #41032CB228A2",
"M c #104010401040",
"N c #492438E34103",
"B c #28A2208128A2",
"V c #A699596538E3",
"C c #30C21C711040",
"Z c #30C218611040",
"A c #965865955965",
"S c #618534D32081",
"D c #38E31C711040",
"F c #082000000820",
" ",
" .XoO ",
" +@#$%o& ",
" *=-;#::o+ ",
" >,<12#:34 ",
" 45671#:X3 ",
" +89<02qwo ",
"e* >,67;ro ",
"ty> 459@>+&& ",
"$2u+ ><ipas8* ",
"%$;=* *3:.Xa.dfg> ",
"Oh$;ya *3d.a8j,Xe.d3g8+ ",
" Oh$;ka *3d$a8lz,,xxc:.e3g54 ",
" Oh$;kO *pd$%svbzz,sxxxxfX..&wn> ",
" Oh$@mO *3dthwlsslszjzxxxxxxx3:td8M4 ",
" Oh$@g& *3d$XNlvvvlllm,mNwxxxxxxxfa.:,B* ",
" Oh$@,Od.czlllllzlmmqV@V#V@fxxxxxxxf:%j5& ",
" Oh$1hd5lllslllCCZrV#r#:#2AxxxxxxxxxcdwM* ",
" OXq6c.%8vvvllZZiqqApA:mq:Xxcpcxxxxxfdc9* ",
" 2r<6gde3bllZZrVi7S@SV77A::qApxxxxxxfdcM ",
" :,q-6MN.dfmZZrrSS:#riirDSAX@Af5xxxxxfevo",
" +A26jguXtAZZZC7iDiCCrVVii7Cmmmxxxxxx%3g",
" *#16jszN..3DZZZZrCVSA2rZrV7Dmmwxxxx&en",
" p2yFvzssXe:fCZZCiiD7iiZDiDSSZwwxx8e*>",
" OA1<jzxwwc:$d%NDZZZZCCCZCCZZCmxxfd.B ",
" 3206Bwxxszx%et.eaAp77m77mmmf3&eeeg* ",
" @26MvzxNzvlbwfpdettttttttttt.c,n& ",
" *;16=lsNwwNwgsvslbwwvccc3pcfu<o ",
" p;<69BvwwsszslllbBlllllllu<5+ ",
" OS0y6FBlvvvzvzss,u=Blllj=54 ",
" c1-699Blvlllllu7k96MMMg4 ",
" *10y8n6FjvllllB<166668 ",
" S-kg+>666<M<996-y6n<8* ",
" p71=4 m69996kD8Z-66698&& ",
" &i0ycm6n4 ogk17,0<6666g ",
" N-k-<> >=01-kuu666> ",
" ,6ky& &46-10ul,66, ",
" Ou0<> o66y<ulw<66& ",
" *kk5 >66By7=xu664 ",
" <<M4 466lj<Mxu66o ",
" *>> +66uv,zN666* ",
" 566,xxj669 ",
" 4666FF666> ",
" >966666M ",
" oM6668+ ",
" *4 ",
" ",
" "};
/* 调用这个函数时(通过d e l e t e _ e v e n t信号),终止应用程序* /
void close_application( GtkWidget *widget,
GdkEvent *event, gpointer data )
{
g t k _ m a i n _ q u i t ( ) ;
}
int main (int argc, char *argv[])
{
/* 构件的存储类型是GtkWidget */
GtkWidget *window, *pixmap, *fixed;
GdkPixmap *gdk_pixmap;
GdkBitmap *mask;
GtkStyle *style;
GdkGC *gc;
/* 创建主窗口,为d e l e t e _ e v e n t信号设置回调函数以终止应用程序。
* 注意,主窗口没有标题条,因为我们让它是一个弹出窗口* /
gtk_init (&argc, &argv);
window = gtk_window_new( GTK_WINDOW_POPUP );
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (close_application), NULL);
gtk_widget_show (window);
/* 下面创建p i x m a p图片和p i x m a p构件* /
style = gtk_widget_get_default_style();
gc = style->black_gc;
gdk_pixmap = gdk_pixmap_create_from_xpm_d( window->window, &mask,
& s t y l e - > b g [ G T K _ S T A T E _ N O R M A L ] ,
WheelbarrowFull_xpm );
pixmap = gtk_pixmap_new( gdk_pixmap, mask );
gtk_widget_show( pixmap );
/* 要显示p i x m a p图片,我们将p i x m a p构件放在G t k F i x e d构件上* /
fixed = gtk_fixed_new();
gtk_widget_set_usize( fixed, 200, 200 );
gtk_fixed_put( GTK_FIXED(fixed), pixmap, 0, 0 );
gtk_container_add( GTK_CONTAINER(window), fixed );
gtk_widget_show( fixed );
/* 下面的函数屏蔽了除图片本身以外的所有东西* /
gtk_widget_shape_combine_mask( window, mask, 0, 0 );
/* 显示窗口*/
gtk_widget_set_uposition( window, 20, 400 );
gtk_widget_show( window );
gtk_main ();
r e t u r n ( 0 ) ;
}
/* 示例结束* /
要想让“手推车”图片敏感(对点击响应),可以给窗口连接一个b u t t o n _ p r e s s信号,当我们点击窗口时,就会调用一个回调函数。下面几行代码让图片敏感,当鼠标按下时终止应用程序。
gtk_widget_set_events( window,
gtk_widget_get_events( window ) |
GDK_BUTTON_PRESS_MASK );
gtk_signal_connect( GTK_OBJECT(window), "button_press_event",GTK_SIGNAL_FUNC(close_application), NULL );


标尺构件GtkRuler
G t k R u l e r (标尺构件)一般用于在给定窗口中指示鼠标指针的位置。一个窗口可以有一个横跨整个窗口宽度的水平标尺和一个占据整个窗口高度的垂直标尺。标尺上有一个小三角形的指示器标出鼠标指针相对于标尺的精确位置。
有两种标尺构件:G t k H R u l e r(水平)和G t k V R u l e r(垂直)。
首先,必须创建标尺构件。水平和垂直标尺用下面的函数创建:
GtkWidget *gtk_hruler_new(void水);平/标*尺*/
GtkWidget *gtk_vruler_new(void垂);直/标* 尺* /
一旦创建了标尺,我们就能指定它的度量单位。标尺的度量单位可以是b e G T K _ P I X E L S,
G T K _ I N C H E S或G T K _ C E N T I M E T E R S。可以用下面的函数设置:
void gtk_ruler_set_metric( GtkRuler *ruler,GtkMetricType metric );
默认的度量单位是G T K _ P I X E L S。
gtk_ruler_set_metric( GTK_RULER(ruler), GTK_PIXELS );
标尺构件的另一个重要属性是怎样标志刻度单位以及位置指示器一开始应该放在哪里。
可以用下面的函数设置:
void gtk_ruler_set_range( GtkRuler *ruler,gfloat lower,gfloat upper,gfloat position,gfloat max_size );
其中l o w e r和u p p e r参数定义标尺的范围, m a x _ s i z e是要显示的最大可能数值。第四个参数p o s i t i o n定义了标尺的指针指示器的初始位置。
垂直标尺能跨越8 0 0像素宽的窗口,因此:
gtk_ruler_set_range( GTK_RULER(vruler), 0, 800, 0, 800);
标尺上显示标志会从0到8 0 0,每1 0 0个像素一个数字。如果我们想让标尺的范围从7到1 6,可以使用下面的代码:
gtk_ruler_set_range( GTK_RULER(vruler), 7, 16, 0, 20);
标尺上的指示器是一个小三角形的标记,指示鼠标指针相对于标尺的位置。如果标尺是用于跟踪鼠标器指针的,应该将m o t i o n _ n o t i f y _ e v e n t信号连接到标尺的m o t i o n _ n o t i f y _ e v e n t方法。要跟踪鼠标在整个窗口区域内的移动,应该这样做:
#define EVENT_METHOD(i, x) GTK_WIDGET_CLASS(GTK_OBJECT(i)->klass)->x
gtk_signal_connect_object( GTK_OBJECT(area), "motion_notify_event",
(GtkSignalFunc)EVENT_METHOD(ruler, motion_notify_event),
GTK_OBJECT(ruler) );
下列例子创建一个绘图区,上面加一个水平标尺,左边加一个垂直标尺。绘图区的大小是6 0 0像素宽× 4 0 0像素高。水平标尺范围是从7到1 3,每1 0 0像素加一个刻度;垂直标尺范围从0到4 0 0,每1 0 0像素加一个刻度。绘图区和标尺的定位是用表格构件( G t k Ta b l e)实现的。
/* 标尺示例开始rulers.c */
#include <gtk/gtk.h>
#define EVENT_METHOD(i, x) GTK_WIDGET_CLASS(GTK_OBJECT(i)->klass)->x
#define XSIZE 600
#define YSIZE 400
/* 当点击" c l o s e "按钮时,退出应用程序* /
void close_application( GtkWidget *widget,
GdkEvent *event, gpointer data )
{
g t k _ m a i n _ q u i t ( ) ;
}
/* 主函数* /
int main( int argc, char *argv[] ) {
GtkWidget *window, *table, *area, *hrule, *vrule;
/* 初始化G T K,创建主窗口* /
gtk_init( &argc, &argv );
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC( close_application ), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* 创建一个G t k T a b l e构件,标尺和绘图区放在里面* /
table = gtk_table_new( 3, 2, FALSE );
gtk_container_add( GTK_CONTAINER(window), table );
area = gtk_drawing_area_new();
gtk_drawing_area_size( (GtkDrawingArea *)area, XSIZE, YSIZE );
gtk_table_attach( GTK_TABLE(table), area, 1, 2, 1, 2,
GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0 );
gtk_widget_set_events( area, GDK_POINTER_MOTION_MASK |
GDK_POINTER_MOTION_HINT_MASK );
/* 水平标尺放在顶部。鼠标移动穿过绘图区时,一个
* motion_notify_eve被n传t 递给标尺的相应的事件处理函数* /
hrule = gtk_hruler_new();
gtk_ruler_set_metric( GTK_RULER(hrule), GTK_PIXELS );
gtk_ruler_set_range( GTK_RULER(hrule), 7, 13, 0, 20 );
gtk_signal_connect_object( GTK_OBJECT(area), "motion_notify_event",
( G t k S i g n a l F u n c ) E V E N T _ M E T H O D ( h r u l e ,
m o t i o n _ n o t i f y _ e v e n t ) ,
GTK_OBJECT(hrule) );
/* GTK_WIDGET_CLASS(GTK_OBJECT(hrule)->klass)->motion_notify_event, */
gtk_table_attach( GTK_TABLE(table), hrule, 1, 2, 0, 1,
GTK_EXPAND|GTK_SHRINK|GTK_FILL, GTK_FILL, 0, 0 );
/* 垂直标尺显示在左边。当鼠标移动穿过绘图区时,
* motion_notify_eve被n传t 递到标尺相应的事件处理函数中* /
vrule = gtk_vruler_new();
gtk_ruler_set_metric( GTK_RULER(vrule), GTK_PIXELS );
gtk_ruler_set_range( GTK_RULER(vrule), 0, YSIZE, 10, YSIZE );
gtk_signal_connect_object( GTK_OBJECT(area), "motion_notify_event",
( G t k S i g n a l F u n c )
G T K _ W I D G E T _ C L A S S ( G T K _ O B J E C T ( v r u l e ) - > k l a s s ) - >
m o t i o n _ n o t i f y _ e v e n t ,
GTK_OBJECT(vrule) );
gtk_table_attach( GTK_TABLE(table), vrule, 0, 1, 1, 2,
GTK_FILL, GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0 );
/* 现在显示所有的构件* /
gtk_widget_show( area );
gtk_widget_show( hrule );
gtk_widget_show( vrule );
gtk_widget_show( table );
gtk_widget_show( window );
g t k _ m a i n ( ) ;
r e t u r n ( 0 ) ;
} /*示例结束*/
将上面的代码保存为r u l e r s . c,然后编写一个如下所示的M a k e f i l e文件。
CC = gcc
rulers: rulers.c
$(CC) `gtk-config --cflags` rulers.c -o rulers \
`gtk-config --libs`
clean:
rm -f *.o rulers
编译,运行结果如图9 - 4所示。当鼠标在绘图区移动时,水平和垂直标尺上都能清楚地显示鼠标的位置。

GTK+2.0-----杂项构件(1) - 垒 - jiangbowen1_qd的博客
图9-4 标尺示例


文本输入构件GtkEntry
G t k E n t r y (文本输入构件)允许在一个单行文本框里输入和显示一行文本。文本可以用函数进行操作,如将新的文本替换、前插、追加到文本输入构件的当前内容中。
有两个用于创建文本输入构件的函数:
GtkWidget *gtk_entry_new(void);
GtkWidget *gtk_entry_new_with_max_length( guint16 max);
第一个函数创建新的文本输入构件,第二个函数创建新的最大文本长度为m a x的文本输入构件。
有几个函数是用来改变构件内的文本内容的:
void gtk_entry_set_text( GtkEntry *entry,
const gchar *text );
void gtk_entry_append_text( GtkEntry *entry,
const gchar *text );
void gtk_entry_prepend_text( GtkEntry *entry,
const gchar *text
函数g t k _ e n t r y _ s e t _ t e x t设置文本输入构件内的文本内容目录。
函数g t k _ e n t r y _ a p p e n d _ t e x t和g t k _ e n t r y _ p r e p e n d _ t e x t将新文本前插和追加到构件当前文本中。
下面的函数用于设置当前插入点。
void gtk_entry_set_position( GtkEntry *entry,gint position );
文本输入构件内的文本可以用下面的函数获取。这在下面介绍的回调函数中是很有用的。
gchar *gtk_entry_get_text( GtkEntry *entry );
函数返回的值在函数内部使用,不必用f r e e ( )或者g _ f r e e ( )释放。如果想让文本输入构件是只读的,可以改变它的可编辑状态。
void gtk_entry_set_editable( GtkEntry *entry,gboolean editable );
其中e d i t a b l e可设为T R U E(可编辑)或FA L S E(不可编辑)。
如果想让文本输入构件输入的文本不回显(比如用于接收口令),可以使用下列函数,其中v i s i b l e可以取为T R U E(显示)或FA L S E(不显示)。
void gtk_entry_set_visibility( GtkEntry *entry,gboolean visible );
文本内的某一部分可以用下面的函数设置为选中。一般用于用文本输入构件为用户提供一个缺省值,这样当构件获得焦点时就可以全部选中其中的文本,用户的输入会直接替换全部文本。
void gtk_entry_select_region( GtkEntry *entry,
gint start,
gint end );
如果我们想在用户输入文本时进行响应,可以为a c t i v a t e或者c h a n g e d信号设置回调函数。当用户在文本输入构件内部按回车键时引发a c t i v a t e信号;当文本构件内部的文本发生变化时引发c h a n g e d信号。
下面的代码是一个使用文本输入构件的示例。
/* 文本输入构件示例开始entry.c */
#include <gtk/gtk.h>
void enter_callback(GtkWidget *widget, GtkWidget *entry)
{
gchar *entry_text;
entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
printf("Entry contents: %s\n", entry_text);
}
void entry_toggle_editable (GtkWidget *checkbutton,GtkWidget *entry)
{
g t k _ e n t r y _ s e t _ e d i t a b l e ( G T K _ E N T R Y ( e n t r y ) ,
G T K _ T O G G L E _ B U T T O N ( c h e c k b u t t o n ) - > a c t i v e ) ;
}
void entry_toggle_visibility (GtkWidget *checkbutton,GtkWidget *entry)
{
g t k _ e n t r y _ s e t _ v i s i b i l i t y ( G T K _ E N T R Y ( e n t r y ) ,
G T K _ T O G G L E _ B U T T O N ( c h e c k b u t t o n ) - > a c t i v e ) ;
}
int main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *vbox, *hbox;
GtkWidget *entry;
GtkWidget *button;
GtkWidget *check;
gtk_init (&argc, &argv);
/* 创建主窗口* /
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_usize( GTK_WIDGET (window), 200, 100);
gtk_window_set_title(GTK_WINDOW (window), "GTK Entry");
gtk_signal_connect(GTK_OBJECT (window), "delete_event",(GtkSignalFunc) gtk_exit, NULL);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_widget_show (vbox);
entry = gtk_entry_new_with_max_length (50);
gtk_signal_connect(GTK_OBJECT(entry), "activate",
G T K _ S I G N A L _ F U N C ( e n t e r _ c a l l b a c k ) ,e n t r y ) ;
gtk_entry_set_text (GTK_ENTRY (entry), "hello");
gtk_entry_append_text (GTK_ENTRY (entry), " world");
gtk_entry_select_region (GTK_ENTRY (entry),0, GTK_ENTRY(entry)->text_length);
gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 0);
gtk_widget_show (entry);
hbox = gtk_hbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (vbox), hbox);
gtk_widget_show (hbox);
check = gtk_check_button_new_with_label("Editable");
gtk_box_pack_start (GTK_BOX (hbox), check, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT(check), "toggled",G T K _ S I G N A L _ F U N C ( e n t r y _ t o g g l e _ e d i t a b l e ) ,e n t r y ) ;
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
gtk_widget_show (check);
check = gtk_check_button_new_with_label("Visible");
gtk_box_pack_start (GTK_BOX (hbox), check, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT(check), "toggled",
G T K _ S I G N A L _ F U N C ( e n t r y _ t o g g l e _ v i s i b i l i t y ) ,e n t r y ) ;
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
gtk_widget_show (check);
button = gtk_button_new_with_label ("Close");
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",G T K _ S I G N A L _ F U N C ( g t k _ e x i t ) ,
GTK_OBJECT (window));
gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
gtk_widget_show (button);
g t k _ w i d g e t _ s h o w ( w i n d o w ) ;
g t k _ m a i n ( ) ;
r e t u r n ( 0 ) ;
}
/ *示例结束*/
将上面的代码保存为e n t r y. c,然后编写一个如下所示的M a k e f i l e文件。
CC = gcc
entry: entry.c
$(CC) `gtk-config --cflags` entry.c -o \
entry `gtk-config --libs`
clean:
rm -f *.o entry
编译应用程序,然后在s h e l l提示符下输入. / e n t r y,执行结果如图9 - 5所示。当E d i t a b l e检查按钮是按下状态时,可以编辑文本输入构件内的文本;如果该检查按钮是弹起的,不能对文本输入构件的文本进行编辑。Vi s i b l e检查按钮是按下状态时,用户输入的字符会显示在文本输入构件上,否则不显示出来。

GTK+2.0-----杂项构件(1) - 垒 - jiangbowen1_qd的博客
图9-5 文本输入构件GtkEntry


微调按钮构件GtkSpinButton
G t k S p i n B u t t o n (微调按钮构件)通常用于让用户从一个取值范围内选择一个值。它由一个文本输入框和旁边的向上和向下两个按钮组成。点击某一个按钮会让文本输入框内的数值大小在一定范围内改变。文本输入框也可以直接进行编辑。
微调按钮构件允许其中的数值没有小数位或具有指定的小数位,并且数值可以按一种可配置的方式增加或减小。在按钮较长时间呈按下状态时,构件的数值会根据工具按下时间的长短加速变化。
微调按钮用一个调整对象来维护该按钮能够取值的范围。微调按钮构件因此而具有了很强大的功能。
下面是创建调整对象的函数。这里的用意是展示其中所包含的数值的意义:
GtkObject *gtk_adjustment_new( gfloat value,
gfloat lower,
gfloat upper,
gfloat step_increment,
gfloat page_increment,
gfloat page_size );
调整对象的这些属性在微调按钮构件中有如下用处:
value: 微调按钮构件的初值。
lower: 构件允许的最小值。
upper: 构件允许的最大值。
step_increment: 当鼠标左键按下时构件一次增加/减小的值。
page_increment: 当鼠标右键按下时构件一次增加/减小的值。
page_size: 没有用到。
另外,当用鼠标中间键点击向下或向上按钮时,可以直接跳到构件的l o w e r或u p p e r值。
用下面的函数创建新微调按钮构件:
GtkWidget *gtk_spin_button_new( GtkAdjustment *adjustment,gfloat climb_rate,guint digits );
其中的c l i m b _ r a t e参数是介于0 . 0和1 . 0间的值,指明构件数值变化的加速度(长时间按住
按钮,数值会加速变化)。第三个参数d i g i t s指定要显示的值的小数位数。
创建微调按钮构件之后,还可以用下面的函数对其重新配置:
void gtk_spin_button_configure( GtkSpinButton *spin_button,
GtkAdjustment *adjustment,
gfloat climb_rate,
guint digits );
其中s p i n _ b u t t o n参数就是要重新配置的参数。其他的参数与创建时的参数意思相同。
使用下面的函数可以设置或获取构件内部使用的调整对象:
void gtk_spin_button_set_adjustment( GtkSpinButton *spin_button,
GtkAdjustment *adjustment );
GtkAdjustment adjustment(
GtkSpinButton *spin_button );
显示数值的小数位数可以用下面的函数改变,其中d i g i t s就是小数位数:
void gtk_spin_button_set_digits( GtkSpinButton *spin_button,guint digits) ;
当前显示的构件数值可以用下面的函数改变:
void gtk_spin_button_set_value( GtkSpinButton *spin_button,gfloat value );
微调按钮构件的当前值可以以整数或浮点数的形式获得。使用下面的函数:
gfloat gtk_spin_button_get_value_as_float( GtkSpinButton *spin_button );
gint gtk_spin_button_get_value_as_int( GtkSpinButton *spin_button );
如果想以当前值为基数改变构件的值,可以使用下面的函数:
void gtk_spin_button_spin( GtkSpinButton *spin_button,
GtkSpinType direction,
gfloat increment );
其中,d i r e c t i o n参数可以取下面的值:
G T K _ S P I N _ S T E P _ F O RWA R D
G T K _ S P I N _ S T E P _ B A C K WA R D
G T K _ S P I N _ PA G E _ F O RWA R D
G T K _ S P I N _ PA G E _ B A C K WA R D
G T K _ S P I N _ H O M E
G T K _ S P I N _ E N D
G T K _ S P I N _ U S E R _ D E F I N E D
这个函数中包含的一些功能将在下面详细介绍。其中的许多设置都使用了与微调按钮构件相关联的调整对象的值。
G T K _ S P I N _ S T E P _ F O RWA R D和G T K _ S P I N _ S T E P _ B A C K WA R D将构件的值按i n c r e m e n t参数指定的数值增大或减小,除非i n c r e m e n t参数是0。这种情况下,构件的值将按与其相关联的调整对象的s t e p _ i n c r e m e n t值改变。
G T K _ S P I N _ PA G E _ F O RWA R D和G T K _ S P I N _ PA G E _ B A C K WA R D按i n c r e m e n t参数改变微调按钮构件的值。
G T K _ S P I N _ H O M E将构件的值设置为相关联调整对象的范围的最小值。
GTK_SPIN_END 将构件的值设置为相关联调整对象的范围的最大值。
GTK_SPIN_USER_DEFINED 按指定的数值改变构件的数值。
下面介绍影响微调按钮构件的外观和行为的函数。
要介绍的第一个函数就是限制微调按钮构件的文本框只能输入数值。这样就阻止了用户输入任何非法的字符:
void gtk_spin_button_set_numeric( GtkSpinButton *spin_button,gboolean numeric );
可以设置让微调按钮构件在u p p e r和l o w e r之间循环。也就是当达到最大值后再向上调整回到最小值,当达到最小值后再向下调整变为最大值。可以用下面的函数实现,其中w r a p可以设置为T R U E和FA L S E:
void gtk_spin_button_set_wrap( GtkSpinButton *spin_button,gboolean wrap );
可以设置让微调按钮构件将其值圆整到最接近s t e p _ i n c r e m e n t的值(在该微调按钮构件使用的调整对象中设置的)。用下面的函数实现:
void gtk_spin_button_set_snap_to_ticks( GtkSpinButton *spin_button,gboolean snap_to_ticks );
微调按钮构件的更新方式可以用下面的函数改变:
void gtk_spin_button_set_update_policy( GtkSpinButton *spin_button,GtkSpinButtonUpdatePolicy policy );
其中p o l i c y参数可以取G T K _ U P D AT E _ A LWAY S或G T K _ U P D AT E _ I F _ VA L I D。
这些更新方式影响微调按钮构件在解析插入文本并将其值与调整对象的值同步时的行为。
在p o l i c y值为G T K _ U P D AT E _ I F _ VA L I D时,微调按钮构件只有在输入文本是其中调整对象指定范围内合法的值时才进行更新,否则文本会被重置为当前的值。
在p o l i c y值为G T K _ U P D AT E _ A LWAY S时,在将文本转换为数值时忽略错误。构件中使用的向上和向下的按钮的外观可以用下面的函数改变:
void gtk_spin_button_set_shadow_type( GtkSpinButton *spin_button,GtkShadowType shadow_type );
与其他构件一样,s h a d o w _ t y p e参数可以取以下的值:
G T K _ S H A D O W _ I N
G T K _ S H A D O W _ O U T
G T K _ S H A D O W _ E T C H E D _ I N
G T K _ S H A D O W _ E T C H E D _ O U T
最后,可以强行要求微调按钮构件更新自己:
void gtk_spin_button_update( GtkSpinButton *spin_button );
下面是一个使用微调按钮构件的示例。
/* 微调按钮构件示例开始spinbutton.c */
#include <gtk/gtk.h>
static GtkWidget *spinner1;
void toggle_snap( GtkWidget *widget,GtkSpinButton *spin )
{
gtk_spin_button_set_snap_to_ticks (spin,GTK_TOGGLE_BUTTON (widget)->active);
}
void toggle_numeric( GtkWidget *widget,GtkSpinButton *spin )
{
gtk_spin_button_set_numeric (spin,GTK_TOGGLE_BUTTON (widget)->active);
}
void change_digits( GtkWidget *widget,GtkSpinButton *spin )
{
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinner1),
gtk_spin_button_get_value_as_int (spin));
}
void get_value( GtkWidget *widget,gpointer data )
{
gchar buf[32];
GtkLabel *label;
GtkSpinButton *spin;
spin = GTK_SPIN_BUTTON (spinner1);
label = GTK_LABEL (gtk_object_get_user_data (GTK_OBJECT (widget)));
if (GPOINTER_TO_INT (data) == 1)
sprintf (buf, "%d", gtk_spin_button_get_value_as_int (spin));
e l s e
sprintf (buf, "%0.*f", spin->digits,
gtk_spin_button_get_value_as_float (spin));
gtk_label_set_text (label, buf);
}
int main( int argc,
char *argv[] )
{
GtkWidget *window;
GtkWidget *frame;
GtkWidget *hbox;
GtkWidget *main_vbox;
GtkWidget *vbox;
GtkWidget *vbox2;
GtkWidget *spinner2;
GtkWidget *spinner;
GtkWidget *button;
GtkWidget *label;
GtkWidget *val_label;
GtkAdjustment *adj;
/* 初始化GTK */
gtk_init(&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "destroy",GTK_SIGNAL_FUNC (gtk_main_quit),N U L L ) ;
gtk_window_set_title (GTK_WINDOW (window), "Spin Button");
main_vbox = gtk_vbox_new (FALSE, 5);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 10);
gtk_container_add (GTK_CONTAINER (window), main_vbox);
frame = gtk_frame_new ("Not accelerated");
gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
gtk_container_add (GTK_CONTAINER (frame), vbox);
/* 年、月、日微调器* /
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
vbox2 = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
label = gtk_label_new ("Day :");
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
adj = (GtkAdjustment *) gtk_adjustment_new (1.0, 1.0, 31.0, 1.0,5.0, 0.0);
spinner = gtk_spin_button_new (adj, 0, 0);
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinner),G T K _ S H A D O W _ O U T ) ;
gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
vbox2 = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
label = gtk_label_new ("Month :");
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
adj = (GtkAdjustment *) gtk_adjustment_new (1.0, 1.0, 12.0, 1.0,
5.0, 0.0);
spinner = gtk_spin_button_new (adj, 0, 0);
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinner),
G T K _ S H A D O W _ E T C H E D _ I N ) ;
gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
vbox2 = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
label = gtk_label_new ("Year :");
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
adj = (GtkAdjustment *) gtk_adjustment_new (1998.0, 0.0, 2100.0,1.0, 100.0, 0.0);
spinner = gtk_spin_button_new (adj, 0, 0);
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), FALSE);
gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinner),G T K _ S H A D O W _ I N ) ;
gtk_widget_set_usize (spinner, 55, 0);
gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
frame = gtk_frame_new ("Accelerated");
gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
gtk_container_add (GTK_CONTAINER (frame), vbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
vbox2 = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
label = gtk_label_new ("Value :");
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
adj = (GtkAdjustment *) gtk_adjustment_new (0.0, -10000.0, 10000.0,0.5, 100.0, 0.0);
spinner1 = gtk_spin_button_new (adj, 1.0, 2);
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner1), TRUE);
gtk_widget_set_usize (spinner1, 100, 0);
gtk_box_pack_start (GTK_BOX (vbox2), spinner1, FALSE, TRUE, 0);
vbox2 = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
label = gtk_label_new ("Digits :");
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
adj = (GtkAdjustment *) gtk_adjustment_new (2, 1, 5, 1, 1, 0);
spinner2 = gtk_spin_button_new (adj, 0.0, 0);
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner2), TRUE);
gtk_signal_connect (GTK_OBJECT (adj), "value_changed",GTK_SIGNAL_FUNC (change_digits),(gpointer) spinner2);
gtk_box_pack_start (GTK_BOX (vbox2), spinner2, FALSE, TRUE, 0);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
button = gtk_check_button_new_with_label ("Snap to 0.5-ticks");
gtk_signal_connect (GTK_OBJECT (button), "clicked",GTK_SIGNAL_FUNC (toggle_snap),s p i n n e r 1 ) ;
gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
button = gtk_check_button_new_with_label ("Numeric only input mode");
gtk_signal_connect (GTK_OBJECT (button), "clicked",GTK_SIGNAL_FUNC (toggle_numeric),s p i n n e r 1 ) ;
gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
val_label = gtk_label_new ("");
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
button = gtk_button_new_with_label ("Value as Int");
gtk_object_set_user_data (GTK_OBJECT (button), val_label);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (get_value),
GINT_TO_POINTER (1));
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
button = gtk_button_new_with_label ("Value as Float");
gtk_object_set_user_data (GTK_OBJECT (button), val_label);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (get_value),
GINT_TO_POINTER (2));
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
gtk_box_pack_start (GTK_BOX (vbox), val_label, TRUE, TRUE, 0);
gtk_label_set_text (GTK_LABEL (val_label), "0");
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
button = gtk_button_new_with_label ("Close");
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (gtk_widget_destroy),
GTK_OBJECT (window));
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE,5 ) ;
gtk_widget_show_all (window); /* Enter the event loop*/

gtk_main ();
r e t u r n ( 0 ) ; }
/ *示例结束*/
图9 - 6是上面代码的运行结果。点击微调按钮右边的向上和向下箭头,前面的文本框的数值会随之而改变。

GTK+2.0-----杂项构件(1) - 垒 - jiangbowen1_qd的博客

图9-6 微调按钮构件示例


  评论这张
 
阅读(181)| 评论(1)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017