Reputation: 671
I have an application that shows multiple subpanels & the client wants to show different menus for each subpanel.
Mac apps can only have one menuBar per system window, apparently, and it's minimally modifiable (if at all.) I need to remove/add or enable/disable menus on the menubar.
I've thought about making each of the subpanels a system window and attaching a menubar to each, but I don't see any provision for switching to a window's menubar. Besides, I suspect that doing so would create a state/positioning mess for the subpanels.
What I've Found
I've found that if I create the actions as children of the main window, I can add and remove them at will from the menus themselves. So, I can modify the menu contents, but I can't modify the menubar contents.
I've found I can also change the title of the menu to anything at any time. So, if I clear the contents and set the title to an empty string, it has the apparent effect of removing the menu (although it's still there and still highlights).
Barring another solution, have to do that, for now.
Is this possible at all on Mac? If I went down into Cocoa (don't know Cocoa), would I be able to maybe set up multiple menubars, or at least modify the menubar when the subpanel changes?
Upvotes: 0
Views: 2296
Reputation: 2741
Yes, this is possible in a Qt app, and fairly common. :)
In your app you probably have code to build your menus, and install them into the menubar (using QMenuBar) in the first place. As Juan correctly points out, to alter the menu bar, you can delete that instance and regenerate a new menubar and its menus as needed.
In my own code, I just keep my original QMenuBar around, and call QMenuBar::clear() on the instance. This is an alternative to the delete/re-instantiate that Juan recommends, although either approach is likely valid. Then I repopulate the menubar with the currently needed menus.
I typically only rebuild the whole QMenuBar when the set of top-level menus, or the title of a top-level menu needs to change. More commonly, I am dynamically regenerating the actual menu items (QActions) and/or their state (like their text, whether they are enabled or not, checked or not, etc) within a given menu.
To dynamically regenerate a single menu's contents only, you can connect a method callback to that particular QMenu's aboutToShow signal, and rebuild the menu's items dynamically within that callback (don't forget to start with QMenu::clear() on the instance or you may end up with duplicate items in the menu!). When the QMenu pops up, it will show your dynamically rebuilt items/states. This method also works for dynamic regeneration of popup/context menus.
Upvotes: 0
Reputation: 7222
I was searching something else but as precisely I've just been working this one, what I do is
- delete the current menuBar if there's one
- menuBar=new QMenuBar(0);
- menuBar->setNativeMenuBar(true);
And it seems to work fine. Just for what it's worth.
Upvotes: 2
Reputation:
A Cocoa application has only one menubar active at any given time, and you can modify and replace it. For instance, the (Cocoa) code below adds a new menu (with three items) to the menubar. It is also possible to edit and remove menus as well as menu items.
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]
returns the application menu. A new menu item is added to the main menu/menubar, representing a submenu that contains three items, one of them being a separator.
It is also possible to replace the menubar by crafting an appropriate menu and sending [NSApp setMainMenu:menubarReplacement]
.
Upvotes: 0