pythonpyqtpyqt5qt-signalsqt-slot

Qt: multiple menus share the same actions but connect to different slots


I have two menus with the same actions. But I would like to connect them to different slots depending on the menu. Can I do that?

The code below fails to do it, instead, it connects the actions to both slots.

I can create a different set of actions, with the same name. I am wondering whether there is a different way to do it without duplicating all the actions.

import sys
from PyQt5 import QtWidgets, QtGui, QtCore


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        centralWidget = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout()
        centralWidget.setLayout(layout)
        self.setCentralWidget(centralWidget)
        self.menuBar = QtWidgets.QMenuBar(self)
        layout.addWidget(self.menuBar)
        self.log = QtWidgets.QTextEdit()
        layout.addWidget(self.log)        

        fileMenu = self.menuBar.addMenu('File')
        editMenu = self.menuBar.addMenu('Edit')
        actions = []
        for i in range(5):
            action = QtWidgets.QAction('{}'.format(i), self)
            actions.append(action)
        fileMenu.addActions(actions)
        editMenu.addActions(actions)
        fileMenu.triggered.connect(self.file_action_triggered)
        editMenu.triggered.connect(self.edit_action_triggered)

    def file_action_triggered(self, action):
        print('File', action.text())
        self.log.append('File' + action.text())

    def edit_action_triggered(self, action):
        print('Edit', action.text())
        self.log.append('Edit' + action.text())


def main():
    app = QtWidgets.QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

When running the above code, and click "File - 1", I would expect only

File1

to be printed. Instead, it prints

File1
Edit1

Solution

  • You have not created QActions with similar names, which have assigned the same QActions to 2 QMenus. What you should do is create 2 QActions with the same text and assign each one to a different QMenu.

    For example:

    for i in range(5):
        fileMenu.addAction(QtWidgets.QAction('{}'.format(i), self))
        editMenu.addAction(QtWidgets.QAction('{}'.format(i), self))