0

I'm trying to recreate the windows note pad.

I'm currently messing with the QMenuBar

I made a dictionary with all the menus and actions it will have in the following pattern:

menus = {'File':[['New', 'Ctrl+n'],
                 ['Open', 'Ctrl+o'],
                 ['Save', 'Ctrl+s'],
                 ['Save as...', None],
                 'Separator', 
                 # and so on

Then I iterate over that dict, and created the menus and actions successfully and stored them in a second dictionary.

Now I'm trying to connect each action[new, open, save, …] to a instance method of the same name.

I'm doing like so:

for action in menus[m]:
    action = menu.addAction(action[0])

    if action[1]:
        action.setShortcut(QKeySequence(action[1]))

    if isinstance(action, QAction):
        fname = action[0].lower() 
        # and some other string manipulations
        func = getattr(self,fname)
        action.triggered.connect(lambda arg=action: func(arg))

It connects successfully, but if I try to use any of the actions it does nothing.

I had previously connected actions using lambda functions, but this is the first time I'm using getattr() and lambda together.

f.rodrigues
  • 3,499
  • 6
  • 26
  • 62

1 Answers1

5

Found my mistake:

Problem was thatfunc was getting overwritten on every iteration over menus.

fixed it by changing:

action.triggered.connect(lambda arg=action:func(arg))

to

action.triggered.connect(lambda f=func,arg=a:f(arg))

The latter works because a reference to func is stored is taken immediately by default argument in lambda.

Dima Tisnek
  • 11,241
  • 4
  • 68
  • 120
f.rodrigues
  • 3,499
  • 6
  • 26
  • 62