J'ai un menubutton, qui, lorsqu'il est cliqué, devrait afficher un menu contenant une séquence spécifique de chaînes. Exactement ce que les chaînes sont dans cette séquence, nous ne savons pas avant l'exécution, de sorte que le menu qui apparaît doit être généré à ce moment. Voici ce que j'ai:Création dynamique d'un menu dans Tkinter. (expressions lambda?)
class para_frame(Frame):
def __init__(self, para=None, *args, **kwargs):
# ...
# menu button for adding tags that already exist in other para's
self.add_tag_mb = Menubutton(self, text='Add tags...')
# this menu needs to re-create itself every time it's clicked
self.add_tag_menu = Menu(self.add_tag_mb,
tearoff=0,
postcommand = self.build_add_tag_menu)
self.add_tag_mb['menu'] = self.add_tag_menu
# ...
def build_add_tag_menu(self):
self.add_tag_menu.delete(0, END) # clear whatever was in the menu before
all_tags = self.get_article().all_tags()
# we don't want the menu to include tags that already in this para
menu_tags = [tag for tag in all_tags if tag not in self.para.tags]
if menu_tags:
for tag in menu_tags:
def new_command():
self.add_tag(tag)
self.add_tag_menu.add_command(label = tag,
command = new_command)
else:
self.add_tag_menu.add_command(label = "<No tags>")
La partie importante est la substance sous la rubrique « si menu_tags: » - menu_tags Supposer la liste [ « pile », « over », « flux »]. Alors ce que je veux faire est effectivement ceci:
self.add_tag_menu.add_command(label = 'stack', command = add_tag_stack)
self.add_tag_menu.add_command(label = 'over', command = add_tag_over)
self.add_tag_menu.add_command(label = 'flow', command = add_tag_flow)
où add_tag_stack() est définie comme:
def add_tag_stack():
self.add_tag('stack')
et ainsi de suite. Le problème est que la variable 'tag' prend la valeur 'stack', puis la valeur 'over' et ainsi de suite, et qu'elle n'est pas évaluée avant l'appel de new_command, point auquel la variable 'tag 'est juste' flux '. Ainsi, le tag qui est ajouté est toujours le dernier sur le menu, peu importe ce que l'utilisateur clique dessus. J'utilisais à l'origine un lambda, et je pensais que peut-être définir explicitement la fonction ci-dessus pourrait mieux fonctionner. De toute façon, le problème se produit. J'ai essayé d'utiliser une copie de la variable 'tag' (soit avec "current_tag = tag" ou en utilisant le module de copie) mais cela ne le résout pas. Je ne suis pas sûr pourquoi.
Mon esprit commence à errer vers des choses comme "eval" mais j'espère que quelqu'un peut penser à une manière intelligente qui n'implique pas des choses aussi horribles.
Merci beaucoup!
(Dans le cas où il est pertinent, Tkinter .__ version__ retourne 'Révision $: 67083 $ et je suis en utilisant Python 2.6.1 sous Windows XP.)
Eh bien, je pensais qu'il pourrait y avoir une solution spécifique à Tkinter. Quelqu'un disant "Non non non, la façon dont vous faites ceci est la fonction spéciale Tkinter.somethingOrOther()" Merci pour l'aide! – MatrixFrog
Pas de problème! Je voulais juste souligner qu'une bonne première étape consiste à essayer d'isoler un petit exemple du problème, pour voir s'il s'agit d'un problème de langage ou d'un problème d'API. –