Hallo Forumfreunde
Gib es eine Möglichkeit die aktuelle Cursor-Position in einem Entry-Widget als Index zurück zu lesen.
Besten Dank für eure Mühe.
Gruss wuf
Cursor-Position bei einem Entry-Widget
Das müsste die Methode
sein, die den aktuellen Index
(da, wo der Cursor blinkt)
zurückliefert.
yipyip
Code: Alles auswählen
my_entry.index(tk.INSERT)
(da, wo der Cursor blinkt)
zurückliefert.
yipyip
Hallo yipyip
Deine Antwort ist genau die Lösung vonach ich drei Stunden erfolglos gesucht und herumexperimentiert habe. Besten Dank für deine hilfreiche Unterstützung! Ich wollte ein Engabe-Widget konstruieren, welches als Eingabe nur Ziffern akzeptiert. Hier meine Lösung die wohl funktioniert aber sicher noch nicht das gelbe vom Ei ist:
Danke! Gruss wuf
Deine Antwort ist genau die Lösung vonach ich drei Stunden erfolglos gesucht und herumexperimentiert habe. Besten Dank für deine hilfreiche Unterstützung! Ich wollte ein Engabe-Widget konstruieren, welches als Eingabe nur Ziffern akzeptiert. Hier meine Lösung die wohl funktioniert aber sicher noch nicht das gelbe vom Ei ist:
Code: Alles auswählen
# Verfasser : wuf
# Skriptname: entry_num_filter_01.py
# Datum : 24.09.2008
import Tkinter as tk
from string import digits, printable
def entry_key_press(event=None):
cursor_pos = entry.index('insert')
if event.keysym in printable:
if event.keysym in digits:
return
else:
entry.after_idle(remove_char, cursor_pos)
def remove_char(cursor_pos):
entry.delete(cursor_pos)
root = tk.Tk()
root.geometry('200x100')
entry = tk.Entry(root, width=20, bg='white', bd=1,
highlightthickness=0)
entry.place(x=20,y=20)
entry.bind('<KeyPress>',entry_key_press)
entry.focus_set()
root.mainloop()
Take it easy Mates!
Korrektur:
event.keysym muss durch event.char ersetzt werden!
Noch ausstehende Mängel:
a) Umlaute werden noch nicht abgefangen
b) Die 'Ins'-Taste auf meinem Keyboard kopiert etwas aus der Zwischenablage ins Entry-Feld
event.keysym muss durch event.char ersetzt werden!
Noch ausstehende Mängel:
a) Umlaute werden noch nicht abgefangen
b) Die 'Ins'-Taste auf meinem Keyboard kopiert etwas aus der Zwischenablage ins Entry-Feld
Take it easy Mates!
Habe versucht, die Probleme a) und b) zu elimieren:
Ob's noch gelber geht ?
:K
yipyip
Code: Alles auswählen
import Tkinter as tk
import string
####
class My_entry(object):
def __init__(self, root):
self.svar = tk.StringVar()
self.entry = tk.Entry(root,
textvariable=self.svar,
width=20, bg='white', bd=1)
self.entry.bind('<Key>', self.filter_digits)
self.entry.pack()
self.entry.focus_set()
def filter_digits(self, ev):
self.s = ''.join([d for d in self.entry.get() if d in string.digits])
self.svar.set(self.s)
pos = self.entry.index(tk.INSERT)
if not ev.keysym in string.digits:
self.entry.after_idle(lambda i: self.entry.delete(i), pos)
####
root = tk.Tk()
e = My_entry(root)
root.mainloop()
####
:K
yipyip
Zuletzt geändert von yipyip am Donnerstag 25. September 2008, 18:33, insgesamt 1-mal geändert.
Doch, es geht noch gelber.
Jetzt funktioniert's auch mit dem Nummernblock.
yipyip
Code: Alles auswählen
import Tkinter as tk
import string
####
class My_entry(object):
def __init__(self, root):
self.svar = tk.StringVar()
self.entry = tk.Entry(root,
textvariable=self.svar,
width=20, bg='white', bd=1)
self.entry.bind('<Key>', self.filter_digits)
self.entry.pack()
self.entry.focus_set()
self.digits_kp = list(string.digits) + ['KP_' + c for c in string.digits]
def filter_digits(self, ev):
self.s = ''.join([d for d in self.entry.get() if d in string.digits])
self.svar.set(self.s)
pos = self.entry.index(tk.INSERT)
if not ev.char in self.digits_kp:
self.entry.after_idle(lambda i: self.entry.delete(i), pos)
####
root = tk.Tk()
e = My_entry(root)
root.mainloop()
####
yipyip
Zuletzt geändert von yipyip am Donnerstag 25. September 2008, 18:33, insgesamt 1-mal geändert.
Hallo yipyip
Danke, dass du dir noch die Mühe genommen hast mein Problem mit dem Entry-Filter genauer zu untersuchen. Dein Filter scheint absolut dicht zu sein gegen bekannte und unbekannte Tastatureingaben. Das mit der 'Ins'-Taste muss irgendwie auf Tcl-Ebene ablaufen ist vielleich schwierig zu unterbinden.
Jetzt besteht noch ein Problem mit den Steuertasten 'Home', 'End', pfeil-rechts, pfeil-links. Wenn du möchtest könntest du einmal folgendes ausprobieren
a) Gebe einige Ziffern ins Eingabefeld ein z.B. 0123456789
b) Schalte zwischen den 'Home' und 'End' hin und her.
c) Bewege den Cursor mit den Pfeil-Tasten hin und her
Bei diesem Versuch stellte ich auf meinem Notebook fest, dass eingegebene Nummern aus dem Eingabefeld gelöscht werden.
Ich habe mich auch noch weiter mit der Aufgabe beschäftigt. Ich möchte dir meine Variante nicht vorenthalten. Der Code ist noch nicht optimiert. Habe damit noch ein kleines Problem damit. Beim gleichzeitigen aktivieren von zwei Buchstabentasten rutscht ein Buchstabe durch das Filter und gelangt ins Eingabfeld. Funktionier übrigends bei deinem Code problemlos. Hier mein Code natürlich noch nicht auf einer Ebene wie du dich gewöhnt bist zu schreiben.
Danke. Gruss wuf
Danke, dass du dir noch die Mühe genommen hast mein Problem mit dem Entry-Filter genauer zu untersuchen. Dein Filter scheint absolut dicht zu sein gegen bekannte und unbekannte Tastatureingaben. Das mit der 'Ins'-Taste muss irgendwie auf Tcl-Ebene ablaufen ist vielleich schwierig zu unterbinden.
Jetzt besteht noch ein Problem mit den Steuertasten 'Home', 'End', pfeil-rechts, pfeil-links. Wenn du möchtest könntest du einmal folgendes ausprobieren
a) Gebe einige Ziffern ins Eingabefeld ein z.B. 0123456789
b) Schalte zwischen den 'Home' und 'End' hin und her.
c) Bewege den Cursor mit den Pfeil-Tasten hin und her
Bei diesem Versuch stellte ich auf meinem Notebook fest, dass eingegebene Nummern aus dem Eingabefeld gelöscht werden.
Ich habe mich auch noch weiter mit der Aufgabe beschäftigt. Ich möchte dir meine Variante nicht vorenthalten. Der Code ist noch nicht optimiert. Habe damit noch ein kleines Problem damit. Beim gleichzeitigen aktivieren von zwei Buchstabentasten rutscht ein Buchstabe durch das Filter und gelangt ins Eingabfeld. Funktionier übrigends bei deinem Code problemlos. Hier mein Code natürlich noch nicht auf einer Ebene wie du dich gewöhnt bist zu schreiben.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# Verfasser : wuf
# Skriptname: entry_num_filter_02.py
# Datum : 25.09.2008
# Funktion : Eingabe nur für Ziffern
import Tkinter as tk
from string import digits, printable, punctuation
def entry_key_press(event=None):
cursor_pos = entry.index('insert')
if event.char in printable:
if event.char in digits:
#~~ Nur Ziffern
return
else:
entry.after_idle(remove_char, cursor_pos)
if event.char in "äöüÄÖÜàéèÀÉȧ°ç£":
#~~ Umlaute und weitere Sonderzeichen
entry.after_idle(remove_char, cursor_pos)
def remove_char(cursor_pos):
entry.delete(cursor_pos)
root = tk.Tk()
root.geometry('200x100')
entry = tk.Entry(root, width=20, bg='white', bd=1,
highlightthickness=0)
entry.place(x=20,y=20)
entry.bind('<KeyPress>',entry_key_press)
entry.focus_set()
root.mainloop()
Take it easy Mates!
Ich hatte nicht berücksichtigt, dass 'Home' und 'End' zwar
ein Event erzeugen, aber kein zu löschendes Zeichen.
So herum funktioniert es bei mir:
Das sollte jetzt 'gelb' genug sein.
Dein Problem mit den 2 Buchstaben kann ich bei mir nicht
nachvollziehen, bei mir funktioniert's.
(Nur ein 'ß' lässt es noch durch.)
yipyip
P.S.
'Home' und 'End' gehen als Leerstring durch, sind daher auch in string.digits .
ein Event erzeugen, aber kein zu löschendes Zeichen.
So herum funktioniert es bei mir:
Code: Alles auswählen
#!/usr/bin/env python
import Tkinter as tk
import string
####
class My_entry(object):
def __init__(self, root):
self.svar = tk.StringVar()
self.entry = tk.Entry(root,
textvariable=self.svar,
width=20, bg='white', bd=1)
self.entry.bind('<Key>', self.filter_digits)
self.entry.pack()
self.entry.focus_set()
def filter_digits(self, ev):
in_str = self.entry.get()
self.s = ''.join([d for d in in_str if d in string.digits])
self.svar.set(self.s)
if ev.char in string.digits:
return
pos = self.entry.index(tk.INSERT)
self.entry.after_idle(lambda i: self.entry.delete(i), pos)
####
root = tk.Tk()
e = My_entry(root)
root.mainloop()
####
Dein Problem mit den 2 Buchstaben kann ich bei mir nicht
nachvollziehen, bei mir funktioniert's.
(Nur ein 'ß' lässt es noch durch.)
yipyip
P.S.
'Home' und 'End' gehen als Leerstring durch, sind daher auch in string.digits .
Zuletzt geändert von yipyip am Freitag 26. September 2008, 00:23, insgesamt 1-mal geändert.
Hallo yipyip
Danke für dein letztes Code-Snippet. Ich habe es auch wieder näher ausgetestet.
Feststellungen:
a) Test-1: Wie du schon erwähnt hast den Test mit TAB vorhandenen Ziffern markieren und mit einer Buchstabentaste den Text löschen hinterlässt den Buchstaben im Eingabefeld.
b) Test-2: Das gleiche gilt für die folgende Sequenz: HOME (setzt Cursor an den Anfang des im Eingabefeld vorhandenen Textes), SHIFT gedrückt plus END aktivieren (markiert den vorhandenen Text im Eingabefeld), eine Buchstabentaste aktivieren (löscht den markierten Text), zum Schluss steht auch wieder der zum löschen verwendete Buchstabe im Eingabefeld!
c) Test-3: Ziffern 0...9 ins Eingabefeld eintippen. Den Cursor mit der Pfeiltaste vor die Nummer 5 setzen und die DEL-Tatse aktivieren. Diese Aktion entfernt zwei Zeichen ab der Cursorposition!
d) Test-4: Wie du auch schon erwähnt hast hinterlässt das Aktivieren der INSERT-Taste Zeichen die sich momentan in der Zwischenablage befinden im Eingabefeld. Ist eine unschöne Sache. Muss eine Funktion auf Tcl-Ebene sein, die früher für das Einfügen aus der Zwischenablage verwendet wurde, welche für den neuzeitigen Einsatz von Tkinter nicht unterbunden wurde. Dies kann mit CTRL-V ausgeführt werden.
e) Test-5: Wie du sagtest hinterlässt das gleichzeitige betätigen zweier Buchstaben keine Buchstaben im Eingabefeld.
Habe diese Test mit meinem Skript ausgeführt und entsprechende Änderungen vorgenommen um die negativen Symptome zu eliminieren. Dies hatte nichts mehr mit 'strait forward programming' zu tun es ging eher in Richtung 'Teufel-Austreibung'.
Hier der letzte Stand meines Skriptes:
[Code ausgelagert]
Gruss wuf
Danke für dein letztes Code-Snippet. Ich habe es auch wieder näher ausgetestet.
Feststellungen:
a) Test-1: Wie du schon erwähnt hast den Test mit TAB vorhandenen Ziffern markieren und mit einer Buchstabentaste den Text löschen hinterlässt den Buchstaben im Eingabefeld.
b) Test-2: Das gleiche gilt für die folgende Sequenz: HOME (setzt Cursor an den Anfang des im Eingabefeld vorhandenen Textes), SHIFT gedrückt plus END aktivieren (markiert den vorhandenen Text im Eingabefeld), eine Buchstabentaste aktivieren (löscht den markierten Text), zum Schluss steht auch wieder der zum löschen verwendete Buchstabe im Eingabefeld!
c) Test-3: Ziffern 0...9 ins Eingabefeld eintippen. Den Cursor mit der Pfeiltaste vor die Nummer 5 setzen und die DEL-Tatse aktivieren. Diese Aktion entfernt zwei Zeichen ab der Cursorposition!
d) Test-4: Wie du auch schon erwähnt hast hinterlässt das Aktivieren der INSERT-Taste Zeichen die sich momentan in der Zwischenablage befinden im Eingabefeld. Ist eine unschöne Sache. Muss eine Funktion auf Tcl-Ebene sein, die früher für das Einfügen aus der Zwischenablage verwendet wurde, welche für den neuzeitigen Einsatz von Tkinter nicht unterbunden wurde. Dies kann mit CTRL-V ausgeführt werden.
e) Test-5: Wie du sagtest hinterlässt das gleichzeitige betätigen zweier Buchstaben keine Buchstaben im Eingabefeld.
Habe diese Test mit meinem Skript ausgeführt und entsprechende Änderungen vorgenommen um die negativen Symptome zu eliminieren. Dies hatte nichts mehr mit 'strait forward programming' zu tun es ging eher in Richtung 'Teufel-Austreibung'.
Hier der letzte Stand meines Skriptes:
[Code ausgelagert]
Gruss wuf
Take it easy Mates!
Danke für den Hinweis auf die Doppel-Löschung,
hab's auch gleich bei mir verbessert.
Zu e)
Um Missverstaendnissen vorzubeugen:
Ich hatte ursprünglich gemeint, dass ich bei
*Deinem* Programm den Doppelbuchstabenfehler nicht
reproduzieren konnte.
Für meinen Geschmack geht das Ganze in die Richtung,
*gegen* die Gui zu programmieren.
(Du hast den Aufwand ja gemerkt ... )
Vielleicht wäre ja auch z.B. eine Matrix aus Ziffern-Buttons
die Alternative?
yipyip
hab's auch gleich bei mir verbessert.
Zu e)
Um Missverstaendnissen vorzubeugen:
Ich hatte ursprünglich gemeint, dass ich bei
*Deinem* Programm den Doppelbuchstabenfehler nicht
reproduzieren konnte.
Für meinen Geschmack geht das Ganze in die Richtung,
*gegen* die Gui zu programmieren.
(Du hast den Aufwand ja gemerkt ... )
Vielleicht wäre ja auch z.B. eine Matrix aus Ziffern-Buttons
die Alternative?
yipyip
Hier meine (hoffentlich ) letzte Version:
Bei Tab+Buchstabe und nichtleerem Eingabefeld erscheint
zwar der Buchstabe, dieser wird aber nicht übernommen.
Probiere mal mit Deiner letzten Version bei
nichtleerem Eingabefeld:
Ende+Shift(L oder R) gedrückt halten, dann Buchstabentaste (z.B. 'S')
yipyip
Code: Alles auswählen
#!/usr/bin/env python
import Tkinter as tk
import string
####
class My_entry(object):
def __init__(self, root):
self.svar = tk.StringVar()
self.entry = tk.Entry(root,
textvariable=self.svar,
width=20, bg='white', bd=1)
self.entry.bind('<KeyPress>', self.filter_digits)
self.entry.pack()
self.entry.focus_set()
def filter_digits(self, ev):
in_str = self.entry.get()
self.s = ''.join([d for d in in_str if d in string.digits])
self.svar.set(self.s)
#print ev.keysym
#print ev.char
if ev.keysym in ['Delete']:
return
if ev.char in string.digits:
return
pos = self.entry.index(tk.INSERT)
self.entry.after_idle(lambda i: self.entry.delete(i), pos)
#print self.svar.get()
####
root = tk.Tk()
e = My_entry(root)
root.mainloop()
####
zwar der Buchstabe, dieser wird aber nicht übernommen.
Probiere mal mit Deiner letzten Version bei
nichtleerem Eingabefeld:
Ende+Shift(L oder R) gedrückt halten, dann Buchstabentaste (z.B. 'S')
yipyip
Hallo yipyip
Danke für den Tipp. Da ist wirklich noch etwas anzuschauen.
Ich befürchte es ist immer noch nicht das Ende der Geschichte. Ich habe deine letzte Variante noch ausprobiert. Probier mal die Ziffern 0....9 einzugeben. Dann fahre den Cursor in die Mitte der Eingabe und drücke die ENTER-Taste. Hier wird die Ziffer neben dem Cursor gelöscht.
Mein Setup hier ist: Python2.5, SuSE10.0, Notebook TOSHIBA-Satellite
(eventuell kann die Harsware auch noch eine Rolle spielen, was ich nicht hoffe)
OK 'yipyip' ich werden noch weiterforschen. Bei weiteren Erfolgen werde ich dich informieren.
Gruss wuf
Danke für den Tipp. Da ist wirklich noch etwas anzuschauen.
Ich befürchte es ist immer noch nicht das Ende der Geschichte. Ich habe deine letzte Variante noch ausprobiert. Probier mal die Ziffern 0....9 einzugeben. Dann fahre den Cursor in die Mitte der Eingabe und drücke die ENTER-Taste. Hier wird die Ziffer neben dem Cursor gelöscht.
Mein Setup hier ist: Python2.5, SuSE10.0, Notebook TOSHIBA-Satellite
(eventuell kann die Harsware auch noch eine Rolle spielen, was ich nicht hoffe)
OK 'yipyip' ich werden noch weiterforschen. Bei weiteren Erfolgen werde ich dich informieren.
Gruss wuf
Take it easy Mates!
Hallo wuf !
Evt. hilft dir das weiter oder es ist einfach nur dein Problem nicht verstanden.
http://paste.pocoo.org/show/86337/
gruss frank
Evt. hilft dir das weiter oder es ist einfach nur dein Problem nicht verstanden.
http://paste.pocoo.org/show/86337/
gruss frank
Hallo kaytec
Danke für deinen komplett neuen Lösungsansatz. Werde deine Idee noch eingehender studieren. Das Eingabe-Feld muss ein Feld sein dessen Funktionalität dem eines Tk-Entry-Widget mit all seinen Steuerfunktionen wie TAB, DEL, END, HOME, ENTER usw. entspricht. Wie ich sehe benützt du ein Label-Widget. OK wie gesagt ich muss deine Variante noch genauer anschauen.
Es muss schlussendlich ein Eingabe-Widget werden in dem nur gewünschte Zeichen aufgenommen werden.
(Gut ich könnte das Entry-Widget von Pmw nehmen, aber ich möchte fur die GUI nur Tkinter importieren)
Besten Dank! Gruss wuf
Danke für deinen komplett neuen Lösungsansatz. Werde deine Idee noch eingehender studieren. Das Eingabe-Feld muss ein Feld sein dessen Funktionalität dem eines Tk-Entry-Widget mit all seinen Steuerfunktionen wie TAB, DEL, END, HOME, ENTER usw. entspricht. Wie ich sehe benützt du ein Label-Widget. OK wie gesagt ich muss deine Variante noch genauer anschauen.
Es muss schlussendlich ein Eingabe-Widget werden in dem nur gewünschte Zeichen aufgenommen werden.
(Gut ich könnte das Entry-Widget von Pmw nehmen, aber ich möchte fur die GUI nur Tkinter importieren)
Besten Dank! Gruss wuf
Take it easy Mates!
Hallo wuf,
dass die Enter-Taste löscht, habe ich eher
als Feature denn als Bug angesehen.
Hier nochmal eine Version *ohne* 'Enter' und 'Return':
http://paste.pocoo.org/show/86353/
Kaytec's Label-Lösung find' ich gut.
Daher hier eine kleine Erweiterung:
http://paste.pocoo.org/show/86354/
yipyp
dass die Enter-Taste löscht, habe ich eher
als Feature denn als Bug angesehen.
Hier nochmal eine Version *ohne* 'Enter' und 'Return':
http://paste.pocoo.org/show/86353/
Kaytec's Label-Lösung find' ich gut.
Daher hier eine kleine Erweiterung:
http://paste.pocoo.org/show/86354/
yipyp
Hallo yipyip
Danke für deine Skripte. Bin leider zeitlich verhindert gewesen mich weiter mit dem Problem zu beschäftigen. Dein erstes Skript verhält sich was die ENTER betrifft für meinen Einsatz richtig. Aber wie schon angedeutet es ist noch nicht das Ende der Geschichte. Was ich mit meinem und deinem Skript festgestellt habe ist, wenn du etwas mit SHIFT plus Rechts-Taste markierst und mit einer Buchstaben-Taste löscht bleibt der Buchstabe im Eingabefeld zurück. Passiert aber nicht, wenn du mit SHIFT plus Links-Taste markierst.
Mit der Label-Variante muss ich mich noch näher beschäftigen.
Hier mein letzter Wurf:
[Code ausgelagert]
Gruss wuf
Danke für deine Skripte. Bin leider zeitlich verhindert gewesen mich weiter mit dem Problem zu beschäftigen. Dein erstes Skript verhält sich was die ENTER betrifft für meinen Einsatz richtig. Aber wie schon angedeutet es ist noch nicht das Ende der Geschichte. Was ich mit meinem und deinem Skript festgestellt habe ist, wenn du etwas mit SHIFT plus Rechts-Taste markierst und mit einer Buchstaben-Taste löscht bleibt der Buchstabe im Eingabefeld zurück. Passiert aber nicht, wenn du mit SHIFT plus Links-Taste markierst.
Mit der Label-Variante muss ich mich noch näher beschäftigen.
Hier mein letzter Wurf:
[Code ausgelagert]
Gruss wuf
Take it easy Mates!
...mmmh...
... bei Shift+Rechts+Buchstabentaste erscheinen bei *Deinem* Programm
keine Buchstaben, dafür aber bei
Tab+Ende+Buchstabentaste...
Ich halte das Ganze sowieso nicht für eine
so gute Idee, dem Entry-Widget so ins Handwerk
zu pfuschen, ich würde an Deiner Stelle
vielleicht doch lieber einen prinzipiell
anderen Ansatz vorziehen.
Ist das bei Deiner Aufgabe nicht möglich?
(Im Moment fällt mir für das Entry-Widget
nix Sinnvolles mehr ein )
:K
yipyip
... bei Shift+Rechts+Buchstabentaste erscheinen bei *Deinem* Programm
keine Buchstaben, dafür aber bei
Tab+Ende+Buchstabentaste...
Ich halte das Ganze sowieso nicht für eine
so gute Idee, dem Entry-Widget so ins Handwerk
zu pfuschen, ich würde an Deiner Stelle
vielleicht doch lieber einen prinzipiell
anderen Ansatz vorziehen.
Ist das bei Deiner Aufgabe nicht möglich?
(Im Moment fällt mir für das Entry-Widget
nix Sinnvolles mehr ein )
:K
yipyip
Hallo yipyip
Deine Feststellung hat sich auch bei mir bestätigt. Stimmt es ist aufwendig das Entry-Widget zu bändigen. Trotzdem forsche ich weiter und möchte ich dir hierbei nochmals danken für deine grosszügige Unterstützung.
Gruss wuf
Deine Feststellung hat sich auch bei mir bestätigt. Stimmt es ist aufwendig das Entry-Widget zu bändigen. Trotzdem forsche ich weiter und möchte ich dir hierbei nochmals danken für deine grosszügige Unterstützung.
Gruss wuf
Take it easy Mates!