GTK中设置滚动条到某一特定位置

接触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的值应该设定为多少,才能达到我们想要的效果呢。首先要明确几个概念,如下图所示:

GTK中设置滚动条到某一特定位置  GTK中设置滚动条到某一特定位置  GTK中设置滚动条到某一特定位置

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 Value
Step 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。

你可能感兴趣的:(gtk,设置位置,滚动窗口)