qtqmlmenubarapplicationwindow

QML: How to hide a Menu item from the ApplicationWindow MenuBar


In QML/Qt6.5 I try to add/remove a Menu from the MenuBar of a ApplicationWindow dynamically and I don't find a solution. I can hide MenuItems but not the Menu itself.

ApplicationWindow
{
    id: mainWindow
    width: 600
    height: 400
    visible: true

    menuBar: MenuBar {
        id: mainMenuBar

        // this item should be shown/hidden at runtime
        Menu {
            id: subMenu
            title: "Menu to hide"

            MenuItem {
                text: "Menu Item"
            }
        }
    }
}

I have tried several things. Best so far was setting the title to an empty string, but in this case the Menu is still there (you can see it if you hover the area). Anyone having a solution for that?

Setting the height to 0 is also not working properly.


Solution

  • You can use takeMenu() and insertMenu(), but this feels like a hack. In my opinion it isn't good UX to show/hide menus I would rather disable them if not applicable. This way the user knows there is a menu, but it currently doesn't apply to the situation.

    import QtQuick
    import QtQuick.Controls
    import QtQuick.Window
    
    ApplicationWindow {
        id: window
        width: 320
        height: 260
        visible: true
    
        menuBar: MenuBar {
            Menu {
                id: menu1
                title: qsTr("&File")
                Action { text: qsTr("&New...") }
                Action { text: qsTr("&Open...") }
                Action { text: qsTr("&Save") }
                Action { text: qsTr("Save &As...") }
                MenuSeparator { }
                Action { text: qsTr("&Quit") }
            }
            Menu {
                id: menu2
                title: qsTr("&Edit")
                Action { text: qsTr("Cu&t") }
                Action { text: qsTr("&Copy") }
                Action { text: qsTr("&Paste") }
            }
            Menu {
                id: menu3
                title: qsTr("&Help")
                Action { text: qsTr("&About") }
            }
    
            onMenusChanged: checkMenu()
            Component.onCompleted: checkMenu()
    
            function checkMenu() {
                if (window.menuBar.menuAt(1) === menu2) {
                    removeButton.enabled = true
                    addButton.enabled = false
                } else {
                    removeButton.enabled = false
                    addButton.enabled = true
                }
            }
        }
    
        Column {
            anchors.centerIn: parent
            spacing: 6
    
            Button {
                id:  removeButton
                text: "Remove"
                onClicked: {
                    window.menuBar.takeMenu(1)
                }
            }
    
            Button {
                id: addButton
                text: "Add"
                onClicked: {
                    window.menuBar.insertMenu(1, menu2)
                }
            }
        }
    }