You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过PangoAttribute修改GtkText字体大小?解决更新与内存问题

问题修复方案

问题1:字体不即时更新的解决

原因:仅调用gtk_widget_queue_draw只会触发控件重绘,但GtkText需要重新计算文本布局以适配新字体大小。gtk_widget_queue_resize会触发控件重新布局并同步重绘,确保字体变化即时生效。

将原代码中的gtk_widget_queue_draw ((GtkWidget *)user_data);替换为:

gtk_widget_queue_resize ((GtkWidget *)user_data);

问题2:内存占用增长的解决

核心问题分析

  1. 属性参数错误:原代码中使用pango_attr_size_new_absolute时错误地乘以PANGO_SCALE——该函数接受像素值作为参数,无需额外缩放;PANGO_SCALE仅用于pango_attr_size_new(基于点数的字体大小设置)。
  2. 注释代码的隐性泄漏:若启用注释的(1)方案,gtk_text_get_attributes返回的属性列表必须手动调用pango_attr_list_unref释放,否则会导致内存泄漏。

修正后的属性设置逻辑

当前(2)方案的生命周期管理是正确的:pango_attr_list_insert会接管属性所有权,gtk_text_set_attributes会保留属性列表引用,调用pango_attr_list_unref不会导致泄漏。只需修正字体大小参数即可:

// 使用点数设置字体大小(跨设备适配性更好)
PangoAttribute *attrS = pango_attr_size_new (size * PANGO_SCALE);
// 若需基于像素设置,使用此行(无需乘PANGO_SCALE):
// PangoAttribute *attrS = pango_attr_size_new_absolute (size);

完整修复代码

#include <gtk/gtk.h>

void spinBtn_change_digits( GtkAdjustment *adj,  gpointer user_data)
{
  int size = gtk_adjustment_get_value (adj);
  printf("font Size spin:  %d\n", size);

  PangoAttrList *attrlist = pango_attr_list_new();
  // 基于点数设置字体大小(推荐)
  PangoAttribute *attrS = pango_attr_size_new (size * PANGO_SCALE);
  pango_attr_list_insert (attrlist, attrS);

  gtk_text_set_attributes ((GtkText *)user_data, attrlist);
  pango_attr_list_unref(attrlist);

  // 触发布局重计算+重绘,确保即时更新
  gtk_widget_queue_resize ((GtkWidget *)user_data);
}

static void
activate (GtkApplication* app,
          gpointer        user_data)
{
  GtkWidget *window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Window");
  // 调整窗口大小以完整显示控件
  gtk_window_set_default_size (GTK_WINDOW (window), 400, 100);

  GtkWidget *fixed = gtk_fixed_new ();
  gtk_window_set_child (GTK_WINDOW (window), fixed);

  GtkWidget *preview_text = gtk_text_new();
  gtk_editable_set_text ((GtkEditable *)preview_text, "The quick brown fox jumps over the lazy dog.");
  gtk_widget_set_size_request(preview_text, 245, 50);
  gtk_fixed_put (GTK_FIXED (fixed), preview_text, 0, 3);

  // 初始化字体大小(基于点数)
  PangoAttrList *attrLt = pango_attr_list_new();
  PangoAttribute *attrS = pango_attr_size_new (10 * PANGO_SCALE);
  pango_attr_list_insert (attrLt, attrS);
  gtk_text_set_attributes ((GtkText *)preview_text, attrLt);
  pango_attr_list_unref(attrLt);

  GtkAdjustment *spin_adj = gtk_adjustment_new  (10, 1, 200, 1, 5, 0.0); 
  GtkWidget *spin_btn = gtk_spin_button_new (spin_adj, 0.1, 0);
  gtk_widget_set_size_request(spin_btn, 110, 25);
  gtk_fixed_put (GTK_FIXED (fixed), spin_btn, 250, 3);
  g_signal_connect (spin_adj, "value_changed", G_CALLBACK (spinBtn_change_digits), preview_text);

  gtk_window_present (GTK_WINDOW (window));
}

int
main (int    argc,
      char **argv)
{
  GtkApplication *app;
  int status;
  #if GLIB_CHECK_VERSION(2, 74, 0)
      app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS); 
 #else
        app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE); 
  #endif
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}

内容的提问来源于stack exchange,提问作者dibyendu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 20:23:16