【问题标题】:Qt Mac multiple menubars/modifiable menubarQt Mac 多个菜单栏/可修改的菜单栏
【发布时间】:2011-01-05 19:31:52
【问题描述】:

我有一个显示多个子面板的应用程序,客户希望为每个子面板显示不同的菜单。

显然,Mac 应用程序的每个系统窗口只能有一个 menuBar,而且它的可修改性极低(如果有的话)。我需要删除/添加或启用/禁用菜单栏上的菜单。

我考虑过让每个子面板成为系统窗口并为每个子面板附加一个菜单栏,但我没有看到任何切换到窗口菜单栏的规定。此外,我怀疑这样做会给子面板造成状态/定位混乱。

我发现了什么

我发现如果我将动作创建为主窗口的子窗口,我可以从菜单本身随意添加和删除它们。所以,我可以修改菜单内容,但不能修改菜单栏内容。

我发现我也可以随时将菜单的标题更改为任何内容。所以,如果我清除内容并将标题设置为一个空字符串,它具有删除菜单的明显效果(尽管它仍然存在并且仍然突出显示)。

除非有其他解决方案,否则现在必须这样做。

这在 Mac 上是否可行?如果我进入 Cocoa(不知道 Cocoa),我是否可以设置多个菜单栏,或者至少在子面板更改时修改菜单栏?

【问题讨论】:

  • 将标题设置为空字符串可能对于单个菜单是可以的,但如果您设置空字符串的菜单是多个并且彼此相邻,那么您将获得相当大的空间。

标签: qt macos menubar


【解决方案1】:

我正在寻找其他东西,但正如我刚刚在做这个,我所做的是

- delete the current menuBar if there's one
- menuBar=new QMenuBar(0);
- menuBar->setNativeMenuBar(true);

而且它似乎工作正常。只是为了它的价值。

【讨论】:

    【解决方案2】:

    一个 Cocoa 应用程序在任何给定时间只有一个菜单栏处于活动状态,您可以修改和替换它。例如,下面的 (Cocoa) 代码向菜单栏添加了一个新菜单(包含三个项目)。也可以编辑和删除菜单以及菜单项。

    NSMenu *menubar = [NSApp mainMenu];
    
    NSMenuItem *newBarMenuItem = [[[NSMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:@""] autorelease];
    NSMenu *newMenu = [[[NSMenu alloc] initWithTitle:@"New Menu"] autorelease];
    
    NSMenuItem *menuItem1 = [[[NSMenuItem alloc] initWithTitle:@"Action 1" action:@selector(action1:) keyEquivalent:@""] autorelease];
    NSMenuItem *menuItem2 = [[[NSMenuItem alloc] initWithTitle:@"Action 2" action:@selector(action2:) keyEquivalent:@""] autorelease];
    
    [newMenu addItem:menuItem1];
    [newMenu addItem:[NSMenuItem separatorItem]];
    [newMenu addItem:menuItem2];
    
    [menubar addItem:newBarMenuItem];
    [menubar setSubmenu:newMenu forItem:newBarMenuItem];
    

    [NSApp mainMenu] 返回应用程序菜单。一个新的菜单项被添加到主菜单/菜单栏,代表一个包含三个项目的子菜单,其中一个是分隔符。

    也可以通过制作适当的菜单并发送[NSApp setMainMenu:menubarReplacement]来替换菜单栏。

    【讨论】:

    • 这个答案是很好的信息,但并没有真正解决 Qt 这样做的方法。但是,正如这个答案正确指出的那样,您可以动态更改 QT 应用程序中的菜单栏——我将尝试在单独的答案中更具体。
    【解决方案3】:

    是的,这在 Qt 应用程序中是可能的,而且相当普遍。 :)

    在您的应用程序中,您可能拥有构建菜单的代码,并首先将它们安装到菜单栏中(使用 QMenuBar)。正如 Juan 正确指出的那样,要更改菜单栏,您可以删除该实例并根据需要重新生成新的菜单栏及其菜单。

    在我自己的代码中,我只是保留了我原来的 QMenuBar,并在实例上调用 QMenuBar::clear()。这是 Juan 建议的删除/重新实例化的替代方法,尽管这两种方法都可能有效。然后我用当前需要的菜单重新填充菜单栏。

    我通常只在顶级菜单集或顶级菜单的标题需要更改时重建整个 QMenuBar。更常见的是,我在给定的菜单中动态地重新生成实际的菜单项(QActions)和/或它们的状态(比如它们的文本,它们是否启用、检查与否等)。

    要仅动态重新生成单个菜单的内容,您可以将方法回调连接到该特定 QMenu 的 aboutToShow 信号,并在该回调中动态重建菜单的项目(不要忘记从 QMenu::clear() 开始实例,否则您最终可能会在菜单中看到重复的项目!)。当 QMenu 弹出时,它将显示您动态重建的项目/状态。此方法也适用于弹出/上下文菜单的动态重新生成。

    【讨论】:

    • 稍微偏离主题...如果您想阻止在编辑菜单中添加特定于 OSX 的项目(假设您有一个),请在创建 QMenu 时在“E”之前放置一个空格. IE 使用“编辑”,而不是“编辑”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    • 2011-11-18
    • 1970-01-01
    • 2020-12-27
    相关资源
    最近更新 更多