Qt 5.8 : Main menu items disabled in OSX
-
Well, there's a mess with the parentless menuBar, you need to recreate it each time you create a new window:
int main(int argc, char *argv[]) { Application app(argc, argv); app.setQuitOnLastWindowClosed(false); // create a menubar for OSX only, when no window was opened app.createMenuBar(); QMainWindow* win=new QMainWindow; win->setAttribute(Qt::WA_DeleteOnClose); win->setMenuBar(app.createMenuBar()); // create menubar for this window win->show(); app.createMenuBar(); // recreate QMainWindow* win2=new QMainWindow; win2->setAttribute(Qt::WA_DeleteOnClose); win2->setMenuBar(app.createMenuBar()); // create menubar for this window win2->show(); app.createMenuBar(); // recreate return app.exec();
}
Now the quit menu is active in all cases: if you close the first window or the two windows.
Regardless this bug, the submenu issue seems unrelated, if I add the following in the createMenuBar:
action=menu->addAction(tr("Open Recent")); action->setMenu(new QMenu(menuBar)); action->menu()->setEnabled(true);
The submenu Open Recent is disabled.
In Qt 5.6.1/5.7.1 it's enabled.Referring to the bug report QTBUG-54845, it seems the patch was not apply to 5.8, right ?
-
From the bug report the fix has been applied to 5.6.2 so it's also valid for further versions of Qt.
It seems we have here something new.
-
I guess I have the same or very similar problem. During my research I have found a few interesting examples. And while I am unable to reproduce in example disabled submenu items, I think it still may be useful. I had disabled submenu items in my code, just can't reproduce here, my application code is huge.
It seems like a problem is in application initialization order.
This works well:int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget w; w.setContextMenuPolicy(Qt::CustomContextMenu); w.show(); QMenuBar *m = new QMenuBar(nullptr); QMenu *edit_menu = m->addMenu("Edit"); edit_menu->addAction("One"); QMenu *file_menu = m->addMenu("File"); file_menu->addAction("File One"); QMenu *sub_menu = new QMenu("SubMenu", file_menu); sub_menu->addAction("File Two"); QAction *another_sub_menu_action = new QAction("SubMenu2", file_menu); another_sub_menu_action->setMenu(sub_menu); file_menu->addAction(sub_menu->menuAction()); return a.exec(); }
This works well too. Except for some reason you need to call context menu twice to make code work (I have used context menu signal as some kind of delayed signal after application is shown):
int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget w; w.setContextMenuPolicy(Qt::CustomContextMenu); w.show(); QMenuBar *m = new QMenuBar(nullptr); QMenu *edit_menu = m->addMenu("Edit"); edit_menu->addAction("One"); QWidget::connect(&w, &QWidget::customContextMenuRequested, &w, [&w, m] () { QMenu *file_menu = m->addMenu("File"); file_menu->addAction("File One"); QMenu *sub_menu = new QMenu("SubMenu", file_menu); sub_menu->addAction("File Two"); QAction *another_sub_menu_action = new QAction("SubMenu2", file_menu); another_sub_menu_action->setMenu(sub_menu); file_menu->addAction(sub_menu->menuAction()); }); return a.exec(); }
And this is where troubles begin:
int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget w; w.setContextMenuPolicy(Qt::CustomContextMenu); w.show(); QMenuBar *m = new QMenuBar(nullptr); QMenu *edit_menu = m->addMenu("Edit"); edit_menu->addAction("One"); QTimer::singleShot(0, &w, [&w, m] () { QMenu *file_menu = m->addMenu("File"); file_menu->addAction("File One"); QMenu *sub_menu = new QMenu("SubMenu", file_menu); sub_menu->addAction("File Two"); qDebug()<<w.isVisible(); QAction *another_sub_menu_action = new QAction("SubMenu2", file_menu); another_sub_menu_action->setMenu(sub_menu); file_menu->addAction(sub_menu->menuAction()); }); return a.exec(); }
Take a note: in the last example I use initialization on timer timeout to add items to menu after exec() called. File menu will not appear until you click outside of the window to deactivate it and activate window again.
Possible by the same reason in this example after clicking twice you won't see Emoji and Dictation in Edit menu:int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget w; w.setContextMenuPolicy(Qt::CustomContextMenu); w.show(); QMenuBar *m = new QMenuBar(nullptr); QWidget::connect(&w, &QWidget::customContextMenuRequested, &w, [&w, m] () { QMenu *edit_menu = m->addMenu("Edit"); edit_menu->addAction("One"); QMenu *sub_menu = new QMenu("SubMenu", edit_menu); sub_menu->addAction("Two"); edit_menu->addAction(sub_menu->menuAction()); }); return a.exec(); }
Looks like something is not properly updated. I was trying to find a problem but haven't for now. Hope this will help to fix it because this undefined behavior is really creepy.
-
I am not sure what the status of this problem is, but I also have this issue.
Here is a minimal example:
mac-x86:menu steffen$ cat menu.pro
TARGET = menuCONFIG += qt
QT += widgetsSOURCES = menu.cc
mac-x86:menu steffen$ cat menu.cc
#include <QAction>
#include <QApplication>
#include <QMainWindow>
#include <QMenu>
#include <QMenuBar>int main(int argc, char **argv)
{
QApplication app(argc, argv);
QMenuBar menuBar(0);
QMenu menu(&menuBar);
menu.setTitle("Project");
menuBar.addMenu(&menu);
QAction open(&menu);
open.setText("Open");
menu.addAction(&open);
QMenu sub(&menu);
open.setMenu(&sub);
QAction demo(&sub);
demo.setText("Demo");
sub.addAction(&demo);
QMainWindow win;
win.show();
app.exec();
}When compiling this with Qt 5.7 on Mac OSX 10.12.6 (Sierra), everything works correctly and the "Project - Open" menu is enabled (not ghosted) and I can select its sub menu item "Demo".
But when compiling this with Qt 5.9.1, the "Project - Open" menu item is disabled (ghosted) and when hovering over the item, the sub menu does not pop up and I can't select the "Demo" sub-menu item.
So, either there is something wrong with how I build the menu tree, or something got broken in the OSX version in 5.8 or 5.9. On other systems (Windows, Linux) this problem does not happen.
-
-
Hello @brktim I think it works if you do it this way. Does this not work for you?
int main(int argc, char **argv) { QApplication app(argc, argv); QMainWindow win; QMenu menu(win.menuBar()); menu.setTitle("Project"); QAction open(&menu); open.setText("Open"); menu.addAction(&open); QMenu sub(&menu); open.setMenu(&sub); QAction demo(&sub); demo.setText("Demo"); sub.addAction(&demo); win.menuBar()->addMenu(&menu); win.show(); app.exec(); }
-
@kenchan
Yes it works !So i look at my code and change:
action=menu->addAction("Open Recent"); action->setMenu(new QMenu(menuBar));
to
action=new QAction("Open Recent"); action->setMenu(new QMenu(menuBar)); menu->addAction(action);
Then the submenu is ok !
Anyway it doesn't resolve the Quit menu issue, if I close all the windows, the quit item in the Apple menu is disabled and you can't quit the app even with the shortcut.
The only way is to click on the quit menu through the Dock.