duocorn
duocorn

Reputation: 43

PyQt5 use shortcuts in opened menu

In a PyQt5 application I have a QMenu. I want to make it so that once the menu is open, users can use keys 1, 2, 3, etc to select option 1, 2, 3, etc in the menu. However, I'm having trouble setting the shortcut, or getting the shortcut to react to the keypress.

I've taken an example from this website, and adapted it slightly to show my issue. I tried assigning shortcuts in the addAction function, but this does not work.

I've tried creating regular QShortcuts, but those no longer respond when the menu is open. I noticed that I can change the selected option using arrow up and down, and then confirm my selection with the enter key, so the QMenu is able to catch keypresses. But how can I assign my own shortcuts?

from PyQt5 import QtGui
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu
import sys


class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.title = "PyQt5 Context Menu"
        self.top = 200
        self.left = 500
        self.width = 400
        self.height = 300
        self.InitWindow()


    def InitWindow(self):
        self.setWindowIcon(QtGui.QIcon("icon.png"))
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.show()

    def contextMenuEvent(self, event):
        contextMenu = QMenu(self)
        newAct = contextMenu.addAction("New", self.triggered, shortcut='A')
        openAct = contextMenu.addAction("Open", self.triggered2, shortcut='B')
        quitAct = contextMenu.addAction("Quit", self.triggered3, shortcut='C')
        action = contextMenu.exec_(self.mapToGlobal(event.pos()))
        if action == quitAct:
            self.close()

    def triggered(self):
        print("triggered 1")

    def triggered2(self):
        print("triggered 2")

    def triggered3(self):
        print("triggered 3")
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())

Upvotes: 2

Views: 1430

Answers (2)

Demi-Lune
Demi-Lune

Reputation: 1967

When a QMenu is opened, shortcuts are not active, but accelerator keys are working. You declare them with &:

    newAct = contextMenu.addAction("New &1", self.triggered)

When the context menu pops up, pressing 1 triggers the correct function.

Upvotes: 2

S. Nick
S. Nick

Reputation: 13641

The QKeySequence class encapsulates a key sequence as used by shortcuts. More... https://doc.qt.io/qt-5/qkeysequence.html

Try it:

import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu


class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.title = "PyQt5 Context Menu"
        self.top = 200
        self.left = 500
        self.width = 400
        self.height = 300
        self.InitWindow()

    def InitWindow(self):
        self.setWindowIcon(QtGui.QIcon("icon.png"))
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.show()

    def contextMenuEvent(self, event):
        contextMenu = QMenu(self)
#        newAct = contextMenu.addAction("New", self.triggered, shortcut='A')
        newAct = contextMenu.addAction(
            "New (&A)", self.triggered, shortcut=QtGui.QKeySequence.New)            # +++
        openAct = contextMenu.addAction(
            "Open (&B)", self.triggered2, shortcut=QtGui.QKeySequence.Open)         # +++
        quitAct = contextMenu.addAction(
            "Quit (&C)", self.triggered3, shortcut=QtGui.QKeySequence.Quit)         # +++
        action = contextMenu.exec_(self.mapToGlobal(event.pos()))
        if action == quitAct:
            self.close()

    def triggered(self):
        print("triggered 1")

    def triggered2(self):
        print("triggered 2")

    def triggered3(self):
        print("triggered 3")
        
        
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())

enter image description here

Upvotes: 1

Related Questions