Label aus Wert von Spinbox aktualisieren

Fragen zu Tkinter.
Antworten
lernePython
User
Beiträge: 18
Registriert: Freitag 3. Februar 2017, 20:01

Ich habe eine Spinbox und möchte, dass sich ein Label, jedes mal wenn die Spinbox 'bedient' wird, aktualisiert.
Offensichtlich funktioniert validatecommand bei Spinbox nicht - jedenfalls habe ich es nicht hinbekommen.
Für Tipps bin ich dankbar.
BlackJack

@lernePython: Reicht Dir eventuell einfach ein `*Var`-Objekt aus?

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8
from __future__ import absolute_import, division, print_function
import Tkinter as tk


def main():
    root = tk.Tk()
    variable = tk.IntVar()
    tk.Spinbox(root, from_=0, to=100, textvariable=variable).pack()
    tk.Label(root, textvariable=variable).pack()
    root.mainloop()


if __name__ == '__main__':
    main()
lernePython
User
Beiträge: 18
Registriert: Freitag 3. Februar 2017, 20:01

sorry, das war mein Fehler, ich hab meine Aufgabe nicht genau genug beschrieben.
mit jeder Wertänderung in der Spinbox, möchte ich mit dem Wert, den ich erhalte eine Rechenfunktion auslösen und diesen Wert im Label dann jeweils aktualisieren.
in der Art :
Spinbox 10 --> Label 5 (10/2)
Spinbox 20 --> Label 10 (20/2)
Spinbox 30 --> Label 15 (30/2)
BlackJack

@lernePython: Dafür könnte man Schreibzugriffe auf das `IntVar`-Objekt verfolgen:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8
from __future__ import absolute_import, division, print_function
import Tkinter as tk
from functools import partial


def update(variable, label, *_args):
    try:
        result = variable.get() / 2
    except ValueError:
        result = ''
    label['text'] = result


def main():
    root = tk.Tk()
    variable = tk.IntVar()
    tk.Spinbox(root, from_=0, to=100, textvariable=variable).pack()
    label = tk.Label(root)
    label.pack()
    variable.trace('w', partial(update, variable, label))
    root.mainloop()
 
 
if __name__ == '__main__':
    main()
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

lernePython hat geschrieben:Ich habe eine Spinbox und möchte, dass sich ein Label, jedes mal wenn die Spinbox 'bedient' wird, aktualisiert.
Offensichtlich funktioniert validatecommand bei Spinbox nicht - jedenfalls habe ich es nicht hinbekommen.
Für Tipps bin ich dankbar.
Also, die Beispiele, die von anderer Seite gezeigt wurden, funktionieren nicht richtig. Denn die Rechenfunktion soll ja nicht schon bei jedem Tastendrücken beim Eintippen ausgelöst werden, sondern erst, wenn man fertig getippt hat. Also braucht es ein Binding auf FocusOut, Return und auch auf command.

Hier ist ein Beispiel für ein Entryfeld. Da sollte ein Vorgang aber erst ausgelöst werden, wenn sich der Wert geändert hatte.
Für die Spinbox mußt Du eben noch den command hinzufügen und den Vergleich auf Änderung und das mit StringVar und FocusIn kannst Du herausnehmen.

Code: Alles auswählen

# -*- coding: utf-8 -*-

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk

class Application(tk.Tk):

    def __init__(self,**kwargs):
        tk.Tk.__init__(self,**kwargs)
        # widget definitions ===================================
        self.entry1 = tk.Entry(self)
        self.entry1.grid(row=0, padx=4)
        self.entry2 = tk.Entry(self)
        self.entry2.grid(row=0, column=1, padx=4)
        self.entry3 = tk.Entry(self)
        self.entry3.grid(row=0, column=2, padx=4)
        self.wert1 = tk.Label(self,text='wert1')
        self.wert1.grid(row=1)
        self.wert2 = tk.Label(self,text='wert2')
        self.wert2.grid(row=1, column=1)

        self.entry1.value=tk.StringVar()
        self.entry1.bind('<FocusIn>',lambda event,entry = self.entry1: entry.value.set(entry.get()))
        self.entry1.bind('<FocusOut>',lambda event,entry = self.entry1: self.check_change(entry))
        self.entry1.bind('<Return>',lambda event,entry = self.entry1: self.check_change(entry))


        self.entry2.value=tk.StringVar()
        self.entry2.bind('<FocusIn>',lambda event,entry = self.entry2: entry.value.set(entry.get()))
        self.entry2.bind('<FocusOut>',lambda event,entry = self.entry2: self.check_change(entry))
        self.entry2.bind('<Return>',lambda event,entry = self.entry2: self.check_change(entry))
        

    def check_change(self,entry):
        if entry.value.get() != entry.get():
            entry.value.set(entry.get())
            self.wert1['text'] = self.entry1.get()
            self.wert2['text'] = self.entry2.get()
            print('changed: ',self.entry1.get(),self.entry2.get())

if __name__ == '__main__':
    Application().mainloop()
Antworten