user3191398
user3191398

Reputation:

How to convert QMenu to QMenuBar?

I have QMenu, which contains submenus:

QMenu menu;
// Add some submenus
menu.addMenu(new QMenu("1", menu));
menu.addMenu(new QMenu("2", menu));
menu.addMenu(new QMenu("3", menu));

I want to move these submenus from QMenu to QMenuBar:

QMenuBar* menubar = convertFromQMenu(&menu);

Here is how I think the implementation of convertFromQMenu might look like:

QMenuBar* convertFromQMenu(QMenu* menu) {
    QMenuBar *menubar = new QMenuBar();
    /*
    for(QMenu* menu: menu->menus()) {
        menu.setParent(menubar);
        menubar.addMenu(menu);
    }
    */

    return menubar;
}

However, the commented code does not compile.

How to fix this?

Upvotes: 0

Views: 1046

Answers (2)

scopchanov
scopchanov

Reputation: 8399

Cause

for(QMenu* menu: menu->menus()) {

QMenu does not have a menus method.

Solution

The path to get to where you want is a little bit longer:

  1. Use QWidget::actions to get a list of the actions, added to the menu
  2. Get the QMenu associated with each action using QAction::menu

Now you can add the menu to the QMenuBar.

Note: Do not change the parenting of the menus and submenus.

Example

Based on your code, I would suggest you to implement convertFromQMenu like this:

QMenuBar *MainWindow::convertFromQMenu(QMenu *menu)
{
    auto *menubar = new QMenuBar(this);

    foreach (QAction *act, menu->actions())
        if (act->menu())
            menubar->addMenu(act->menu());

    menu->deleteLater();

    return menubar;
}

Here is how to test the suggested implementation:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    auto *menu = new QMenu("Menu", this);

    // Add some menus
    menu->addMenu(new QMenu("Menu 1", this));
    menu->addMenu(new QMenu("Menu 2", this));
    menu->addSeparator();

    auto *submenu = new QMenu("Menu 3", this);

    submenu->addActions(QList<QAction *>({new QAction("Action 1", this),
                                          new QAction("Action 2", this),
                                          new QAction("Action 3", this)}));

    menu->addMenu(submenu);

    setMenuBar(convertFromQMenu(menu));
    setCentralWidget(new QWidget(this));
    resize(300, 200);
}

I took the liberty to extend this example to switch between compact and extended form of the menus in the menu bar (not shown here). The full code is available on GitHub.

Result

As written, the given example produces the following result:

Window with the menu expanded to three menus

Upvotes: 0

Ayak973
Ayak973

Reputation: 454

You don't need that kind of 'conversion'. If you read carefully from the Qt official doc about QMenuBar and addMenu() member, you can easily add your QMenu to your QMenuBar:

QMenu menu;
// Add some menus
menu.add (new QMenu("1", menu));
menu.add (new QMenu("2", menu));
menu.add (new QMenu("3", menu));

QMenuBar menubar;
menubar.addMenu(&menu);

If you want to use the QMainWindow menu bar, the doc states :

In most main window style applications you would use the menuBar() function provided in QMainWindow, adding QMenus to the menu bar and adding QActions to the pop-up menus.

Example (from the Menus example):

fileMenu = menuBar()->addMenu(tr("&File"));

fileMenu->addAction(newAct);

Upvotes: 1

Related Questions