如何用Qooxdoo创建响应式可调整Window:空间不足时隐藏组件
Qooxdoo 实现可自适应隐藏组件的可调大小窗口
核心需求实现
要创建满足要求的窗口,我们需要结合Qooxdoo的布局系统、组件可见性控制和窗口resize事件监听,按优先级隐藏组件,同时保证窗口最小宽度为核心组件的宽度。
完整代码示例
// 应用入口类示例 qx.Class.define("myapp.Application", { extend: qx.application.Standalone, members: { main: function() { this.base(arguments); // 1. 创建可调大小的窗口 const win = new qx.ui.window.Window("自适应组件窗口"); win.set({ width: 600, height: 120, allowResize: true, layout: new qx.ui.layout.HBox({ alignY: "middle", spacing: 10 }) }); this.getRoot().add(win, { left: 50, top: 50 }); win.open(); // 2. 创建各组件(处理附加问题:用Composite实现标签与核心组件垂直居中) // 核心组件:must have(优先级最高) const mustHaveComponent = new qx.ui.basic.Label("must have"); mustHaveComponent.set({ padding: [10, 15], backgroundColor: "#e0e0e0" // 高亮显示方便观察 }); // 附属标签:unimportant(优先级最低) const unimportantLabel = new qx.ui.basic.Label("unimportant"); // 包裹标签与核心组件,实现垂直居中对齐 const mustHaveContainer = new qx.ui.container.Composite( new qx.ui.layout.HBox({ gap: 5, alignY: "middle" }) ); mustHaveContainer.add(unimportantLabel); mustHaveContainer.add(mustHaveComponent); // 次要重要组件:very important(优先级中等) const veryImportantLabel = new qx.ui.basic.Label("very important"); // 3. 将组件加入窗口HBox,分配空间权重 win.add(veryImportantLabel, { flex: 1 }); // 占据左侧剩余空间 win.add(new qx.ui.core.Spacer(), { flex: 2 }); // 占据中间大部分额外空间,保证右侧组件靠右 win.add(mustHaveContainer); // 4. 计算各组件最小宽度,设置窗口最小限制 const minWidthVeryImportant = veryImportantLabel.getSizeHint().width; const minWidthUnimportant = unimportantLabel.getSizeHint().width; const minWidthMustHave = mustHaveComponent.getSizeHint().width; const minWidthMustHaveContainer = minWidthUnimportant + minWidthMustHave + 5; // 5是gap const totalMinFull = minWidthVeryImportant + minWidthMustHaveContainer; const totalMinWithoutUnimportant = minWidthVeryImportant + minWidthMustHave; const totalMinOnlyMustHave = minWidthMustHave; // 设置窗口最小宽度为核心组件的最小宽度 win.setMinWidth(totalMinOnlyMustHave); // 5. 监听窗口resize事件,动态控制组件可见性 win.addListener("resize", (e) => { const availableWidth = e.getData().width; // 默认显示所有组件 veryImportantLabel.show(); unimportantLabel.show(); // 按优先级判断隐藏逻辑 if (availableWidth < totalMinFull) { // 空间不足,先隐藏unimportant标签 unimportantLabel.exclude(); if (availableWidth < totalMinWithoutUnimportant) { // 空间仍不足,隐藏very important标签 veryImportantLabel.exclude(); } } }); } } });
关键逻辑说明
- 窗口配置:通过
allowResize: true开启窗口调整功能,minWidth绑定核心组件的最小宽度,防止窗口缩到无法显示核心内容。 - 布局与空间分配:
- HBox布局的
alignY: "middle"保证所有组件垂直居中。 - 给
veryImportantLabel和中间的Spacer设置flex属性,让额外空间优先分配给左侧区域,确保右侧的mustHaveContainer始终靠右,符合示例中的对齐要求。
- HBox布局的
- 组件可见性控制:
- 监听窗口
resize事件,根据当前可用宽度与各组件组合的最小宽度对比,按优先级隐藏组件:先藏unimportant,再藏very important,最后保留must have。 - 使用
exclude()而非hide(),因为exclude()会让组件完全不参与布局计算,更符合空间不足时的隐藏需求。
- 监听窗口
- 附加问题处理:
- 用
Composite(或Atom,如果是图标+文本场景)包裹unimportant标签和must have组件,通过alignY: "middle"实现两者垂直居中对齐,即使must have组件高度变化也能保持对齐。
- 用
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

