Skip to content

Instantly share code, notes, and snippets.

@MaurizioB
Created March 3, 2020 02:58
Show Gist options
  • Save MaurizioB/49338f3b6f83816a3638127056cff622 to your computer and use it in GitHub Desktop.
Save MaurizioB/49338f3b6f83816a3638127056cff622 to your computer and use it in GitHub Desktop.
'''
Different ways to doSomething(row, column) based on the clicked button
'''
class GuiBase(QtWidgets.QWidget):
def doSomething(self, row, column):
print(row, column)
'''
Using a "matrix" and self.sender()
'''
class GuiDefGrid(GuiBase):
def __init__(self):
super().__init__()
layout = QtWidgets.QGridLayout(self)
self.grid = []
for row in range(4):
rowList = []
self.grid.append(rowList)
for column in range(4):
button = QtWidgets.QPushButton('{} {}'.format(row, column))
layout.addWidget(button, row, column)
rowList.append(button)
button.clicked.connect(self.doSomethingFromButton)
def doSomethingFromButton(self):
sender = self.sender()
for row, rowList in enumerate(self.grid):
for column, button in enumerate(rowList):
if button == sender:
self.doSomething(row, column)
break
'''
Setting a custom object attribute, also with sender()
'''
class GuiDefAttrib(GuiBase):
def __init__(self):
super().__init__()
layout = QtWidgets.QGridLayout(self)
for row in range(4):
for column in range(4):
button = QtWidgets.QPushButton('{} {}'.format(row, column))
layout.addWidget(button, row, column)
button.clicked.connect(self.doSomethingFromButton)
button.coords = (row, column)
def doSomethingFromButton(self):
sender = self.sender()
self.doSomething(*sender.coords)
class GuiLambda(GuiBase):
def __init__(self):
super().__init__()
layout = QtWidgets.QGridLayout(self)
for row in range(4):
for column in range(4):
button = QtWidgets.QPushButton('{} {}'.format(row, column))
layout.addWidget(button, row, column)
button.clicked.connect(lambda _, r=row, c=column: self.doSomething(r, c))
@juanarrivillaga
Copy link

juanarrivillaga commented Mar 3, 2020

But my point is that you can just do the following:

class GuiLambda(GuiBase):
    def __init__(self):
        super().__init__()
        layout = QtWidgets.QGridLayout(self)
        for row in range(4):
            for column in range(4):
                button = QtWidgets.QPushButton('{} {}'.format(row, column))
                layout.addWidget(button, row, column)
                def _click_handler(_, r=row, c=column): return self.doSomething(r, c)
                button.clicked.connect(_click_handler)

And it does the same thing.

lambda x,y: x*y

is essentially sugar for:

def some_unique_name(x, y): return x*y; del some_unique_name

Most of the time, you don't care, because you are in some loop in some local scope, so the name doesn't matter.

@MaurizioB
Copy link
Author

Yes, you're right, that's another option.
Nonetheless I don't think that's an improvement over lambda (but I realize that it's also a matter of preference and habit, amongst other things), since in similar cases (and others I was referring to in my comment) one doesn't really care about the function name as you also pointed out, and the syntax is usually smaller and easier to write/read.
Plus, it takes half the lines :-P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment