Когда обновляется предпочтительный размер GtkTextView? - PullRequest
0 голосов
/ 28 марта 2020

Я заметил, что предпочтительный размер GtkTextView изменяется не сразу после изменения его содержимого, а только спустя некоторое время при обработке событий.

В следующем примере, когда вы нажимаете кнопку, текст в GtkTextView обновляется через gtk_text_buffer_set_text (). Новый текст достаточно длинный, чтобы вызвать перенос строки, поэтому предпочтительная высота элемента управления должна измениться. Но gtk_widget_get_preferred_size () все еще сообщает о старой предпочтительной высоте. Позже, в обработчике события size-allocate, gtk_widget_get_preferred_size () уже сообщает о правильном размере для нового содержимого.

Я пытаюсь понять, что происходит между возвратом из обработчика события clicked кнопки и размером -allocate 'обработчик события, который вызывает изменение предпочтительного размера 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
...