GtkTextView の優先サイズは、内容が変更された直後には変更されず、イベント処理の後でのみ変更されることに気付きました。
次の例では、ボタンをクリックすると、GtkTextView のテキストが gtk_text_buffer_set_text() によって更新されます。新しいテキストは、改行を引き起こすのに十分な長さであるため、コントロールの適切な高さを変更する必要があります。しかし、gtk_widget_get_preferred_size() はまだ古い推奨高さを報告します。その後、'size-allocate' イベント ハンドラーで、gtk_widget_get_preferred_size() は既に新しいコンテンツの正しいサイズを報告しています。
ボタンの「クリックされた」イベントハンドラーからの戻りと「サイズ割り当て」イベントハンドラーの間で何が起こるかを理解しようとしています。これにより、GtkTextView の優先サイズが更新され、変更されたコンテンツが反映されます。
#include <gtk/gtk.h>
static bool button_clicked(GtkWidget* obj, GtkWidget* view)
{
// set text in GtkTextView to
const char* long_text="aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa aaaaa";
printf("----------------------------\n");
printf("in button_clicked(): setting text\n");
GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
gtk_text_buffer_set_text(buffer, long_text, -1);
GtkRequisition req;
gtk_widget_get_preferred_size(view, &req, NULL);
printf("in button_clicked(): preferred height = %u\n", req.height);
return false;
}
static bool on_size_allocate(GtkWidget* obj, GdkRectangle *allocation, GtkWidget* view)
{
GtkRequisition req;
gtk_widget_get_preferred_size(view, &req, NULL);
printf("in on_size_allocate(): preferred height = %u\n", req.height);
return false;
}
static void activate(GtkApplication* app, gpointer user_data)
{
GtkWidget *window;
window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW (window), "Wrapped text");
gtk_window_set_default_size(GTK_WINDOW (window), 200, 200);
gtk_widget_show_all(window);
GtkTextBuffer* buffer = gtk_text_buffer_new(NULL);
GtkWidget* view = GTK_WIDGET(gtk_text_view_new_with_buffer(buffer));
g_object_unref(buffer);
gtk_widget_set_size_request(view, 180, -1);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD_CHAR);
g_signal_connect(view, "size-allocate", G_CALLBACK(on_size_allocate), view);
GtkWidget *button = gtk_button_new_with_label("Set Text");
g_signal_connect(button, "clicked", G_CALLBACK(button_clicked), view);
GtkWidget* grid = gtk_grid_new();
gtk_container_add(GTK_CONTAINER(window), grid);
gtk_grid_attach(GTK_GRID(grid), button, 0, 0, 1, 1);
gtk_grid_attach(GTK_GRID(grid), view, 0, 1, 1, 1);
gtk_widget_show_all(window);
}
int main (int argc, char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
これは次のように表示されます。
in on_size_allocate(): preferred height = 17
----------------------------
in button_clicked(): setting text
in button_clicked(): preferred height = 17
in on_size_allocate(): preferred height = 34