Menu - command - Funktion mit Parameter

Fragen zu Tkinter.
Antworten
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hallo Allerseits! Ich hoffe, der Fehler ist leicht zu sehen und es gibt jemanden, der ihn entdeckt und eine Lösung vorschlagen kann:

Folgendes Script startet ein Fenster mit einem Menü (2 enüpunkte).
Beide Menüpunkte öffnen ein weiteres kleines Fensterchen.

Code: Alles auswählen

# -*- coding: utf-8 -*-
# File: main.py
from Tkinter import *

class KMM:
    def __init__(self):
        self.hauptframe = Tk()
        self.hauptframe.title('KM Manager (Hauptfenster)')
        self.hauptframe.name = 'KMM'
        #~ width = self.hauptframe.winfo_screenwidth() - 8
        #~ height = self.hauptframe.winfo_screenheight()
        width = 400
        height = 200
        self.hauptframe.maxsize(width, height)
        self.hauptframe.wm_geometry("%dx%d+%d+%d" % (width, height, 30, 30))
        KMMMenu(self.hauptframe)
        self.hauptframe.mainloop()

class KMMMenu:
    def __init__(self, master):
        # Menueinstanz erzeugen
        menuobj = Menu(master)
        # Die Menueinstanz dem Fenster zuordnen
        master['menu'] = menuobj

        if master.name == 'KMM':
            # Eine Untermenueinstanz erzeugen
            mnuArbeitsbereiche = Menu(menuobj)
            mnuArbeitsbereiche['tearoff'] = 0
            menuobj.add_cascade(label = 'Arbeitsbereich', menu = mnuArbeitsbereiche)

            # wenn ein Menüpunkt mit einem Separator beendet werden soll, dann 1:
            ABsdef = {'SunMoon' : 1, 'Hauptflugbuch' : 0}
            ABs = ABsdef.keys()

            for mi in ABs:
                mnuArbeitsbereiche.add_command(label = mi, command = lambda:KFrame(master, mi))
                if ABsdef[mi]:
                    mnuArbeitsbereiche.add_separator()

class KFrame    :
    def __init__(self, master, title):
        self.frm = Toplevel(master)
        self.frm.title(title)
        self.frm.focus_set()
        self.frm.transient()

root = KMM()




Anhand des Menüpunkt-Namens möchte ich den Titel des Fensters schalten. Doch leider klappt es nicht. Egal welchen
Menüpunkt ich wähle, der Titel des Fensters ist immer derselbe.

Um den Parameter command bei einem Menüpunkt mit einer Funktion plus
übergebenen Parametern belegen kann, verwende ich die lambda-Funktion, wie es jemandem hier im Forum
empfohlen wurde.

Gibt es bessere Lösungen? Mein Ziel ist eine Applikation mit einem Hauptfenster, über dessen Menü man viele
verschiedene weitere Fenster rufen kann. Da diese sich erstmal ähneln, wollte ich hierfür eine einzige
Klasse bauen, die mir die Grundeinstellungen der Fenster bereitstellt.

Viele Grüße und gespannt auf Hilfe wartend...
JR[/code]
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hi JR!

Du übergibst in Deiner Lambda-Funktion den Namen mi und nicht seinen Wert an den KFrame-Konstruktor. Da die KFrame-Instanz zur Laufzeit erzeugt wird, wird auch der dann aktuelle Wert im Namen mi verwendet. Also der, den mi zum Ende der Schleife hat. Die genauso plausible Lösung ist, dass Du Lambda bei der Parameterübergabe eine Kopie von mi anlegen lässt:

Code: Alles auswählen

[...]lambda mi_local=mi:KFrame(master, mi_local))
Einfach "mi = mi" wäre auch möglich, mi_local dient nur der Veranschaulichung.

Grüße,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
JR
User
Beiträge: 286
Registriert: Montag 20. Februar 2006, 16:43
Wohnort: Berlin

Hallo Michael!

Vielen Dank für deine Antwort!
Ich werde deinen Tipp gleich mal so einbauen.

Viele Grüße
Jamil
Antworten