Ich habe einen Menubutton, der beim Anklicken ein Menü anzeigen sollte, das eine bestimmte Sequenz von Strings enthält. Genau welche Strings in dieser Sequenz sind, wissen wir erst zur Laufzeit, also muss das Menü, das erscheint, in diesem Moment generiert werden. Hier ist, was ich habe:Dynamisches Erstellen eines Menüs in Tkinter. (Lambda-Ausdrücke?)
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>")
Der wichtigste Teil ist das Zeug unter "wenn menu_tags:" - Es sei menu_tags ist die Liste [ 'Stack', 'über', 'flow']. Und was ich tun möchte, ist effektiv dies:
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)
wo add_tag_stack() ist definiert als:
def add_tag_stack():
self.add_tag('stack')
und so weiter.
Das Problem ist, die Variable 'tag' nimmt den Wert 'stack' und dann den Wert 'over' und so weiter, und es wird nicht ausgewertet, bis new_command aufgerufen wird, an welcher Stelle die Variable 'tag "ist nur" fließen ". Das Tag, das hinzugefügt wird, ist immer das letzte im Menü, unabhängig davon, auf was der Benutzer klickt.
Ich habe ursprünglich ein Lambda verwendet, und ich dachte, dass vielleicht die Funktion wie oben definiert, könnte besser funktionieren. In beiden Fällen tritt das Problem auf. Ich habe versucht, eine Kopie der Variable 'tag' (entweder mit "current_tag = tag" oder mit dem Kopiermodul), aber das löst es nicht. Ich bin mir nicht sicher warum.
Mein Verstand beginnt in Richtung Dinge wie "eval" zu wandern, aber ich hoffe, dass jemand an einen schlauen Weg denken kann, der solche schrecklichen Dinge nicht einschließt.
Vielen Dank!
(Falls es relevant ist, Tkinter .__ version__ gibt '$ Revision: 67083 $' und ich bin mit Python 2.6.1 auf Windows XP.)
Nun, ich dachte, es könnte eine Tkinter-spezifische Lösung gegeben haben. Jemand, der sagt: "Nein, nein, nein, wie du das machst, ist die spezielle Funktion Tkinter.somethingOrOther()" Danke für die Hilfe! – MatrixFrog
Kein Problem! Ich wollte nur darauf hinweisen, dass ein guter erster Schritt darin besteht, ein kleines Beispiel des Problems zu isolieren, um zu sehen, ob es sich um ein Sprachproblem oder ein API-Problem handelt. –