Problem
As far as I'm aware, this undesired behaviour (by my standards) happens, because of late-binding in contrast to early binding in the loop. That is, when the lambda function is called, the iterator variables all have the same values, namely the ones after all loops are finnished.
for color in range(N_COLORS):
for hsv in range(N_HSV):
for mm in range(N_MINMAX):
cv2.createTrackbar(STR_COLORS[color] + STR_HSV[hsv] + STR_MINMAX[mm], window_title, 0, 255, lambda x: change(color, hsv, mm, x))
Question
How can I rewrite this code, so that each Trackbar that is created, has distinct values for color
, hsv
and mm
instead of all of them having the same value.
Minimal Working Example:
import numpy as np
N_COLORS = 3
N_HSV = 3
N_MINMAX = 2
list = []
for color in range(N_COLORS):
for hsv in range(N_HSV):
for mm in range(N_MINMAX):
list.append(lambda: print(color, hsv, mm))
list[0]()
list[1]()
list[2]()
expected output:
[0, 0, 0]
[0, 0, 1]
[0, 1, 0]
actual output:
[2, 2, 1]
[2, 2, 1]
[2, 2, 1]
Answer
As per the duplicate, this solves it
cv2.createTrackbar(STR_COLORS[color] + STR_HSV[hsv] + STR_MINMAX[mm], window_title, 0, 255, lambda x, color=color, hsv=hsv, mm=mm: change(color, hsv, mm, x))