Please nominate your Qt Champions for 2021! https://forum.qt.io/topic/132134/looking-for-the-2021-qt-champions

different behavior of pressed vs clicked with lambdas



  • I'm using lambda functions to define the actions for dynamically generated buttons. To "freeze" the value of the loop variable "i" assign it to a local variable "n" in the way described here https://docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result

    This works fine for 'pressed',

    button.pressed.connect(lambda a=i : print(f'pressed {a}'))
    

    --> "pressed 7"

    but somehow fails for 'clicked'.

    button.clicked.connect(lambda a=i: print(f'clicked {a}'))
    

    --> "clicked False"

    Reproduce:

    from PySide2.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout
    
    app = QApplication()
    
    window = QWidget()
    layout = QVBoxLayout()
    
    for i in range(10):
        button = QPushButton()
    
        if i > 4:
            button.setText(f'pressed {i}')
            button.pressed.connect(lambda a=i : print(f'pressed {a}'))
        else:
            button.setText(f'clicked {i}')
            button.clicked.connect(lambda a=i: print(f'clicked {a}'))
    
        layout.addWidget(button)
    
    window.setLayout(layout)
    
    window.show()
    
    app.exec_()
    
    

    I fail to understand why this happens. Is there a fundamental difference in the way that 'pressed' and 'clicked' are handled? Or is this a bug?



  • @VirtualFloat Change to:

    • button.clicked[bool].connect(lambda checked, a=i: print(f'clicked {a}'))

    OR

    • button.clicked.connect(lambda *args, a=i: print(f'clicked {a}'))

    See https://stackoverflow.com/a/65185119/6622587 for more information.



  • Ah, so clicked gets an argument where pressed doesn't. Thanks!

    I like the button.clicked.connect(lambda *args, a=i: print(f'clicked {a}')) solution because it will work even if the signature would change.


Log in to reply