Event Verarbeitung

Fragen zu Tkinter.
Antworten
Foxxi
User
Beiträge: 33
Registriert: Sonntag 10. Mai 2009, 16:49

Hallo,

ich erstelle gerade eine Anwendung mit diversen Combobox Widgets, wobei die möglichen Eingaben einiger Boxes von den Eingaben in anderen abhängig sein sollen. Das Problem wollte ich lösen, indem ich die Aktivierung einer Combobox als Event festlege und dann die dort erlaubten Eingaben bestimme. Läuft aber leider nicht. :?

Das folgende Beispiel zeigt, was ich meine. In der ersten Combobox kann man zwischen 'Pommes' und 'Reis' wählen. Je nach Auswahl soll man dann in der zweiten zwischen 'Ketchup' und 'Majo' (Pommes) oder 'Sojasauce' und 'Süßsauer' (Reis) wählen können.

Code: Alles auswählen

# Python Version 3.2.2

import tkinter as tk
from tkinter import ttk

class Test(object):

    def __init__(self):
        self.w       = tk.Tk()
        self.Beilage = tk.ttk.Combobox(values = ['Pommes', 'Reis'])
        self.Beilage.pack()
        self.Sauce   = tk.ttk.Combobox(values = self.Saucenliste)
        self.Sauce.bind('<Activate>', self.Saucenauswahl(self.Beilage.get()))
        # Saucenauswahl wird nicht aufgerufen 
        self.Sauce.pack()
        self.w.mainloop()

    def Saucenauswahl(self, Beilage):
        print('Saucenauswahl wurde aufgerufen')
        if Beilage == 'Pommes':
            self.Saucenliste = ['Ketchup', 'Majo']
        elif Beilage == 'Reis':
            self.Saucenliste = ['Sojasauce', 'Süßsauer']
        else:
            self.Saucenliste = []

Test()
Kann mir jemand sagen, was ich da falsch gemacht habe? Vielen Dank schon mal.

Foxxi
Zuletzt geändert von Anonymous am Sonntag 13. Januar 2013, 12:23, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Du musst bei bind eine Funktion übergeben und nicht das Ergebnis eines Funktionsaufrufs.
Das Leben ist wie ein Tennisball.
Foxxi
User
Beiträge: 33
Registriert: Sonntag 10. Mai 2009, 16:49

Danke für die schnelle Antwort. Ich taste mich mal langsam ran und übergebe jetzt nur noch die Funktion. Leider wird sie trotzdem nicht aufgerufen:

Code: Alles auswählen

# Python Version 3.2.2

import tkinter as tk
from tkinter import ttk

class Test(object):

    def __init__(self):
        self.w       = tk.Tk()
        self.Beilage = tk.ttk.Combobox(values = ['Pommes', 'Reis'])
        self.Beilage.pack()
        self.Sauce   = tk.ttk.Combobox(values = self.Saucenliste)
        self.Sauce.bind('<Activate>', self.Saucenauswahl)
        # Saucenauswahl wird leider immer noch nicht aufgerufen 
        self.Sauce.pack()
        self.w.mainloop()

    def Saucenauswahl(self):
        print('Saucenauswahl wurde aufgerufen')
        Beilage = self.Beilage.get()
        if Beilage == 'Pommes':
            self.Saucenliste = ['Ketchup', 'Majo']
        elif Beilage == 'Reis':
            self.Saucenliste = ['Sojasauce', 'Süßsauer']
        else:
            self.Saucenliste = []

Test()
Wenn ich das richtig sehen, dann ist meine Funktion self.Saucenauswahl wohl der Eventhandler, oder? In den Beispielen, die ich zur Enventverarbeitung angeshen habe wird dort immer noch eine Variable event mit übergeben. Nützt in meinem Beispiel aber auch nichts :K und ich muss auch gestehen, dass ich nicht verstehe, was da eigentlich konkret passiert.

Kann man das obige Beipiel denn so verändern, dass bei Aktivierung der zweiten Combobox die Funktion self.Saucenauswahl aufgerufen wird?

Foxxi

P.S. (nachträchlich): Moment, ich sehe gerade, das kann ja auch gar nicht gehen, weil self.Saucenliste bereits vor dem Funktionsaufruf benutzt wird. Ich stricke das eben noch mal um....
Zuletzt geändert von Anonymous am Sonntag 13. Januar 2013, 12:24, insgesamt 2-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ganz übersehen: "Activate" ist sicher auch nicht das richtige Ereignis, ich würde mal auf "ComboboxSelected" tippen.
Das Leben ist wie ein Tennisball.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@EyDu: dann müsste man es aber an Beilagen und nicht an Saucen binden.
Foxxi
User
Beiträge: 33
Registriert: Sonntag 10. Mai 2009, 16:49

Ja, genau, es muss an Beilagen gebunden werden, damit die dortige Selektion berücksichtigt wird, bevor die nächste Combobox erzeugt wird.

Ich habe das mal gemacht, aber leider wird die Funktion immer noch nicht aufgerufen. Aber ich glaube, wir kommen der Sache schon näher:

Code: Alles auswählen

# Python Version 3.2.2

import tkinter as tk
from tkinter import ttk

class Test(object):

    def __init__(self):
        self.w       = tk.Tk()
        self.Beilage = tk.ttk.Combobox(values = ['Pommes', 'Reis'])
        self.Beilage.bind('<<ComboboxSelected>>', self.Saucenauswahl)
        self.Beilage.pack()
        self.Sauce   = tk.ttk.Combobox(values = self.Saucenliste)
        # Saucenauswahl wird leider immer noch nicht aufgerufen 
        self.Sauce.pack()
        self.w.mainloop()

    def Saucenauswahl(self):
        print('Saucenauswahl wurde aufgerufen')
        Beilage = self.Beilage.get()
        if Beilage == 'Pommes':
            self.Saucenliste = ['Ketchup', 'Majo']
        elif Beilage == 'Reis':
            self.Saucenliste = ['Sojasauce', 'Süßsauer']
        else:
            self.Saucenliste = ['test1', 'test2']

Test()
Irgendwie bleibt ja das Problem, dass bei der Abarbeitung des Codes noch keine Selektion erfolgt ist und deshalb noch keine Saucenliste existiert.
Foxxi
User
Beiträge: 33
Registriert: Sonntag 10. Mai 2009, 16:49

Weiss jemand, ob und wenn ja wie man die values einer Combobox nachträglich verändern kann?
:?:
BlackJack

@Foxxi: Die Werte sind in der Option `values` gespeichert und die setzt man wie jede andere Tk-Option auch: Schlüsselzuweisung mit der Index-Syntax oder mit der `configure()`-Methode auf `Widget`\s. Ganz allgemein:

Code: Alles auswählen

widget['option'] = value
# oder
widget.configure(option=value)
Foxxi
User
Beiträge: 33
Registriert: Sonntag 10. Mai 2009, 16:49

@BlackJack: Ah, klar, manche Dinge sind halt zu naheliegend.

Super, jetzt funktioniert es auch. Danke für die Hilfe.

Das Ergebnis sieht dann so aus:

Code: Alles auswählen

# Python Version 3.2.2

import tkinter as tk
from tkinter import ttk

class Test(object):

    def __init__(self):
        self.w       = tk.Tk()
        self.Beilage = tk.ttk.Combobox(values = ['Pommes', 'Reis'])
        self.Beilage.bind('<<ComboboxSelected>>', self.Saucenauswahl)
        self.Beilage.pack()
        self.Sauce   = tk.ttk.Combobox()
        self.Sauce.pack()
        self.w.mainloop()

    def Saucenauswahl(self, event):
        Beilage = self.Beilage.get()
        if Beilage == 'Pommes':
            self.Saucenliste = ['Ketchup', 'Majo']
        elif Beilage == 'Reis':
            self.Saucenliste = ['Sojasauce', 'Süßsauer']
        else:
            self.Saucenliste = []
        self.Sauce['values'] = self.Saucenliste
        self.Sauce.delete(0, tk.END)

Test()
Foxxi
Antworten