Gtk 当窗口最小化时,如何将滚动条自动滚动到底部

Gtk 当窗口最小化时,如何将滚动条自动滚动到底部,gtk,gtk2,Gtk,Gtk2,我正在从事一个项目,该项目必须在GTK-2.0中,我面临的问题是,如果窗口在最大化后最小化,滚动条将不再返回底部 下面是可以查看和测试的代码的一部分: #include <gtk/gtk.h> typedef struct { GtkWidget *entry; GtkWidget *textview; } Widgets; void chatMSG ( GtkButton *, Widgets * ); int main ( void ) { Gt

我正在从事一个项目,该项目必须在
GTK-2.0
中,我面临的问题是,如果窗口在最大化后最小化,滚动条将不再返回底部

下面是可以查看和测试的代码的一部分:

#include <gtk/gtk.h>

typedef struct
{
    GtkWidget *entry;
    GtkWidget *textview;
} Widgets;

void chatMSG ( GtkButton *, Widgets * );

int main ( void )
{
    GtkWidget *window, *scrolled_win, *hbox, *vbox, *button;
    Widgets *widg = g_slice_new ( Widgets );
    /// ***
    gtk_init ( NULL, NULL );
    /// ***
    window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
    g_signal_connect ( G_OBJECT ( window ), "delete_event", gtk_main_quit, NULL );
    gtk_window_set_title ( GTK_WINDOW ( window ), "WhatsChat" );
    gtk_container_set_border_width ( GTK_CONTAINER ( window ), 10 );
    gtk_widget_set_size_request ( window, 250, 200 );
    /// ***
    widg->textview = gtk_text_view_new();
    gtk_text_view_set_editable ( GTK_TEXT_VIEW ( widg->textview ), FALSE );
    gtk_text_view_set_cursor_visible ( GTK_TEXT_VIEW ( widg->textview ), FALSE );
    /// ***
    widg->entry = gtk_entry_new();
    button = gtk_button_new_with_label ( "Send" );
    /// ***
    g_signal_connect ( G_OBJECT ( button      ), "clicked",  G_CALLBACK ( chatMSG ), ( gpointer ) widg );
    g_signal_connect ( G_OBJECT ( widg->entry ), "activate", G_CALLBACK ( chatMSG ), ( gpointer ) widg );
    /// ***
    scrolled_win = gtk_scrolled_window_new ( NULL, NULL );
    gtk_widget_set_size_request ( scrolled_win, -1, 200 );
    gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scrolled_win ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
    gtk_container_add ( GTK_CONTAINER ( scrolled_win ), widg->textview );
    /// ***
    hbox = gtk_hbox_new ( FALSE, 5 );
    gtk_box_pack_start_defaults ( GTK_BOX ( hbox ), widg->entry );
    gtk_box_pack_start_defaults ( GTK_BOX ( hbox ), button );
    /// ***
    vbox = gtk_vbox_new ( FALSE, 5 );
    gtk_box_pack_start ( GTK_BOX ( vbox ), scrolled_win, TRUE, TRUE, 0 );
    gtk_box_pack_start ( GTK_BOX ( vbox ), hbox, FALSE, TRUE, 0 );
    /// ***
    gtk_container_add ( GTK_CONTAINER ( window ), vbox );
    gtk_widget_show_all ( window );
    gtk_main();
}

void chatMSG ( GtkButton *button, Widgets *widg )
{
    ( void ) button;
    GtkTextBuffer *buffer;
    GtkTextMark *mark;
    GtkTextIter iter, start, end;
    const gchar *text;
    /// ***
    buffer = gtk_text_view_get_buffer ( GTK_TEXT_VIEW ( widg->textview ) );
    text   = gtk_entry_get_text ( GTK_ENTRY ( widg->entry ) );
    /// ***
    mark = gtk_text_buffer_get_insert ( buffer );
    gtk_text_buffer_get_iter_at_mark ( buffer, &iter, mark );
    gtk_text_buffer_get_bounds ( buffer, &start, &end );

    if (  gtk_text_buffer_get_char_count ( buffer ) && strlen( text ) > 0 )
    {
        gtk_text_buffer_insert ( buffer, &iter, "\n", -1 );
    }

    gtk_text_buffer_insert ( buffer, &iter, text, -1 );
    gtk_entry_set_text ( GTK_ENTRY ( widg->entry ), "" );
    /// ***
    mark = gtk_text_buffer_create_mark ( buffer, NULL, &iter, FALSE );
    gtk_text_view_scroll_mark_onscreen ( GTK_TEXT_VIEW ( widg->textview ), mark );
    gtk_text_buffer_delete_mark ( buffer, mark );
}

但它也不起作用。

经过大量搜索并尝试了不同的东西,但这些都没有帮助,我通过搜索“帮助”并设法修复了它

我决定把这个分享给两个人,因为这对以后的其他人也有帮助。 以下是一个工作示例:

#include <gtk/gtk.h>

typedef struct
{
    GtkWidget *entry;
    GtkWidget *textview;
} Widgets;

void chatMSG ( GtkButton *, Widgets * );
void scroll_value_changed ( GtkAdjustment *adjustment, gpointer user_data );
void scroll_bottom_gravity ( GtkWidget    *scrolled_window, gpointer user_data );

int main ( void )
{
    GtkWidget *window, *scrolled_win, *hbox, *vbox, *button;
    Widgets *widg = g_slice_new ( Widgets );
    double from_bottom = 0.0;
    /// ***
    gtk_init ( NULL, NULL );
    /// ***
    window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
    g_signal_connect ( G_OBJECT ( window ), "delete_event", gtk_main_quit, NULL );
    gtk_window_set_title ( GTK_WINDOW ( window ), "WhatsChat" );
    gtk_container_set_border_width ( GTK_CONTAINER ( window ), 10 );
    gtk_widget_set_size_request ( window, 250, 200 );
    /// ***
    widg->textview = gtk_text_view_new();
    gtk_text_view_set_editable ( GTK_TEXT_VIEW ( widg->textview ), FALSE );
    gtk_text_view_set_cursor_visible ( GTK_TEXT_VIEW ( widg->textview ), FALSE );
    /// ***
    widg->entry = gtk_entry_new();
    button = gtk_button_new_with_label ( "Send" );
    /// ***
    g_signal_connect ( G_OBJECT ( button      ), "clicked",  G_CALLBACK ( chatMSG ), ( gpointer ) widg );
    g_signal_connect ( G_OBJECT ( widg->entry ), "activate", G_CALLBACK ( chatMSG ), ( gpointer ) widg );
    /// ***
    scrolled_win = gtk_scrolled_window_new ( NULL, NULL );
    gtk_widget_set_size_request ( scrolled_win, -1, 200 );
    gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scrolled_win ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
    GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment ( GTK_SCROLLED_WINDOW ( scrolled_win ) );
    g_signal_connect ( scrolled_win, "size-allocate", ( GCallback ) scroll_bottom_gravity, &from_bottom );
    g_signal_connect ( adjustment, "value-changed", ( GCallback ) scroll_value_changed, &from_bottom );
    gtk_container_add ( GTK_CONTAINER ( scrolled_win ), widg->textview );
    /// ***
    hbox = gtk_hbox_new ( FALSE, 5 );
    gtk_box_pack_start_defaults ( GTK_BOX ( hbox ), widg->entry );
    gtk_box_pack_start_defaults ( GTK_BOX ( hbox ), button );
    /// ***
    vbox = gtk_vbox_new ( FALSE, 5 );
    gtk_box_pack_start ( GTK_BOX ( vbox ), scrolled_win, TRUE, TRUE, 0 );
    gtk_box_pack_start ( GTK_BOX ( vbox ), hbox, FALSE, TRUE, 0 );
    /// ***
    gtk_container_add ( GTK_CONTAINER ( window ), vbox );
    gtk_widget_show_all ( window );
    gtk_main();
}

void chatMSG ( GtkButton *button, Widgets *widg )
{
    ( void ) button;
    GtkTextMark *mark;
    GtkTextIter iter;
    /// ***
    GtkTextBuffer *buffer = gtk_text_view_get_buffer ( GTK_TEXT_VIEW ( widg->textview ) );
    const gchar *text     = gtk_entry_get_text ( GTK_ENTRY ( widg->entry ) );
    /// ***
    mark = gtk_text_buffer_get_insert ( buffer );
    gtk_text_buffer_get_iter_at_mark ( buffer, &iter, mark );

    if (  gtk_text_buffer_get_char_count ( buffer ) && strlen ( text ) > 0 )
    {
        gtk_text_buffer_insert ( buffer, &iter, "\n", -1 );
    }

    gtk_text_buffer_insert ( buffer, &iter, text, -1 );
    gtk_entry_set_text ( GTK_ENTRY ( widg->entry ), "" );
}

void scroll_bottom_gravity ( GtkWidget *scrolled_window,  gpointer user_data )
{
    GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment ( GTK_SCROLLED_WINDOW ( scrolled_window ) );
    double *from_bottom = user_data;
    double upper = gtk_adjustment_get_upper ( adjustment );
    double page_size = gtk_adjustment_get_page_size ( adjustment );
    gtk_adjustment_set_value ( adjustment, upper - page_size - *from_bottom );
}

void scroll_value_changed ( GtkAdjustment *adjustment, gpointer user_data )
{
    double *from_bottom = user_data;
    double value = gtk_adjustment_get_value ( adjustment );
    double upper = gtk_adjustment_get_upper ( adjustment );
    double page_size = gtk_adjustment_get_page_size ( adjustment );
    *from_bottom = upper - page_size - value;
}
#包括
类型定义结构
{
GtkWidget*条目;
GtkWidget*文本视图;
}小部件;
void chatMSG(GtkButton*,Widgets*);
无效滚动值更改(GTK调整*调整,gpointer用户数据);
无效滚动底部重力(GtkWidget*滚动窗口,gpointer用户数据);
内部主(空)
{
GtkWidget*窗口、*滚动窗口、*hbox、*vbox、*按钮;
Widgets*widg=g_slice_new(Widgets);
从底部开始加倍=0.0;
/// ***
gtk_init(NULL,NULL);
/// ***
窗口=gtk_窗口_新建(gtk_窗口_顶层);
g_信号连接(g_对象(窗口),“删除事件”,gtk_主退出,空);
gtk_窗口设置标题(gtk_窗口(窗口),“WhatsChat”);
gtk_容器_设置_边框_宽度(gtk_容器(窗口),10);
gtk_小部件_设置_大小_请求(窗口,250200);
/// ***
widg->textview=gtk_text_view_new();
gtk_文本_视图_设置_可编辑(gtk_文本_视图(widg->textview),FALSE);
gtk_文本_视图_设置_光标_可见(gtk_文本_视图(widg->textview),FALSE);
/// ***
widg->entry=gtk_entry_new();
按钮=gtk_按钮_新建_,带有_标签(“发送”);
/// ***
g_信号连接(g_对象(按钮),“单击”,g_回调(chatMSG),(gpointer)widg);
g_信号连接(g_对象(widg->entry),“激活”,g_回调(chatMSG),(gpointer)widg);
/// ***
scrolled_win=gtk_scrolled_window_new(NULL,NULL);
gtk_widget_set_size_request(滚动的_win,-1200);
gtk_滚动_窗口_设置_策略(gtk_滚动_窗口(滚动_赢)、gtk_策略_自动、gtk_策略_自动);
gtk调整*调整=gtk滚动窗口获取调整(gtk滚动窗口(滚动窗口));
g_信号_连接(滚动的_win、“大小分配”、(GCallback)滚动的_bottom_gravity和from_bottom);
g_信号_连接(调整,“值更改”,(GCallback)滚动_值_更改,&从底部开始);
gtk_container_add(gtk_container(滚动的_win),widg->textview);
/// ***
hbox=gtk_hbox_新(假,5);
gtk_-box_-pack_-start_默认值(gtk_-box(hbox),widg->entry);
gtk_盒\包装\启动\默认值(gtk_盒(hbox),按钮);
/// ***
vbox=gtk_vbox_new(假,5);
gtk_-box_-pack_-start(gtk_-box(vbox)),滚动_-win,TRUE,TRUE,0;
gtk_-box_-pack_-start(gtk_-box(vbox),hbox,FALSE,TRUE,0);
/// ***
gtk_容器添加(gtk_容器(窗口),vbox);
gtk_小部件_全部显示(窗口);
gtk_main();
}
void chatMSG(GtkButton*按钮,Widgets*widg)
{
(作废)按钮;
GtkTextMark*标记;
GtkTextIter国际热核实验堆;
/// ***
GtkTextBuffer*buffer=gtk_text_view_get_buffer(gtk_text_view(widg->textview));
const gchar*text=gtk_entry\u get_text(gtk_entry(widg->entry));
/// ***
标记=gtk_文本_缓冲区_获取_插入(缓冲区);
gtk_text_buffer_get_iter_at_mark(buffer,&iter,mark);
如果(gtk_text_buffer_get_char_count(buffer)&&strlen(text)>0)
{
gtk文本缓冲区插入(缓冲区和iter,“\n”,-1);
}
gtk_text_buffer_insert(buffer,&iter,text,-1);
gtk_条目设置文本(gtk_条目(widg->条目),“”);
}
无效滚动\底部\重力(GtkWidget*滚动\窗口,gpointer用户\数据)
{
gtk调整*调整=gtk滚动窗口获取调整(gtk滚动窗口(滚动窗口));
double*from_bottom=用户_数据;
双上=gtk_调整_获得_上(调整);
双页面大小=gtk页面调整页面大小(调整);
gtk_调整_设置_值(调整,上部-页面大小-*自底部);
}
无效滚动值更改(GTK调整*调整,gpointer用户数据)
{
double*from_bottom=用户_数据;
双值=gtk_调整_获取_值(调整);
双上=gtk_调整_获得_上(调整);
双页面大小=gtk页面调整页面大小(调整);
*from_bottom=上限-页面大小-值;
}

这个问题是否特定于linux API?它与gcc有什么关系?我建议删除这些标记。@这是一个关于使用
GCC
编译的
Linux
上使用的
GTK
的问题。作为旁注,GTK+2不应在新项目中使用。GTK+3多年来一直是稳定的版本,一旦今年晚些时候发布GTK+4,对GTK+2的支持将完全停止(甚至是安全问题)。帮你自己一个忙,使用GTK+3,并将此信息转发给要求你使用GTK+2进行编码的人。@liberforce我已经准备好使用
GTK4
,但我在
GTK2
中需要它。请不要问为什么:)
#include <gtk/gtk.h>

typedef struct
{
    GtkWidget *entry;
    GtkWidget *textview;
} Widgets;

void chatMSG ( GtkButton *, Widgets * );
void scroll_value_changed ( GtkAdjustment *adjustment, gpointer user_data );
void scroll_bottom_gravity ( GtkWidget    *scrolled_window, gpointer user_data );

int main ( void )
{
    GtkWidget *window, *scrolled_win, *hbox, *vbox, *button;
    Widgets *widg = g_slice_new ( Widgets );
    double from_bottom = 0.0;
    /// ***
    gtk_init ( NULL, NULL );
    /// ***
    window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
    g_signal_connect ( G_OBJECT ( window ), "delete_event", gtk_main_quit, NULL );
    gtk_window_set_title ( GTK_WINDOW ( window ), "WhatsChat" );
    gtk_container_set_border_width ( GTK_CONTAINER ( window ), 10 );
    gtk_widget_set_size_request ( window, 250, 200 );
    /// ***
    widg->textview = gtk_text_view_new();
    gtk_text_view_set_editable ( GTK_TEXT_VIEW ( widg->textview ), FALSE );
    gtk_text_view_set_cursor_visible ( GTK_TEXT_VIEW ( widg->textview ), FALSE );
    /// ***
    widg->entry = gtk_entry_new();
    button = gtk_button_new_with_label ( "Send" );
    /// ***
    g_signal_connect ( G_OBJECT ( button      ), "clicked",  G_CALLBACK ( chatMSG ), ( gpointer ) widg );
    g_signal_connect ( G_OBJECT ( widg->entry ), "activate", G_CALLBACK ( chatMSG ), ( gpointer ) widg );
    /// ***
    scrolled_win = gtk_scrolled_window_new ( NULL, NULL );
    gtk_widget_set_size_request ( scrolled_win, -1, 200 );
    gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scrolled_win ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
    GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment ( GTK_SCROLLED_WINDOW ( scrolled_win ) );
    g_signal_connect ( scrolled_win, "size-allocate", ( GCallback ) scroll_bottom_gravity, &from_bottom );
    g_signal_connect ( adjustment, "value-changed", ( GCallback ) scroll_value_changed, &from_bottom );
    gtk_container_add ( GTK_CONTAINER ( scrolled_win ), widg->textview );
    /// ***
    hbox = gtk_hbox_new ( FALSE, 5 );
    gtk_box_pack_start_defaults ( GTK_BOX ( hbox ), widg->entry );
    gtk_box_pack_start_defaults ( GTK_BOX ( hbox ), button );
    /// ***
    vbox = gtk_vbox_new ( FALSE, 5 );
    gtk_box_pack_start ( GTK_BOX ( vbox ), scrolled_win, TRUE, TRUE, 0 );
    gtk_box_pack_start ( GTK_BOX ( vbox ), hbox, FALSE, TRUE, 0 );
    /// ***
    gtk_container_add ( GTK_CONTAINER ( window ), vbox );
    gtk_widget_show_all ( window );
    gtk_main();
}

void chatMSG ( GtkButton *button, Widgets *widg )
{
    ( void ) button;
    GtkTextMark *mark;
    GtkTextIter iter;
    /// ***
    GtkTextBuffer *buffer = gtk_text_view_get_buffer ( GTK_TEXT_VIEW ( widg->textview ) );
    const gchar *text     = gtk_entry_get_text ( GTK_ENTRY ( widg->entry ) );
    /// ***
    mark = gtk_text_buffer_get_insert ( buffer );
    gtk_text_buffer_get_iter_at_mark ( buffer, &iter, mark );

    if (  gtk_text_buffer_get_char_count ( buffer ) && strlen ( text ) > 0 )
    {
        gtk_text_buffer_insert ( buffer, &iter, "\n", -1 );
    }

    gtk_text_buffer_insert ( buffer, &iter, text, -1 );
    gtk_entry_set_text ( GTK_ENTRY ( widg->entry ), "" );
}

void scroll_bottom_gravity ( GtkWidget *scrolled_window,  gpointer user_data )
{
    GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment ( GTK_SCROLLED_WINDOW ( scrolled_window ) );
    double *from_bottom = user_data;
    double upper = gtk_adjustment_get_upper ( adjustment );
    double page_size = gtk_adjustment_get_page_size ( adjustment );
    gtk_adjustment_set_value ( adjustment, upper - page_size - *from_bottom );
}

void scroll_value_changed ( GtkAdjustment *adjustment, gpointer user_data )
{
    double *from_bottom = user_data;
    double value = gtk_adjustment_get_value ( adjustment );
    double upper = gtk_adjustment_get_upper ( adjustment );
    double page_size = gtk_adjustment_get_page_size ( adjustment );
    *from_bottom = upper - page_size - value;
}