0

I'm trying to build a QMenu with several dynamically generated actions. The code bellow makes a simple window with two QAction in a QMenu. The QMenu is used in the menu bar and in a button.


from PyQt5.QtWidgets import QMainWindow, QPushButton, QHBoxLayout, QAction, QMenu, QApplication

class MainWin(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self)
        self.setupGui()
        self.setupMenu()
        
        
    def setupGui(self): 
        """ make a QpushButton for the QAction """
        self.btn = QPushButton("Press me!", self)
        self.btn.move(50,50)
        self.layout().addWidget(self.btn)
    
    
    def setupMenu(self):
        self.menu = QMenu(self) # making the Qmenu
        self.menu.setTitle('Broken menu')
        
        for actName in ['neverTrig', 'alwaysTrig']:
            act = QAction(actName, self)
            act.triggered.connect(lambda : print(actName))
            self.menu.addAction(act)
            
        self.btn.setMenu(self.menu) #binding the menu to the button
        self.menuBar().addMenu(self.menu) #binding the menu to the menuBar
        
        
        
if __name__ == '__main__':
    app=QApplication([])
    win = MainWin()
    win.show()
    app.exec_()

The method setupMenu() fills the QMenu with two different QAction. However, no matter which is clicked, its always the last one that is triggered. Even if neverTrig is clicked, alwaysTrig will be printed.

I’ve tried different syntaxes, not using lambda functions, keeping a reference of the lambda functions, keeping another reference to the QAction, being more verbose, less verbose, and different version of PyQt. No matter what the last QAction is always the one that is triggered.

I’m using Python 3.8.8 on Windows and PyQt 5.15.2

1 Answers1

0

You asign the act to the same variable,and thats why your trigger connect always to the last one.Try:

act1 = QAction('neverTrig', self)
act1.triggered.connect(lambda : print('whatever'))
self.menu.addAction(act1)

act2 = QAction('alwaysTrig', self)
act2.triggered.connect(lambda : print('whatever 2'))
self.menu.addAction(act2)