Seite 1 von 1
Inhalt von Entry-Widget löschen
Verfasst: Sonntag 10. April 2011, 11:37
von tomkin
Ich möchte über ein Eingabefeld Ziffern eingeben lassen, diese werden danach verarbeitet, und anschließend soll der Inhalt des Felder wieder gelöscht werden. Dann kann die nächste Eingabe erfolgen.
Hier die dafür verwendeten Programmteile:
Code: Alles auswählen
def auswaehlen(eingabe):
# Zuvor Eingabe verarbeiten, dann Inhalt des Eingabefelds für nächste Eingabe löschen
eing.delete()
eing = tkinter.Entry(frame2,width=2,font="arial 11 bold")
eing.bind("1",auswaehlen)
eing.bind("3",auswaehlen)
eing.bind("2",auswaehlen)
eing.place(x=90,y=100)
Ergebnis:
Ich kann eingeben, jede Eingabe wird richtig verarbeitet, aber die Ziffer wird nicht wieder gelöscht. Es wird immer die neue Eingabe an die alte angefügt.
Fehlermeldung: "TypeError: delete() takes at least 2 positional arguments (1 given)"
Wenn ich in der Funktion
schreibe, dann kommt keine Fehlermeldung. Es wird aber auch nichts gelöscht.
Was mache ich falsch?
Re: Inhalt von Entry-Widget löschen
Verfasst: Sonntag 10. April 2011, 12:47
von Xynon1
Im Prinzip 3 Sachen:
1. "eing" ist bei dir auf Modulebene definiert und du greifst in der Funktion darauf zu, das ist nicht sehr schön.
2. Deine Eingabe ist ein Ereignis und keine Widget. Aber ein Ereignis hat ein "widget"-Attribute auf das man zugreifen kann und die Eingabe kann man über das "keysym"-Attribute erhalten.
Also so hier:
Code: Alles auswählen
import Tkinter as tkinter
def _input(event):
print event.keysym
event.widget.delete(0, "end")
if __name__ == "__main__":
root = tkinter.Tk()
entry = tkinter.Entry(root)
entry.bind("1", _input)
entry.bind("2", _input)
entry.bind("3", _input)
entry.pack(fill="x")
root.mainloop()
3. Das wichtigste aber ist, das ein Event vor dem Eintrag der Zahl in das Widget ausgelöst wird und damit immer nur der vorherige Inhalt gelöscht werden kann. Möchtest du dennoch das Feld nach der Eingabe löschen, müsstest du die "delete"-Funktion wohl mit einer "after"-Methode aufrufen müssen.
Re: Inhalt von Entry-Widget löschen
Verfasst: Sonntag 10. April 2011, 16:04
von tomkin
Vielen Dank! Genau so soll's funktionieren. Die letzte Eingabe soll solange im Eingabefeld stehen bleiben, bis die neue kommt, und das tut's. Danke nochmal!
Re: Inhalt von Entry-Widget löschen
Verfasst: Montag 11. April 2011, 17:22
von tomkin
Hm.. das nächste Problem. Sorry, ich bin noch Python-Anfänger
Wenn ich nun die Eingabe mit
in eine Variable speichere, wie kann ich das Programm dann auf die ESC-Taste und die Pfeiltasten reagieren lassen.
beispielsweise für die Escape-Taste funktioniert leider nicht.
Re: Inhalt von Entry-Widget löschen
Verfasst: Montag 11. April 2011, 17:32
von Xynon1
Ist ja auch Blödsinn

, wir arbeiten hier mit etwas modeneren Mitteln (20+ Jahre alt).
Spaß bei Seite, du bekommst bei Escape eine String bei keysym und zwar taadaa "Escape". Ich vermute mal du mal du hast den Auslöser nicht richtig gesetzt, müsste so hier gehen
Eine Übersticht über die Events kannst du dir hier verschaffen:
http://effbot.org/tkinterbook/tkinter-e ... ndings.htm
Wenn du aber lieber mit der 27 arbeitest, dann musst du "keycode" statt keysym nehmen.
Re: Inhalt von Entry-Widget löschen
Verfasst: Montag 11. April 2011, 20:19
von tomkin
Wow, es ist alles viel einfacher als ich dachte!
zum Beispiel für die linke Pfeiltaste.
Ich liebe Python jetzt schon!
Re: Inhalt von Entry-Widget löschen
Verfasst: Montag 11. April 2011, 20:30
von Xynon1
Das hat allerdings nicht viel mit Python zutun, sonder mit Tk. Aber mit Python ist Tk wesentlich schöner zu handhaben als mit tcl oder perl.
Re: Inhalt von Entry-Widget löschen
Verfasst: Montag 11. April 2011, 22:06
von tomkin
Hm.. weiter geht's mit meinen Fragen
Ich gebe nun eine Ziffer ein, mit der das Programm arbeitet.
Von da an werden bis zur Eingabe von <Escape> nur mehr Eingaben über die Pfeiltasten oder eben <Escape> erwartet.
Das Problem ist nun folgendes:
Wenn ich nun trotzdem etwas anderes eingebe, soll das sofort wieder aus dem Widget gelöscht werden und die Ziffer der ersten Eingabe dort stehen bleiben. Mit
bleibt immer die aktuelle Eingabe im Feld. Ich dachte eigentlich,
würde funktionieren und die letzte Eingabe wieder löschen, tut es aber nicht. Ist das ein Fall, wo ich diese after-Methode (von der ich natürlich keine blassen Schimmer habe, was die tut und wie sie funktioniert) verwenden muss?
Und das nächste Problem:
Code: Alles auswählen
eing.bind("1",ersteauswahl)
eing.bind("2",ersteauswahl)
eing.bind("3",ersteauswahl)
eing.bind("4",ersteauswahl)
eing.bind("5",ersteauswahl)
eing.bind("6",ersteauswahl)
eing.bind("7",ersteauswahl)
eing.bind("8",ersteauswahl)
eing.bind("9",ersteauswahl)
eing.bind("<Escape>",escape)
Left, Right, Up und Down werden auch noch Funktionen auslösen.
Alle anderen Eingaben sollen dann die gleiche Funktion (wieder eine zum Löschen der Neueingabe) auslösen. Aber wie mache ich eing.bind für "alle anderen"?
Re: Inhalt von Entry-Widget löschen
Verfasst: Montag 11. April 2011, 22:26
von BlackJack
"Für alle anderen" wird wohl nicht gehen, wohl aber "für alle". Das ist im ersten Beispiel auf der verlinkten `Tkinter`-Seite von Effbot zu sehen. Und was `after()` macht, kann man da auch irgendwo nachlesen.
Edit: Für alle anderen geht doch. Einfach mal die Seite dort durchlesen.
Re: Inhalt von Entry-Widget löschen
Verfasst: Montag 11. April 2011, 22:42
von Xynon1
@BlackJack
Jetzt habe ich mir schon solche Mühe gemacht
Das könnte man so realisieren:
Code: Alles auswählen
def delete(widget):
widget.delete(1, "end")
def _input(event):
widget = event.widget
if event.keysym in "0123456789":
widget.delete(0, "end")
elif event.keysym == "Escape":
pass
else:
widget.after(10, delete, widget)
if __name__ == "__main__":
root = tkinter.Tk()
entry = tkinter.Entry(root)
entry.bind("<Key>", _input)
entry.pack(fill="x")
root.mainloop()
Also bindet alle Key-Events an das Entry und entscheidet dann in der Funktion wie diese behandelt werden. Wird eine Zahl von 0-9 gewählt, so soll alles vorherige gelöscht werden. Wenn anderer Tasten gedrückt werden, wird auch irgendwas gemacht. Und sollte die Taste nicht definiert sein so wird alles hinter der Zahl mit der "after"-Methode gelöscht. Nochmmal zur Erinnerung die "after"-Methode ist hier nicht sehr schön, da sie Zeit gesteuert ist. Jedes Widget hat diese Methode, kann also von jedem genutzt werden. Die Wirkung ist einfach nur das eine Funktion nach einer bestimmten Zeit, 1. Parameter in Millisekunden, gerufen wird. Der 2. Parameter ist dann die Funktion und der 3., 4., ... die Paramter die an die Funktion übermittelt werden sollen. Hier nochmal zum nachlesen:
http://effbot.org/tkinterbook/widget.ht ... ter-method
Eventuell wäre ein Label für diese Art besser geeignet, dem könnte man vorschreiben, was es anzeigen soll und was nicht. Und nicht unerwünchtes hintenherum wieder löschen. Das könnte dann in etwa so aussehen:
Code: Alles auswählen
def _input(event):
if event.keysym in "123456789":
event.widget.config(text=event.keysym)
elif event.keysym == "Escape":
pass
if __name__ == "__main__":
root = tkinter.Tk()
label = tkinter.Label(root, width=30, takefocus=True)
label.bind("<Key>", _input)
label.pack(fill="x")
label.focus_set()
root.mainloop()
Re: Inhalt von Entry-Widget löschen
Verfasst: Dienstag 12. April 2011, 00:08
von BlackJack
@Xynon1: So könnte man es natürlich auch machen.