PDA

View Full Version : OSX - setMenuBar() - EXC_BAD_ACCESS error - how to re-setMenuBar()



LucaDanieli
11th May 2017, 15:42
I am trying to create an application that shows a QMainWindow and multiple QWidget as additional windows. Each window's menu is slightly different. My problem is on MAC.
Basically, I have to update some actions.
Each time I create a new window, my constructor is like:



QMenuBar * MainWindow::createMenus( MultiEditor * thisWindow )
{
QMenuBar *menuBar;
QMenu *menu;
QMenu *submenu;

#ifdef Q_OS_MAC
menuBar = new QMenuBar(0);
#else
menuBar = new QMenuBar();
#endif

menu = new QMenu(tr("&File"), this);
menu->addAction( thisWindow->action(MultiEditor::Undo) );

return menu;
}


So, thisWindow is fixed in the moment I create a new window.
What happens is that, if I change focus and click on a different window, the action doesn't update (it applies to my previous window), as thisWindow has not changed with the focus.

So I was thinking of resetting the menuBar with a function updateMenuBar(menu) each time the focus changes, and I wrote this:



MainWindow::updateMenuBar( QMenuBar * menu )
{
#ifdef Q_QS_MAC
this->setMenuBar(menu)
#endif
}


When I create the MainWindow, the this->setMenuBar(menu1) works fine and menu1 is set.
When I create additional windows, this->setMenuBar(menu2) or (menu3) or (...) are set correctly in the moment of the creation.

But when I change window, and then focus, and I call the function updateMenuBar(menu1) for example, the application crashes and I get the error:

Thread 1: EXC_BAD_ACCESS (code=1, ...) within the updateMenuBar(...) method.

Does any of you know if I can continuously re-setMenuBar? I really don't understand what is the best approach for MAC.

Kind regards,
Luca

Santosh Reddy
12th May 2017, 12:46
setMenuBar() of QMainWindow will take ownership of the menu and will delete it, you should not reuse it. The solution will be to create a new menu every time the focus changes and then set it as menu bar. Write a factory function to create menus, something like



createMenuBar1()
{
QMenuBar * menu = new QMenuBar();

// add actions

return menu;
}

{
...
updateMenuBar(createMenuBar1());
...
updateMenuBar(createMenuBar2());
...
updateMenuBar(createMenuBar3());
...
updateMenuBar(createMenuBar1());
...
}