Search code examples
pythonpython-3.xlambdapyqt5slot

How to define lambda functions to override several slots in Qt?


I try to use lambda functions to call a method that take arguments from slot that do not provide any (QtWidgets.QGroupBox.clicked() just fires without emitting anything).

I construct several QtWidgets.QGroupBox automatically for several light types. Each one should toggle on/off a sort of lighting in a 3D environment. This toggling is to be driven by the check of the groupBox for the lightType, hence this slot should pass its type and state.

This is a simplified code:

for lightType in A_CERTAIN_LIST:
    lightTypeBox = QtWidgets.QGroupBox(lightType, self.lightingDock)
    for param in a A_CERTAIN_DIC.keys():
        if param IS_THE_BOOL_PARAM:
            slotLambda = lambda: self.updateLighting(lightType, param, lightTypeBox.isChecked())
            lightTypeBox.clicked.connect(slotLambda)
...

the lightTypeBox created is also added to a dic to keep a ref of each, and all added in the end to the dockPanel it appears in.

I did hope each lightTypeBox to have its own lambda function connected, giving proper arguments (lightType, param, bool) passed to the function self.updateLighting defined in my class MainWindow(QtWidgets.QMainWindow):

    @Slot(str, str, bool)
    @Slot(str, str, int)
    @Slot(str, str, float)
    def updateLighting(self, lighting, param, val):
        self.canvas.mainRenderer.setLighting(lighting, param, val)

This has several @Slot(...) signatures for I hope to use it with others lambdas (for QspinBox, QDoubleSpinBox and so on, still to have their settings given back, for which light, for which parameters, what value...).

But What I have currently is all my group boxes on their check/uncheck do use the last slotLambda defined as if there was only but one lambda function defined, even if defined inside the second for.

What should I do differently? I did try to put lambdas in a list, in a dic, hoping to keep them separated and not rewritten at each for param pass. I don't know if it's clear...

Anyway, do you see something here?


Solution

  • Ok,

    I got it:

    I just defined input attributes passed to the lambda:

    slotLambda = lambda lightType=lightType, param=param, lightTypeBox=lightTypeBox: self.updateLighting(lightType, param, lightTypeBox.isChecked())

    So every lambda has its own arguments :-).