接触GTK没多久,这个问题总算搞通了。可能还有更简便的方法,希望高手指点一下。
问题:滚动窗口中有一列表,列表中每一行的高度是确定的,用代码实现将滚动条滚动到某一行。
解决方案:
原理是设置滚动条的GtkAdjustment属性。
GtkAdjustment *adj;adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolled_window));
这段代码是获取滚动窗口的纵向GtkAdjustment,之后,通过设定adj的值就可以实现设定滚动条的位置了。
gtk_adjustment_set_value(GTK_ADJUSTMENT(adj), value);
但是要注意的是,要在程序执行gtk_main();之后才有效。例如,可以把上面的代码用在某个回调函数中。
本文所讨论的都是在gtk_main();执行之后的情况,否则的话将不能得到正确结果。
那么,value的值应该设定为多少,才能达到我们想要的效果呢。首先要明确几个概念,如下图所示:
Current Value:GtkAdjustment的当前值,如上图Max Value:这个是我自己给起的名称,表示可以给GtkAdjustment设定的最大值,如上图Page Size:如上图,滚动条按钮的长度Page Increment:表示单击滚动条中的空白区域一次,Current Value发生变化的值Step Increment:这个表示点击一次滚动条的上移或者下移按钮(也就是带三角形的按钮)一次,Current Value发生变化的值Lower Value:如上图,表示最小值Upper Value:如上图,可以理解为整个列表的高度
其中:
Max Value + Page Size = Upper ValueStep Increment + Page Increment = Page Size
上面的值都可以通过GTK提供的函数获取或者设置:
gdouble gtk_adjustment_get_value(GtkAdjustment *adjustment);void gtk_adjustment_set_value(GtkAdjustment *adjustment, gdouble value);gdouble gtk_adjustment_get_lower(GtkAdjustment *adjustment);void gtk_adjustment_set_lower(GtkAdjustment *adjustment, gdouble lower);gdouble gtk_adjustment_get_upper(GtkAdjustment *adjustment);void gtk_adjustment_set_upper(GtkAdjustment *adjustment, gdouble upper);gdouble gtk_adjustment_get_step_increment(GtkAdjustment *adjustment);void gtk_adjustment_set_step_increment(GtkAdjustment *adjustment, gdouble step_increment);gdouble gtk_adjustment_get_page_increment(GtkAdjustment *adjustment);void gtk_adjustment_set_page_increment(GtkAdjustment *adjustment, gdouble page_increment);gdouble gtk_adjustment_get_page_size (GtkAdjustment *adjustment);void gtk_adjustment_set_page_size(GtkAdjustment *adjustment, gdouble page_size);
明确了这些概念就可以精确的使得滚动条滚动到某位置了。但是gtk_adjustment_set_value这个函数在使用时要注意:
value值最好别大于Max Value值,也别小于Lower Value,否则滚动条上的滑块将会陷入两端,显得很不和谐。
以上面几张图为例,想要设置滚动条滚动到列表的某一行,由于每一行高度是固定的,所以可以采用以下方法:
/************************************************************************//* 函数名:scroll_to_line/* 输入: scrolled_window:要操作的滚动窗口/* line_num:列表中行数/* to_line_index:要滚动到的那一行的行号,从0开始/* 输出: 无/* 功能: 使得滚动窗口的滚动条滚到列表的某一行/************************************************************************/void scroll_to_line(GtkWidget *scrolled_window, gint line_num, gint to_line_index){ GtkAdjustment *adj; gdouble lower_value, upper_value, page_size, max_value, line_height, to_value; adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolled_window)); lower_value = gtk_adjustment_get_lower(adj); upper_value = gtk_adjustment_get_upper(adj); page_size = gtk_adjustment_get_page_size(adj); max_value = upper_value - page_size; line_height = upper_value/line_num; to_value = line_height*to_line_index; if (to_value < lower_value) to_value = lower_value; if (to_value > max_value) to_value = max_value; gtk_adjustment_set_value(adj, to_value);}
有时候为了比较清晰地显示移动到那一行,可以用代码将那行标记为选择,大体代码如下:
GtkTreeSelection *selection;selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_list));GtkTreePath *path;path = gtk_tree_path_new_from_indices(index, -1 ); gtk_tree_selection_select_path( selection, path );
这里直接操作的是滚动窗口中的Tree View。