自动滚动GtkScrolledWindow,GtkTextView包装在GtkBox中

自动滚动GtkScrolledWindow,GtkTextView包装在GtkBox中,c,gtk,gtk3,C,Gtk,Gtk3,当我在GtkScrolledWindow中有GtkTextView时,当用户在小部件底部添加新行时,它会自动滚动。当我将GtkTextView放入GtkBox,然后放入GTKScrolledwindowo时,我无法工作。我需要把这个框放在GtkTextView和scrollbar之间,我不能不把整个东西放在另一个框中。在GtkScrolledWindow中使用GtkBox时,有没有办法保持自动滚动行为 以下代码说明了我的问题: #include <gtk/gtk.h> int ma

当我在GtkScrolledWindow中有GtkTextView时,当用户在小部件底部添加新行时,它会自动滚动。当我将GtkTextView放入GtkBox,然后放入GTKScrolledwindowo时,我无法工作。我需要把这个框放在GtkTextView和scrollbar之间,我不能不把整个东西放在另一个框中。在GtkScrolledWindow中使用GtkBox时,有没有办法保持自动滚动行为

以下代码说明了我的问题:

#include <gtk/gtk.h>

int main(int argc, char *argv[]) {
    GtkWidget *window;
    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size(GTK_WINDOW(window),
        gdk_screen_width()*0.5, gdk_screen_height()*0.5); 

    GtkWidget *main = gtk_box_new(0, 0);
    gtk_container_add(GTK_CONTAINER(window), main);
    /*/////////////////////////////////////////////////*/

    /* IMPORTANT PART */

    /* FIRST CASE (this one works correctly) */
    GtkWidget *scrolled_window_first = gtk_scrolled_window_new(NULL, NULL);
    GtkWidget *text_view_first = gtk_text_view_new();

    gtk_container_add(GTK_CONTAINER(scrolled_window_first), text_view_first);
    gtk_box_pack_start(GTK_BOX(main), scrolled_window_first, 1, 1, 0);

    /* SECOND CASE (there is no auto scroll which I need) */
    GtkWidget *scrolled_window_second = gtk_scrolled_window_new(NULL, NULL);
    GtkWidget *text_view_second = gtk_text_view_new();
    GtkWidget *box_from_second_example = gtk_box_new(0, 0);
    GtkWidget *example_box_before_scroller = gtk_box_new(0,0);

    GtkWidget *example_label = gtk_label_new("I need this box badly!");

    gtk_box_pack_start(GTK_BOX(box_from_second_example), text_view_second, 1, 1, 0);
    gtk_container_add(GTK_CONTAINER(scrolled_window_second), box_from_second_example);
    gtk_container_add(GTK_CONTAINER(box_from_second_example), example_box_before_scroller);
    gtk_box_pack_start(GTK_BOX(main), scrolled_window_second, 1, 1, 0);

    /* END IMPORTANT PART */

    /*/////////////////////////////////////////////////*/
    gtk_container_add(GTK_CONTAINER(example_box_before_scroller), example_label);
    g_signal_connect(GTK_WINDOW(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_widget_show_all(window);
    gtk_main ();

    return 0;
}
#包括
int main(int argc,char*argv[]){
GtkWidget*窗口;
gtk_init(&argc,&argv);
窗口=gtk_窗口_新建(gtk_窗口_顶层);
gtk_窗口设置默认大小(gtk_窗口(窗口),
gdk_屏幕宽度()*0.5,gdk_屏幕高度()*0.5);
GtkWidget*main=gtk_box_new(0,0);
gtk_容器添加(gtk_容器(窗口),主);
/*/////////////////////////////////////////////////*/
/*重要部分*/
/*第一种情况(这一种工作正常)*/
GtkWidget*滚动窗口\u first=gtk\u滚动窗口\u new(NULL,NULL);
GtkWidget*text_view_first=gtk_text_view_new();
gtk_容器添加(gtk_容器(先滚动窗口),先查看文本);
gtk_盒_包_开始(gtk_盒(主),滚动窗口_第一,1,1,0);
/*第二种情况(没有我需要的自动滚动)*/
GtkWidget*scrolled_window_second=gtk_scrolled_window_new(NULL,NULL);
GtkWidget*text_view_second=gtk_text_view_new();
GtkWidget*box_from_second_example=gtk_box_new(0,0);
GtkWidget*滚动条前的示例框=gtk框新(0,0);
GtkWidget*example_label=gtk_label_new(“我非常需要这个盒子!”);
gtk_-box_-pack_-start(gtk_-box(box_-from_-second_示例)、text_-view_-second、1、1、0);
gtk_容器添加(gtk_容器(滚动的第二个窗口),第二个示例中的框);
gtk_container_add(gtk_container(第二个示例中的框),滚动条前的示例框);
gtk_盒_包_开始(gtk_盒(主),滚动窗口_秒,1,1,0);
/*结束重要部分*/
/*/////////////////////////////////////////////////*/
gtk_容器添加(gtk_容器(滚动条前的示例框)、示例标签);
g_信号连接(GTK_窗口(窗口),“销毁”,g_回调(GTK_主退出),NULL);
gtk_小部件_全部显示(窗口);
gtk_main();
返回0;
}

您是否尝试修改文本视图默认创建的
gtkaadjustment
s(
GtkScrolledWindow
实现
GtkScrollable
afaik)

我认为最好的方法是检测插入到
GtkTextBuffer
(通过

GtkTextBuffer *     gtk_text_view_get_buffer            (GtkTextView *text_view);
并将回调(用于测试
\n
)挂接到其
插入文本
g\u信号并使用

void             gtk_adjustment_set_value            (GtkAdjustment *adjustment,
                                                      gdouble value);
修改滚动高度


请注意,这是未经测试的,一个更简单的方法可能即将出现。

问题是
GtkTextView
实现了
GtkScrollable
,但
GtkBox
没有。这不是一个小问题:如果您想采用
GtkBox
的方式,您应该将其放入这涉及到对整个事情如何滚动的深刻理解

无论如何,如果你足够懒,你也可以注意到
GtkTextview
是一个
GtkContainer
。换句话说,你可以在
GtkTextview
周围添加小部件,而无需修改
GtkBox
。这不完全是你想要的,但可能足够满足你的需要:

#include <gtk/gtk.h>                                                    

gint main(gint argc, gchar **argv)                                      
{                                                                       
    GtkWidget *window, *scrolled_window, *text_view, *label;            

    gtk_init(&argc, &argv);                                             

    text_view = gtk_text_view_new();                                    
    gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view)),
                             "1\n\n\n2\n\n\n3\n\n\n4\n\n\n5\n\n\n6\n\n\n7\n\n\n8", -1);
    /* Use this to set the size you want to reserve on the right */     
    gtk_text_view_set_border_window_size(GTK_TEXT_VIEW(text_view),      
                                         GTK_TEXT_WINDOW_RIGHT,         
                                         130);                          
    /* Add whatever you want instead of a GtkLabel */                   
    gtk_text_view_add_child_in_window(GTK_TEXT_VIEW(text_view),         
                                      gtk_label_new("You badly need this"),
                                      GTK_TEXT_WINDOW_RIGHT,            
                                      0, 0);                            

    scrolled_window = gtk_scrolled_window_new(NULL, NULL);              
    gtk_container_add(GTK_CONTAINER(scrolled_window), text_view);       

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);                       
    gtk_window_set_default_size(GTK_WINDOW(window), 320, 240);                                                                                                         
    gtk_container_add(GTK_CONTAINER(window), scrolled_window);          
    gtk_widget_show_all(window);                                        

    gtk_main ();                                                        

    return 0;                                                           
}                                                                       
#包括
gint干管(gint argc、gchar**argv)
{                                                                       
GtkWidget*窗口、*滚动窗口、*文本视图、*标签;
gtk_init(&argc,&argv);
text_view=gtk_text_view_new();
gtk_文本_缓冲区_设置_文本(gtk_文本_视图_获取_缓冲区(gtk_文本_视图(文本_视图)),
“1\n\n\n2\n\n\n3\n\n\n4\n\n\n5\n\n\n\n6\n\n\n\n7\n\n\n8”,-1);
/*使用此选项在右侧设置要保留的大小*/
gtk_文本_视图_设置_边框_窗口_大小(gtk_文本_视图(文本视图)),
GTK_文本_窗口_右侧,
130);                          
/*添加您想要的任何内容,而不是GtkLabel*/
gtk_文本视图在窗口中添加子视图(gtk_文本视图(文本视图)),
gtk_label_new(“您非常需要这个”),
GTK_文本_窗口_右侧,
0, 0);                            
scrolled_window=gtk_scrolled_window_new(NULL,NULL);
gtk_容器添加(gtk_容器(滚动窗口),文本视图);
窗口=gtk_窗口_新建(gtk_窗口_顶层);
gtk_窗口设置默认大小(gtk_窗口(窗口),320240);
gtk_容器添加(gtk_容器(窗口),滚动窗口);
gtk_小部件_全部显示(窗口);
gtk_main();
返回0;
}                                                                       

这很糟糕……添加的小部件不支持滚动,但保持在x=0,y=0……事实上,我甚至喜欢这种行为。也许这不是更好的选择,但在我的情况下更简单、更充分。感谢大家的帮助。我发现,如果你将框或任何可滚动元素放在里面,它会滚动。
#include <gtk/gtk.h>                                                    

gint main(gint argc, gchar **argv)                                      
{                                                                       
    GtkWidget *window, *scrolled_window, *text_view, *label;            

    gtk_init(&argc, &argv);                                             

    text_view = gtk_text_view_new();                                    
    gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view)),
                             "1\n\n\n2\n\n\n3\n\n\n4\n\n\n5\n\n\n6\n\n\n7\n\n\n8", -1);
    /* Use this to set the size you want to reserve on the right */     
    gtk_text_view_set_border_window_size(GTK_TEXT_VIEW(text_view),      
                                         GTK_TEXT_WINDOW_RIGHT,         
                                         130);                          
    /* Add whatever you want instead of a GtkLabel */                   
    gtk_text_view_add_child_in_window(GTK_TEXT_VIEW(text_view),         
                                      gtk_label_new("You badly need this"),
                                      GTK_TEXT_WINDOW_RIGHT,            
                                      0, 0);                            

    scrolled_window = gtk_scrolled_window_new(NULL, NULL);              
    gtk_container_add(GTK_CONTAINER(scrolled_window), text_view);       

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);                       
    gtk_window_set_default_size(GTK_WINDOW(window), 320, 240);                                                                                                         
    gtk_container_add(GTK_CONTAINER(window), scrolled_window);          
    gtk_widget_show_all(window);                                        

    gtk_main ();                                                        

    return 0;                                                           
}