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

如何从含固定尺寸Widget的窗口获取缩小尺寸信号以触发重排?

解决方案

问题根源

窗口缩小时,原有行容器的最小宽度被内部固定尺寸的词块限制,导致窗口实际宽度无法缩小,因此notify::default-width信号(仅监听默认宽度变化)不会触发,自然无法触发重排。

具体修复步骤

  1. 替换信号绑定
    放弃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);
    
  2. 动态调整窗口最小宽度
    在重排函数中,完成词块重新布局后,计算所有行容器的最大宽度,将其设为窗口的最小宽度。这样窗口可以被缩小到新布局的最小宽度,不会被旧布局的行容器卡住:

    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);
    }
    
  3. 调整行容器布局属性
    确保行容器不会强制扩展到窗口宽度导致最小宽度被锁定:

    • 将行容器的hexpand设为FALSE,避免它强制占满窗口宽度;
    • 保持halign为GTK_ALIGN_START,让行容器宽度由内部词块决定,而非窗口宽度。

原理说明

通过绑定实际宽度变化信号,确保窗口无论扩大还是缩小都会触发重排;动态调整窗口最小宽度,打破旧布局对窗口尺寸的限制;调整行容器属性,让其宽度随内容自适应,这样窗口缩小操作就能正常触发重排流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:25:17