Search code examples
qmlpyside6qt6

How to add shortcut hint in MenuBar items in Qt/QML 6


I'm looking for a way to add the shortcut hint to a Menu item into the red square as shown on the picture:

Expected result

It should say "Usage guide" on the left and "F1" on the right. However, in Qt6 I cannot find a way to do this, because MenuItem as compared to Qt5 doesn't have shortcut property anymore.

This is my code that doesn't show the shortcut:

Menu {
    id: helpMenu
    title: "&Help"

    Action {
        text: "Usage guide"
        shortcut: "F1"
    }
}

However, using a delegate on Menu, I can force it to display more information:

Menu {
    id: helpMenu
    title: "&Help"
    delegate: MenuItem {
        id: control

        contentItem: Rectangle {
            anchors.centerIn: parent

            Text {
                text: control.text
                anchors.left: parent.left
            }

            Text {
                text: "F1"
                anchors.right: parent.right
            }
        }
    }

    Action {
        text: "Usage guide"
        shortcut: "F1"
    }
}

but here I don't know how to pass the shortcut from an Action into the delegate. It only works for text. I can hardcode the text in there, but that's not useful.


Solution

  • This is basically your solution, but using Shortcut to convert the standard keyboard shortcuts into a string.

    import QtQuick
    import QtQuick.Controls
    
    Window {
        width: 640
        height: 480
        visible: true
        title: qsTr("Hello World")
    
        Menu {
            id: contextMenu
            title: "&Help"
    
            Action {
                text: "Usage guide"
                shortcut: "F1"
            }
            Action {
                text: "Cut"
                shortcut: StandardKey.Copy
            }
            Action {
                text: "Copy"
                shortcut: "Ctrl+E,Ctrl+W"
            }
            Action { text: "Paste" }
    
            delegate: MenuItem {
                id: control
    
                contentItem: Item {
                    anchors.centerIn: parent
    
                    Text {
                        text: control.text
                        anchors.left: parent.left
                        color: "white"
                    }
    
                    Shortcut {
                        id: shortcutHelper
                        sequence: control.action.shortcut
                    }
    
                    Text {
                        text: shortcutHelper.nativeText
                        anchors.right: parent.right
                        color: "white"
                    }
                }
            }
        }
    
        Component.onCompleted: contextMenu.open()
    }
    

    After reading a bit about shortcuts and standard keyboard shortcuts I found this bugreport. The solution I came up with outputs a warning which says to use sequences for standard keyboard shortcuts instead of sequence as there could be multiple shortcuts assigned to a standard keyboard shortcut.

    QML Shortcut: Shortcut: Only binding to one of multiple key bindings associated with 9. Use 'sequences: [ ]' to bind to all of them.

    So for your purpose this would be sufficient:

    Menu {
        id: contextMenu
        title: "&Help"
    
        Action {
            text: "Usage guide"
            shortcut: "F1"
        }
    
        delegate: MenuItem {
            id: control
    
            contentItem: Item {
                anchors.centerIn: parent
    
                Text {
                    text: control.text
                    anchors.left: parent.left
                    color: "white"
                }
    
                Text {
                    text: control.action.shortcut
                    anchors.right: parent.right
                    color: "white"
                }
            }
        }
    }