I am trying to create a side menu using PyQT6. I want the menu to be passed as a list like this
menu = [ ("File", [("New", newHandler), ("Open", openHandler), ("Exit", exitHandler)] ), ("Edit", [("Copy", copyHandler), ("Paste", pasteHandler)] ) ]
So this menu
variable encapsulates the fact that there is going to be two broad menus: File
Menu and Edit
menu. Under File
Menu, there is New
, Open
and Exit
. Similarly, under Edit
menu, there is Copy
and Paste
.
I will pass this to a SideMenu object like this which will construct the menu as specified
SideMenu(menu)
Now the SideMenu Class is like this:
class SideMenu(QWidget):
def __init__(self, menu):
QWidget.__init__(self)
self.layout = QVBoxLayout(self)
for menuItem, actions in menu:
self.layout.addWidget(QLabel(menuItem))
for actionName, actionHandler in actions:
btn=QPushButton(actionName)
btn.clicked.connect(lambda: actionHandler(btn))
self.layout.addWidget(btn)
self.show()
def newHandler(x):
print("Inside newHandler")
def openHandler(x):
print("Inside openHandler")
def exitHandler(x):
print("Inside exitHandler")
def copyHandler(x):
print("Inside copyHandler")
def pasteHandler(x):
print("Inside pasteHandler")
menu = [ ("File", [("New", newHandler), ("Open", openHandler), ("Exit", exitHandler)] ), ("Edit", [("Copy", copyHandler), ("Paste", pasteHandler)] ) ]
app = QApplication(sys.argv)
screen = SideMenu(menu)
screen.show()
sys.exit(app.exec())
However, the problem is whenever any button is pressed, just the pasteHandler is called. i.e. I get to see the output Inside pasteHandler
no matter which button is pressed.
However, if I modify just one line of the above program from
btn.clicked.connect(lambda: actionHandler(btn))
to
btn.clicked.connect(actionHandler)
this works perfectly !
I dont understand why it should happen. I need to pass the button to the handler function definitely. But if try to pass the button as an argument to the handler function, only the last handler function is executed on each button click.