2017-02-16 5 views
1

Ich habe versucht, ein Problem zu rekonstruieren, das ich in einem Projekt, das ich gerade entwickle, vorfindet, wo meine Funktion scheinbar einen Klick zurückliegt.Warum läuft meine Funktion einen Klick zurück?

Ich habe 3 Spinboxen. Jede gegebene Kombination der Werte in den ersten beiden Spinboxen sollte den Wert des dritten bestimmen, der aus einigen verschachtelten Listen stammt.

Zum Beispiel sollte '0' in der Spinbox_1 und 'A' in der Spinbox_2 den Wert von spinbox_3 auf '1' setzen. und '1' und 'A' in Spinboxes_2 und _3, bis '4' in Spinbox_3. Wenn wir spinbox_1 von "0" nach "1" scrollen, bleibt spinbox_3 jedoch gleich - und erst wenn ich erneut klicke, ändert sich die Einstellung in "4". Zu diesem Zeitpunkt sollte sie von "4" auf "7" wechseln.

from tkinter import * 
import tkinter as tk 
root = Tk() 

sp1_values = [0, 1, 2] 
abc_values = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 

def set_default_in_sp3(args): 
    selected = var1.get() 
    idx = selected 
    lvl = var2.get() 
    if idx == 0: 
     if lvl == 'A': 
      var3.set(abc_values[0][0]) 
     if lvl == 'B': 
      var3.set(abc_values[0][1]) 
     if lvl == 'C': 
      var3.set(abc_values[0][2]) 
    if idx == 1: 
     if lvl == 'A': 
      var3.set(abc_values[1][0]) 
     if lvl == 'B': 
      var3.set(abc_values[1][1]) 
     if lvl == 'C': 
      var3.set(abc_values[1][2]) 
    if idx == 2: 
     if lvl == 'A': 
      var3.set(abc_values[2][0]) 
     if lvl == 'B': 
      var3.set(abc_values[2][1]) 
     if lvl == 'C': 
      var3.set(abc_values[2][2]) 

var1 = tk.IntVar() 
var2 = tk.StringVar() 
var3 = tk.IntVar() 

spinbox_1=tk.Spinbox(textvariable=var1, values=sp1_values) 
spinbox_1.pack() 
spinbox_1.bind('<Button-1>', set_default_in_sp3) 

spinbox_2=tk.Spinbox(values=('A', 'B', 'C'), textvariable = var2) 
spinbox_2.pack() 

spinbox_3=tk.Spinbox(from_=1, to=10, increment=1, textvariable = var3) 
spinbox_3.pack() 
spinbox_3.bind('<Button-1>', set_default_in_sp3) 

root.mainloop() 

In einer Antwort auf ein ähnliches Problem auch auf SO (Tkinter Label bound to StringVar is one click behind when updating) geschrieben, ein Listenfeld und ein Etikett wurde vorgeschlagen, dass „die beste Lösung für das virtuelle Ereignis beteiligt ist zu binden‚ListboxSelect‘, und so weit wie ich sehe, kann es für die Spinnbox Widget in Tkinter kein vergleichbares virtuelles Ereignis.

wie kann ich mich über dieses Problem zu lösen?

+0

'spinbox' hat ein Befehlsattribut, mit dem Sie eine Funktion angeben können, die nach einer Änderung aufgerufen werden soll. –

+0

Das scheint zu funktionieren - Danke. In dem Projekt, an dem ich arbeite, wurde das Befehlsattribut jedoch einer anderen Funktion für jede der Spinboxen zugewiesen. Gibt es eine Möglichkeit, einem Befehlsattribut mehrere Funktionen zuzuweisen? – MarkyMark

Antwort

2

wie @Bryan Oakley sagte, können Sie die command Option auf dem Spinbox es verwenden können, um eine Funktion anzugeben, die aufgerufen werden soll, wenn sie sich ändert und die Maustaste zu jedem. Ich bemerkte und entfernte auch etwas von dem wiederholten Code, den Sie in der Funktion set_default_in_sp3 hatten.

from tkinter import * 
import tkinter as tk 
root = Tk() 

sp1_values = [0, 1, 2] 
abc_values = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 

def set_default_in_sp3(*args): 
    idx = int(var1.get()) 
    lvl = var2.get() 
    if lvl == 'A': 
     var3.set(abc_values[idx][0]) 
    if lvl == 'B': 
     var3.set(abc_values[idx][1]) 
    if lvl == 'C': 
     var3.set(abc_values[idx][2]) 

var1 = tk.IntVar() 
var2 = tk.StringVar() 
var3 = tk.IntVar() 

spinbox_1=tk.Spinbox(textvariable=var1, values=sp1_values, command=set_default_in_sp3) 
spinbox_1.pack() 

spinbox_2=tk.Spinbox(values=('A', 'B', 'C'), textvariable=var2, command=set_default_in_sp3) 
spinbox_2.pack() 

spinbox_3=tk.Spinbox(from_=1, to=10, increment=1, textvariable=var3, 
        command=set_default_in_sp3) 
spinbox_3.pack() 

root.mainloop() 

Sie können nicht mehr Funktionen auf einen command Rückruf zuweisen, aber Sie können eine andere Funktion schreiben, die eine oder mehr andere Funktionen aufrufen und seinen Namen in den Spinbox Konstrukteure verwenden.

Verwandte Themen