Seite 1 von 1
Kommandoaufruf nach Wertänderung eines Radiobuttons bei tkin
Verfasst: Freitag 4. Juli 2014, 09:41
von Papp Nase
Hi,
ich hab mir ein kleines Programm mit drei Radiobuttons geschrieben:
Code: Alles auswählen
import tkinter
def RadioButtonFunction (Variable):
print ("\n Die Variable des Radiobuttons ist: " + str(Variable))
def start_tkinter ():
root = tkinter.Tk()
RadioButtonValue=tkinter.StringVar()
RadioButtonValue.set("Button3")
widget1 = tkinter.Radiobutton(root, value="Button1", text="Button 1", variable=RadioButtonValue, pady=100, command=RadioButtonFunction(RadioButtonValue.get()))
widget1.pack()
widget2 = tkinter.Radiobutton(root, value="Button2", text="Button 2", variable=RadioButtonValue, command=RadioButtonFunction(RadioButtonValue.get()))
widget2.pack()
widget3 = tkinter.Radiobutton(root, value="Button3", text="Button 3", variable=RadioButtonValue, command=RadioButtonFunction(RadioButtonValue.get()))
widget3.pack()
root.mainloop()
return (RadioButtonValue.get())
def main():
print ("in main")
backwert = start_tkinter()
print ("nach tkinter, backwert = " + str(backwert))
if __name__ == '__main__':
main()
Hier auf dieser Seite steht:
http://www.tutorialspoint.com/python/tk_radiobutton.htm
Eigenschaft command= Routine wird gestartet, wenn Wert des Radiobuttons verändert wird.
Beim Starten des Programms wird 3mal die Routine RadioButtonFunction ausgeführt. Aber wenn ich dann in dem Fenster die Radiobuttons anklicke, dann wird die Funktion nicht nochmal aufgerufen - das verstehe ich nicht, denn ich hab doch extra mit command=RadioButton... definiert, dass dann die Routine ausgeführt werden soll.
Kann mir von Euch vielleicht jemand weiterhelfen?
Re: Kommandoaufruf nach Wertänderung eines Radiobuttons bei
Verfasst: Freitag 4. Juli 2014, 09:47
von EyDu
Hallo.
Du musst die Funktion an command binden. Momentan führst du jedoch die Funktion aus und bindest dessen Ergebnis an command.
Re: Kommandoaufruf nach Wertänderung eines Radiobuttons bei
Verfasst: Freitag 4. Juli 2014, 10:00
von Papp Nase
Danke für die Info. Ich hab das jetzt so gelöst, dass ich die Klammern am Ende der Funktion weggelassen hab, also nicht command=tuwas(), sondern command=tuwas.
Wenn ich dann Werte übergeben will, muss ich das dann mittels globaler Variablen tun, um Daten hin- und herzuschaufeln?
Re: Kommandoaufruf nach Wertänderung eines Radiobuttons bei
Verfasst: Freitag 4. Juli 2014, 10:05
von darktrym
Man kann auch die Handles zurückgeben lassen oder löst das mittels Klassen. Global ist immer die schlechteste Lösung.
Re: Kommandoaufruf nach Wertänderung eines Radiobuttons bei
Verfasst: Freitag 4. Juli 2014, 10:10
von Papp Nase
Danke für die Antwort.
Kannst Du mir einen Tipp geben, was Du mit Klassen meinst? Ich vermute mal, dass ich mir eine Klasse definiere, in der ich den Variablenwert speichere und dann diese Klasse von den verschiedenen Funktionen aufrufe, um Werte zu schreiben oder zu lesen?
Re: Kommandoaufruf nach Wertänderung eines Radiobuttons bei
Verfasst: Freitag 4. Juli 2014, 10:22
von darktrym
Wenn du den Zugriff auf widget* brauchst, würde ich die Handles als Klassenattribute sichern. So kann auch jede Klassenmethode nach belieben darauf zugreifen. Alternativ gibts du deine Handles als Tupel zurück und schleifst die durch wo immer sie gebraucht werden.
Re: Kommandoaufruf nach Wertänderung eines Radiobuttons bei
Verfasst: Freitag 4. Juli 2014, 10:29
von EyDu
Papp Nase hat geschrieben:Danke für die Info. Ich hab das jetzt so gelöst, dass ich die Klammern am Ende der Funktion weggelassen hab, also nicht command=tuwas(), sondern command=tuwas.
Richtig. Damit übergist du die Funktion und rufst sie nicht vorher auf. Funktionen sind, wie alles was du in Python an einen Namen binden kannst, ganz normale Objekte. Du kannst sie also beliebig durch die Gegend reichen.
Papp Nase hat geschrieben:Wenn ich dann Werte übergeben will, muss ich das dann mittels globaler Variablen tun, um Daten hin- und herzuschaufeln?
Nein, am besten vergisst du, dass es globale Variablen überhaupt gibt. Die sind nur in sehr sehr seltenen Fällen wirklich sinnvoll. Klassen brauchst du in diesem Fall auch nicht, das kannst du einfacher lösen. Zum Beispiel kannst du der callback-Funktion auch Werte übergeben:
Code: Alles auswählen
import functools
def callback(value, event):
v = value.get()
...
widget1 = tkinter.Radiobutton(root, value="Button1", text="Button 1", variable=RadioButtonValue, pady=100, command=functools.partial(RadioButtonFunction, RadioButtonValue))
In diesem Fall ist das aber überflüssig, da der event-Parameter der callback-Funktion bereits das angeklickte Widget als Attribut enthält. Zu dem Widget bekommst du dann auch die dazugehörige Variable raus.
Bei der Gelegenheit solltest du einen Blick in PEP 8 werfen, deine Namensgebung ist etwas unschön. "RadioButtonValue" impliziert, dass es sich hierbei um einen Typ handelt, die übliche Schreibweise lautet "radio_button_value". Selbiges gilt für "RadioButtonFunction".
Auch solltest du dir gar nicht erst angewöhnen Namen zu nummerieren, da solltest du besser geeignete Datenstrukruen wählen. Üblich sind Listen, Tupel oder Dictionaries. "return" ist zudem keine Funktion und sollte deshalb nicht wie eine behandelt werden. Lasse die Klammern um den Rückgabewert weg.
Was du "backwert" nennst, das nennt sich "Rückgabewert". Bei der Gelegenheit so noch angemerkt, dass du dich für eine Sprache entscheiden solltest. Entweder Deutsch oder Englisch. Eine Mischung aus beidem ist etwas gruselig.
Re: Kommandoaufruf nach Wertänderung eines Radiobuttons bei
Verfasst: Samstag 5. Juli 2014, 10:18
von BlackJack
@Papp Nase: `tkinter` wird üblicherweise als `tk` importiert, damit das nicht so oft ausgeschrieben im Quelltext stehen muss.
Die Leerzeichensetzung zwischen Funktionsnamen und öffnender Klammer ist inkonsequent. Per Konvention gehört dort kein Leerzeichen hin.
Was die durchnummerierten Namen angeht: Da kann man in diesem Fall auch einfach immer den selben Namen verwenden, denn die `RadioButton`-Exemplare werden danach ja gar nicht mehr benötigt, oder man spaltet den Ausdruck nicht auf und gibt dem Ergebnis einfach gar keinen Namen. Da sich der Code für jeden Radiobutton nahezu identisch wiederholt, böte sich an der Stelle auch eine Schleife an wo die Unterschiede als Daten herausgezogen sind.
Code: Alles auswählen
from __future__ import print_function
try:
import Tkinter as tk
except ImportError:
import tkinter as tk
from functools import partial
def radio_button_function(variable):
print('\n Die Variable des Radiobuttons ist:', variable.get())
def start_tkinter():
radiobutton_data = [
('Button1', 'Button 1'),
('Button2', 'Button 2'),
('Button3', 'Button 3'),
]
root = tk.Tk()
variable = tk.StringVar(root, radiobutton_data[-1][0])
for value, text in radiobutton_data:
tk.Radiobutton(
root,
value=value,
text=text,
variable=variable,
command=partial(radio_button_function, variable)
).pack()
root.mainloop()
return variable.get()
def main():
print('in main')
result = start_tkinter()
print('nach tkinter, ergebnis =', result)
if __name__ == '__main__':
main()
Falls das ein beliebig einsetzbarer Dialog sein soll, dann ist das Verwenden von `Tk` ungünstig, denn davon darf es in einem Programm immer nur *ein* Exemplar geben. Zumindest zur gleichen Zeit. Man kann diese Funktion also nicht in GUI-Programmen verwenden in denen es schon ein `Tk`-Exemplar gibt. Für modale Dialoge gibt es in `tkinter.simpledialog` Klassen die man als Basis für eigene Dialoge nehmen kann.