Why does clicking on any menu item always start the last one?
Question:
In Python, I am trying to generate a menu using a for loop, but when I click on any menu item, the last menu item is always triggered, how can I fix this? I am using Tkinter.
font_sizes = [
str ('8' ),
str ('9' ),
str ("10"),
str ("11"),
str ("12"),
str ("14"),
str ("16"),
str ("18"),
str ("20"),
str ("22"),
str ("24"),
str ("26"),
str ("28"),
str ("36"),
str ("48"),
str ("72"),
];
for font_size in font_sizes :
font_size_menu.add_command (
label = font_size,
command = lambda : function (font_size),
);
Answers:
This is a tricky corner of Python. The issue is that the lambda
captures the name font_size
, not the value. So, by the time any of those functions run, the value of font_size
is "72". You work around this by "capturing" the value as a default parameter. As a side note, you don’t ever need to call str
on a string. And we do not use semi-colons as statement terminators in Python.
font_sizes = [
'8','9','10','11','12','14','16','18',
'20','22','24','26','28','30','48','72'
]
for font_size in font_sizes :
font_size_menu.add_command (
label = font_size,
command = lambda font_size=font_size: function (font_size),
)
In Python, I am trying to generate a menu using a for loop, but when I click on any menu item, the last menu item is always triggered, how can I fix this? I am using Tkinter.
font_sizes = [
str ('8' ),
str ('9' ),
str ("10"),
str ("11"),
str ("12"),
str ("14"),
str ("16"),
str ("18"),
str ("20"),
str ("22"),
str ("24"),
str ("26"),
str ("28"),
str ("36"),
str ("48"),
str ("72"),
];
for font_size in font_sizes :
font_size_menu.add_command (
label = font_size,
command = lambda : function (font_size),
);
This is a tricky corner of Python. The issue is that the lambda
captures the name font_size
, not the value. So, by the time any of those functions run, the value of font_size
is "72". You work around this by "capturing" the value as a default parameter. As a side note, you don’t ever need to call str
on a string. And we do not use semi-colons as statement terminators in Python.
font_sizes = [
'8','9','10','11','12','14','16','18',
'20','22','24','26','28','30','48','72'
]
for font_size in font_sizes :
font_size_menu.add_command (
label = font_size,
command = lambda font_size=font_size: function (font_size),
)