On Mon, Nov 15, 2021 at 8:44 AM Rudi Hammad <[email protected]> wrote:

> Amazing, thanks for the explanation.
> I've used wrappers before in other contexts but not partial.  Didn't found
> that issue until now.
> Nothing much to add! that solved it. Thank you
>

Welcome!

Also, I should point out that I have seen cases in either pyqt or pyside
where using a partial() or local scope function wrapper could lead to a
memory leak on the object with the signal, depending on how objects are
parented and deleted. This can happen because python (I think) won't be
able to automatically disconnect the signal if it doesnt see that the
object owning the slot has been garbage collected. When you use a partial()
or a local wrapper, its a branch new object. So switching to always using
methods bound to your object seems to work better
(self._printFooHandler(self.printFoo, n))
Not saying it happens all the time, but I have seen it before.


>
> El domingo, 14 de noviembre de 2021 a las 20:21:29 UTC+1,
> [email protected] escribió:
>
>> On Mon, Nov 15, 2021 at 7:15 AM Rudi Hammad <[email protected]> wrote:
>>
>>> Hello,
>>>
>>> I wrote this simple ui to ilustrate the issue. As the title says I am
>>> creating dynamically
>>> some widgets and attaching a signal. In this case 4 buttons that when
>>> clicked, print their name.
>>> The problem if you run the code is that all buttons are printing the
>>> same letter 'D', which is the last signal to be set.
>>>
>>> dynamic widget creation <https://pastebin.com/clone/k8cVKC05>
>>>
>>> Any ideas how to create dynamic signals that will be attached to the
>>> corresponding widget?
>>>
>>
>> Hey there. So this is caused by the fact that a python lambda does not
>> perform a full closure over the scoped variable, which leads to bugs like
>> this when the locally scope variable (n) is changing over the course of the
>> loop. Each lambda you are passing as a slot function has a reference to
>> that scope, but will evaluate the last value of the variable n.
>>
>> (note: dont do the following)
>> The safer way to express the lambda that properly captures the variable
>> value at that time is something like this double-lambda:
>>
>> fn = lambda val: lambda: self.fooPrint(n)
>> btn.clicked.connect(fn(n))
>>
>>
>> This directly captures the current value of your loop variable and
>> returns a new lambda with a closure over that value.
>>
>> Because this is such a fragile mechanism, PEP advises against using
>> anonymous lambdas in the first place:
>> https://www.flake8rules.com/rules/E731.html
>>
>> So what you could do instead is wrap local def functions (there are
>> multiple ways to do this, but here is one way):
>>
>> for n in 'ABCD':
>>     def wrap(val=n, *args):
>>         self.fooPrint(val)
>>     btn.clicked.connect(wrap)
>>
>>
>> And this is pretty much what functools.partial() is for:
>>
>> from functools import partial
>> for n in 'ABCD':
>>     btn.clicked.connect(partial(self.fooPrint, n))
>>
>>
>>
>>
>>> thanks
>>>
>>> R
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Python Programming for Autodesk Maya" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/python_inside_maya/eeb1960d-1e46-43d0-a0d9-1107f695a859n%40googlegroups.com
>>> <https://groups.google.com/d/msgid/python_inside_maya/eeb1960d-1e46-43d0-a0d9-1107f695a859n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "Python Programming for Autodesk Maya" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/python_inside_maya/919b3797-15f2-4dd9-9769-9bcdd55137c2n%40googlegroups.com
> <https://groups.google.com/d/msgid/python_inside_maya/919b3797-15f2-4dd9-9769-9bcdd55137c2n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/python_inside_maya/CAPGFgA0DwBjPb_A3qzeyrFp95Wxs_fUWEw9-C%3DOJg2fYd7caRA%40mail.gmail.com.

Reply via email to