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

Qooxdoo多窗口应用命令处理:工具栏按钮绑定GroupManager

问题描述

我想要创建一个包含Desktop和多个Window的Qooxdoo应用,Desktop(而非每个Window)拥有一个公共ToolBar。我需要实现一个“保存”命令,用于保存当前活动窗口的文档,该命令可通过快捷键“Ctrl+S”以及工具栏按钮触发。

为了让“Ctrl+S”触发当前活动窗口的命令,我已按照文档实现了qx.ui.command.GroupManager,但目前无法将工具栏保存按钮正确绑定到GroupManager,以使其调用当前活动窗口的保存命令。

以下是可在Qooxdoo Playground中运行的示例代码:

// NOTE: run this script only once. Before running it again you need to reload
// the page as it seems that the commands are accumulation and not reset.
// I guess that this is a bug in the Playground

const root = this.getRoot();

qx.Class.define('test.Application',
{
  extend : qx.application.Standalone,
  members: {
    main: function() {
      const layout = new qx.ui.layout.VBox(5);
      const container = new qx.ui.container.Composite(layout);
      root.add(container, {edge: 0});
      const windowManager = new qx.ui.window.Manager();
      const desktop = new qx.ui.window.Desktop(windowManager);

      this._manager = new qx.ui.command.GroupManager();
      
      const menuBar = new qx.ui.menubar.MenuBar();
      let menu = new qx.ui.menu.Menu();
      
      ///////////////////////////
      // TODO: Call _doSave() of the active window!
      let saveMenuButton = new qx.ui.menu.Button('Save','@MaterialIcons/save/16');
      ///////////////////////////
      
      menu.add(saveMenuButton);
      var fileMenu = new qx.ui.menubar.Button('File', null, menu);
      menuBar.add(fileMenu);
      const toolBar = new qx.ui.toolbar.ToolBar();
      
      ///////////////////////////
      // TODO: Call _doSave() of the active window!
      let saveToolBarButton = new qx.ui.toolbar.Button('Save','@MaterialIcons/save/16');
      ///////////////////////////
      
      toolBar.add(saveToolBarButton);
      container.add(menuBar,{flex:0});
      container.add(toolBar,{flex:0});
      container.add(desktop,{flex:1});
      
      this._foo1 = new test.Window('foo1', this);
      desktop.add(this._foo1);
      this._foo1.open();
      this._foo1.moveTo(100,20);
      
      this._foo2 = new test.Window('foo2', this);
      desktop.add(this._foo2);
      this._foo2.open();
      this._foo2.moveTo(200,100);

      this._foo3 = new test.Window('foo3', this);
      desktop.add(this._foo3);
      this._foo3.open();
      this._foo3.moveTo(300,180);
    },
    getGroupManager() {
      return this._manager;
    }
  }
});

qx.Class.define('test.Window', {
  extend: qx.ui.window.Window,
  construct(windowName, controller) {
    this.base(arguments, windowName);
    this._name = windowName;
    
    let commandGroup = new qx.ui.command.Group();
    const cmd = new qx.ui.command.Command("Ctrl+S");
    cmd.addListener('execute', this._doSave, this);
    commandGroup.add('save', cmd);
    controller.getGroupManager().add(commandGroup);
    this.addListener('changeActive', () => {
      if (this.isActive()) {
        controller.getGroupManager().setActive(commandGroup);
      }
    }, this);
  },
  members: {
    _doSave() {
      alert("save " + this._name);
    }
  }
});

a = new test.Application();

请问应如何设置saveMenuButton.setCommand()和saveToolBarButton.setCommand(),以确保它们始终调用活动窗口的命令?

解决方案

直接通过GroupManager的getCommand方法,获取当前激活组中名为save的命令并绑定给按钮即可。修改test.Application的main方法中对应的TODO部分:

// 菜单按钮绑定命令
let saveMenuButton = new qx.ui.menu.Button('Save','@MaterialIcons/save/16');
saveMenuButton.setCommand(this._manager.getCommand('save'));

// 工具栏按钮绑定命令
let saveToolBarButton = new qx.ui.toolbar.Button('Save','@MaterialIcons/save/16');
saveToolBarButton.setCommand(this._manager.getCommand('save'));

原理说明

  • GroupManager.getCommand('save')会返回当前激活命令组中对应名称的命令
  • 当窗口切换激活状态时,你已通过changeActive事件更新了GroupManager的激活组,此时按钮绑定的命令会自动切换为新激活窗口的保存命令
  • 无论是点击按钮还是按下Ctrl+S,都会触发当前激活窗口的_doSave方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:25:50