如何从含固定尺寸Widget的窗口获取缩小尺寸信号以触发重排?
解决方案
问题根源
窗口缩小时,原有行容器的最小宽度被内部固定尺寸的词块限制,导致窗口实际宽度无法缩小,因此notify::default-width信号(仅监听默认宽度变化)不会触发,自然无法触发重排。
具体修复步骤
替换信号绑定
放弃notify::default-width,改用监听窗口实际宽度变化的信号:- 如果使用GTK,绑定
notify::width信号,它会在窗口当前宽度(而非默认宽度)变化时触发; - 或者使用
size-allocate信号,该信号会在窗口尺寸分配完成后触发,更可靠。
示例代码(GTK):
// 替换原有notify::default-width绑定 g_signal_connect(window, "notify::width", G_CALLBACK(on_window_resize), NULL); // 或使用size-allocate g_signal_connect(window, "size-allocate", G_CALLBACK(on_window_size_allocate), NULL);- 如果使用GTK,绑定
动态调整窗口最小宽度
在重排函数中,完成词块重新布局后,计算所有行容器的最大宽度,将其设为窗口的最小宽度。这样窗口可以被缩小到新布局的最小宽度,不会被旧布局的行容器卡住:void on_window_resize(GtkWidget *window, GParamSpec *pspec, gpointer user_data) { gint current_width = gtk_widget_get_width(window); // 执行你的词块重排逻辑,根据current_width重新分配词块到行容器 rearrange_word_blocks(current_width); // 计算新布局的最小宽度(所有行中最宽的一行) gint min_width = 0; GList *rows = get_all_row_containers(); for (GList *l = rows; l != NULL; l = l->next) { GtkWidget *row = GTK_WIDGET(l->data); gint row_min, row_nat; gtk_widget_get_preferred_width(row, &row_min, &row_nat); if (row_min > min_width) { min_width = row_min; } } g_list_free(rows); // 更新窗口最小宽度,允许缩小到新的最小尺寸 gtk_widget_set_size_request(window, min_width, -1); }调整行容器布局属性
确保行容器不会强制扩展到窗口宽度导致最小宽度被锁定:- 将行容器的
hexpand设为FALSE,避免它强制占满窗口宽度; - 保持
halign为GTK_ALIGN_START,让行容器宽度由内部词块决定,而非窗口宽度。
- 将行容器的
原理说明
通过绑定实际宽度变化信号,确保窗口无论扩大还是缩小都会触发重排;动态调整窗口最小宽度,打破旧布局对窗口尺寸的限制;调整行容器属性,让其宽度随内容自适应,这样窗口缩小操作就能正常触发重排流程。
内容的提问来源于stack exchange,提问作者Oliver Cox
相关产品推荐
相关产品推荐

