如何通过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:内存占用增长的解决
核心问题分析
- 属性参数错误:原代码中使用
pango_attr_size_new_absolute时错误地乘以PANGO_SCALE——该函数接受像素值作为参数,无需额外缩放;PANGO_SCALE仅用于pango_attr_size_new(基于点数的字体大小设置)。 - 注释代码的隐性泄漏:若启用注释的(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
相关产品推荐
相关产品推荐

