主要分析 void create_range_controls( void ) 函数: 源码如下:
1 #include <gtk/gtk.h> 2 3 GtkWidget *hscale, *vscale; 4 void cb_pos_menu_select(GtkWidget *item, 5 GtkPositionType pos ) 6 { 7 /* 设置两个比例构件的比例值的显示位置 */ 8 gtk_scale_set_value_pos (GTK_SCALE (hscale), pos); 9 gtk_scale_set_value_pos (GTK_SCALE (vscale), pos); 10 } 11 12 void cb_update_menu_select(GtkWidget *item, 13 GtkUpdateType policy ) 14 { 15 /* 设置两个比例构件的更新方式 */ 16 gtk_range_set_update_policy (GTK_RANGE (hscale), policy); 17 gtk_range_set_update_policy (GTK_RANGE (vscale), policy); 18 } 19 20 void cb_digits_scale( GtkAdjustment *adj ) 21 { 22 /* 设置adj->value圆整的小数位数 */ 23 gtk_scale_set_digits (GTK_SCALE (hscale), (gint) adj->value); 24 gtk_scale_set_digits (GTK_SCALE (vscale), (gint) adj->value); 25 } 26 27 void cb_page_size(GtkAdjustment *get, 28 GtkAdjustment *set ) 29 { 30 /* 将示例调整对象的page size和page increment size设置为"Page Size"比例构件指定的值 */ 31 set->page_size = get->value; 32 set->page_increment = get->value; 33 /* 设置调整对象的值并使它引发一个 "changed" 信号,以重新配置所有已经连接到这个调整对象的构件。 */ 34 gtk_adjustment_set_value(set, CLAMP(set->value,set->lower,(set->upper - set->page_size))); 35 } 36 37 void cb_draw_value( GtkToggleButton *button ) 38 { 39 /* 根据复选按钮的状态设置在比例构件上是否显示比例值 */ 40 gtk_scale_set_draw_value (GTK_SCALE (hscale), button->active); 41 gtk_scale_set_draw_value (GTK_SCALE (vscale), button->active); 42 } 43 44 /* 方便的函数 */ 45 GtkWidget *make_menu_item (gchar *name, 46 GCallback callback, 47 gpointer data) 48 { 49 GtkWidget *item; 50 item = gtk_menu_item_new_with_label (name); 51 g_signal_connect (G_OBJECT (item), "activate", callback, data); 52 gtk_widget_show (item); 53 return item; 54 } 55 56 void scale_set_default_values( GtkScale *scale ) 57 { 58 gtk_range_set_update_policy (GTK_RANGE (scale), 59 GTK_UPDATE_CONTINUOUS); 60 gtk_scale_set_digits (scale, 1); 61 gtk_scale_set_value_pos (scale, GTK_POS_TOP); 62 gtk_scale_set_draw_value (scale, TRUE); 63 } 64 65 /* 创建示例窗口 */ 66 void create_range_controls( void ) 67 { 68 GtkWidget *window; 69 GtkWidget *box1, *box2, *box3; 70 GtkWidget *button; 71 GtkWidget *scrollbar; 72 GtkWidget *separator; 73 GtkWidget *opt, *menu, *item; 74 GtkWidget *label; 75 GtkWidget *scale; 76 GtkObject *adj1, *adj2; 77 78 /* 标准的创建窗口代码 */ 79 window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 80 g_signal_connect (G_OBJECT (window), "destroy", 81 G_CALLBACK (gtk_main_quit), 82 NULL); 83 gtk_window_set_title (GTK_WINDOW (window), "range controls"); 84 box1 = gtk_vbox_new (FALSE, 0); 85 gtk_container_add (GTK_CONTAINER (window), box1); 86 gtk_widget_show (box1); 87 box2 = gtk_hbox_new (FALSE, 10); 88 gtk_container_set_border_width (GTK_CONTAINER (box2), 10); 89 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0); 90 gtk_widget_show (box2); 91 /* value, lower, upper, step_increment, page_increment, page_size */ 92 /* 注意,page_size值只对滚动条构件有区别,并且,你实际上能取得的最高值是(upper - page_size)。 */ 93 adj1 = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0); /* 创建了一个调整对象 */ 94 vscale = gtk_vscale_new (GTK_ADJUSTMENT (adj1)); 95 scale_set_default_values (GTK_SCALE (vscale)); 96 gtk_box_pack_start (GTK_BOX (box2), vscale, TRUE, TRUE, 0); 97 gtk_widget_show (vscale); 98 box3 = gtk_vbox_new (FALSE, 10); 99 gtk_box_pack_start (GTK_BOX (box2), box3, TRUE, TRUE, 0); 100 gtk_widget_show (box3); 101 /* 重新使用同一个调整对象 */ 102 hscale = gtk_hscale_new (GTK_ADJUSTMENT (adj1)); 103 gtk_widget_set_size_request (GTK_WIDGET (hscale), 200, -1); 104 scale_set_default_values (GTK_SCALE (hscale)); 105 gtk_box_pack_start (GTK_BOX (box3), hscale, TRUE, TRUE, 0); 106 gtk_widget_show (hscale); 107 108 /* 再次重用同一个调整对象 */ 109 scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adj1)); 110 /* 注意,这导致当滚动条移动时,比例构件总是连续更新 */ 111 gtk_range_set_update_policy (GTK_RANGE (scrollbar), 112 GTK_UPDATE_CONTINUOUS); 113 gtk_box_pack_start (GTK_BOX (box3), scrollbar, TRUE, TRUE, 0); 114 gtk_widget_show (scrollbar); 115 box2 = gtk_hbox_new (FALSE, 10); 116 gtk_container_set_border_width (GTK_CONTAINER (box2), 10); 117 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0); 118 gtk_widget_show (box2); 119 /* 用一个复选按钮控制是否显示比例构件的值 */ 120 button = gtk_check_button_new_with_label("Display value on scale widgets"); 121 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); 122 g_signal_connect (G_OBJECT (button), "toggled", 123 G_CALLBACK (cb_draw_value), NULL); 124 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); 125 gtk_widget_show (button); 126 box2 = gtk_hbox_new (FALSE, 10); 127 gtk_container_set_border_width (GTK_CONTAINER (box2), 10); 128 /* 用一个选项菜单以改变显示值的位置 */ 129 label = gtk_label_new ("Scale Value Position:"); 130 gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0); 131 gtk_widget_show (label); 132 opt = gtk_option_menu_new (); 133 menu = gtk_menu_new (); 134 item = make_menu_item ("Top", 135 G_CALLBACK (cb_pos_menu_select), 136 GINT_TO_POINTER (GTK_POS_TOP)); 137 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); 138 139 item = make_menu_item ("Bottom", 140 G_CALLBACK (cb_pos_menu_select), 141 GINT_TO_POINTER (GTK_POS_BOTTOM)); 142 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); 143 144 item = make_menu_item ("Left", 145 G_CALLBACK (cb_pos_menu_select), 146 GINT_TO_POINTER (GTK_POS_LEFT)); 147 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); 148 149 item = make_menu_item ("Right", 150 G_CALLBACK (cb_pos_menu_select), 151 GINT_TO_POINTER (GTK_POS_RIGHT)); 152 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); 153 154 gtk_option_menu_set_menu (GTK_OPTION_MENU (opt), menu); 155 gtk_box_pack_start (GTK_BOX (box2), opt, TRUE, TRUE, 0); 156 gtk_widget_show (opt); 157 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0); 158 gtk_widget_show (box2); 159 160 box2 = gtk_hbox_new (FALSE, 10); 161 gtk_container_set_border_width (GTK_CONTAINER (box2), 10); 162 /* 另一个选项菜单,这里是用于设置比例构件的更新方式 */ 163 label = gtk_label_new ("Scale Update Policy:"); 164 gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0); 165 gtk_widget_show (label); 166 opt = gtk_option_menu_new (); 167 menu = gtk_menu_new (); 168 item = make_menu_item ("Continuous", 169 G_CALLBACK (cb_update_menu_select), 170 GINT_TO_POINTER (GTK_UPDATE_CONTINUOUS)); 171 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); 172 item = make_menu_item ("Discontinuous", 173 G_CALLBACK (cb_update_menu_select), 174 GINT_TO_POINTER 175 (GTK_UPDATE_DISCONTINUOUS)); 176 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); 177 item = make_menu_item ("Delayed", 178 G_CALLBACK (cb_update_menu_select), 179 GINT_TO_POINTER (GTK_UPDATE_DELAYED)); 180 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); 181 gtk_option_menu_set_menu (GTK_OPTION_MENU (opt), menu); 182 gtk_box_pack_start (GTK_BOX (box2), opt, TRUE, TRUE, 0); 183 gtk_widget_show (opt); 184 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0); 185 gtk_widget_show (box2); 186 box2 = gtk_hbox_new (FALSE, 10); 187 gtk_container_set_border_width (GTK_CONTAINER (box2), 10); 188 /* 一个水平比例构件,用于调整示例比例构件的显示小数位数。 */ 189 label = gtk_label_new ("Scale Digits:"); 190 gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0); 191 gtk_widget_show (label); 192 adj2 = gtk_adjustment_new (1.0, 0.0, 5.0, 1.0, 1.0, 0.0); 193 g_signal_connect (G_OBJECT (adj2), "value_changed", 194 G_CALLBACK (cb_digits_scale), NULL); 195 scale = gtk_hscale_new (GTK_ADJUSTMENT (adj2)); 196 gtk_scale_set_digits (GTK_SCALE (scale), 0); 197 gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0); 198 gtk_widget_show (scale); 199 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0); 200 gtk_widget_show (box2); 201 box2 = gtk_hbox_new (FALSE, 10); 202 gtk_container_set_border_width (GTK_CONTAINER (box2), 10); 203 /* 以及,最后一个水平比例构件用于调整滚动条的page size。 */ 204 label = gtk_label_new ("Scrollbar Page Size:"); 205 gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0); 206 gtk_widget_show (label); 207 adj2 = gtk_adjustment_new (1.0, 1.0, 101.0, 1.0, 1.0, 0.0); 208 g_signal_connect (G_OBJECT (adj2), "value_changed", 209 G_CALLBACK (cb_page_size), adj1); 210 scale = gtk_hscale_new (GTK_ADJUSTMENT (adj2)); 211 gtk_scale_set_digits (GTK_SCALE (scale), 0); 212 gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0); 213 gtk_widget_show (scale); 214 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0); 215 gtk_widget_show (box2); 216 separator = gtk_hseparator_new (); 217 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0); 218 gtk_widget_show (separator); 219 box2 = gtk_vbox_new (FALSE, 10); 220 gtk_container_set_border_width (GTK_CONTAINER (box2), 10); 221 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); 222 gtk_widget_show (box2); 223 button = gtk_button_new_with_label ("Quit"); 224 g_signal_connect_swapped (G_OBJECT (button), "clicked", 225 G_CALLBACK (gtk_main_quit), 226 NULL); 227 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); 228 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); 229 gtk_widget_grab_default (button); 230 gtk_widget_show (button); 231 gtk_widget_show (window); 232 } 233 234 int main(int argc, 235 char *argv[] ) 236 { 237 gtk_init (&argc, &argv); 238 create_range_controls (); 239 gtk_main (); 240 241 return 0; 242 }