My application uses a QTabWidget for multiple 'pages', where the top-level menu changes depending on what page the user is on.
My issue is that attempting to re-create the contents of the menu bar results in major display issues. It works as expected with the first and third style (haven't tested second, but I'd rather not use that style) on all platforms except for Mac OS X.
The first menu is created in the way I create most in the application, and they receive the correct title, but disappear as soon as the menu is re-created.
The second menu appears both on the initial population and the re-population of the menu bar, but in both cases has the label "Untitled". The style for the second menu was only created when trying to solve this, so it's the only way I've been able to have a menu stick around.
The third dynamic menu never appears, period. I use this style for dynamically populating menus that are about to show.
I have tried deleting the QMenuBar and re-creating one with
m_menuBar = new QMenuBar(0);
and using that as opposed to m_menuBar->clear()
but it has the same behavior.
I don't have enough reputation to post images inline, so I'll include the imgur links:
Launch behavior: https://i.sstatic.net/V4N6O.png
Post button-click behavior: https://i.sstatic.net/fytDc.png
I have created a minimal example to reproduce this behavior on Mac OS X 10.9.4 with Qt 5.3.
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
m_menuBar = new QMenuBar(0);
m_dynamicMenu = new QMenu("Dynamic");
connect(m_dynamicMenu, SIGNAL(aboutToShow()), this, SLOT(updateDynamicMenu()));
changeMenuBar();
QPushButton *menuBtn = new QPushButton("Test");
connect(menuBtn, SIGNAL(clicked()), this, SLOT(changeMenuBar()));
setCentralWidget(menuBtn);
}
void MainWindow::changeMenuBar() {
m_menuBar->clear();
// Disappears as soon as this is called a second time
QMenu *oneMenu = m_menuBar->addMenu("One");
oneMenu->addAction("foo1");
oneMenu->addAction("bar1");
oneMenu->addAction("baz1");
// Stays around but has 'Untitled' for title in menu bar
QMenu *twoMenu = new QMenu("Two");
twoMenu->addAction("foo2");
twoMenu->addAction("bar2");
twoMenu->addAction("baz2");
QAction *twoMenuAction = m_menuBar->addAction("Two");
twoMenuAction->setMenu(twoMenu);
// Never shows up
m_menuBar->addMenu(m_dynamicMenu);
}
void MainWindow::updateDynamicMenu() {
m_dynamicMenu->clear();
m_dynamicMenu->addAction("foo3");
m_dynamicMenu->addAction("bar3");
m_dynamicMenu->addAction("baz3");
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtWidgets>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
private slots:
void changeMenuBar();
void updateDynamicMenu();
private:
QMenuBar *m_menuBar;
QMenu *m_dynamicMenu;
};
#endif // MAINWINDOW_H
oneMenu->menuAction()
is correct and works for the first 2, it is apparently mandatory (on Mac OS X) for a menu to have existing actions when added to theQMenuBar
. Since my dynamic menu example doesn't add actions until theaboutToShow()
signal is emitted, my work-around is to populate the dynamic menu with 1QAction
that serves no purpose other than to get it to initially show. In myupdateDynamicMenu()
slot I then clear and re-populate the dynamic menu. – Joist