Exactement comme le dit la question. Les widgets Text
ont l'événement <>
, mais les widgets Entry
ne semblent pas l'avoir.
Réponses
Trop de publicités?J'utilise Python 3.6 et je n'ai pas réussi à faire fonctionner .trace. Le code suivant permet d'accepter ou de modifier une valeur par défaut de StringVar. on_changed est appelé lorsque la touche de retour est pressée.
from tkinter import Tk, LEFT, BOTH, StringVar
from tkinter.ttk import Entry, Frame
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("Entry")
self.pack(fill=BOTH, expand=1)
self.contents = StringVar()
# donner à StringVar une valeur par défaut
self.contents.set('test')
self.entry = Entry(self)
self.entry.pack(side=LEFT, padx=15)
self.entry["textvariable"] = self.contents
self.entry.bind('', self.on_changed)
def on_changed(self, event):
print('contents: {}'.format(self.contents.get()))
return True
def main():
root = Tk()
ex = Example(root)
root.geometry("250x100+300+300")
root.mainloop()
if __name__ == '__main__':
main()
Je connais une autre variante.
avant d'entrer le code, il serait préférable d'expliquer le chemin du codage : lire ici
et voici mon code:
from Tkinter import *
class ttt:
def __init__(self):
self.str1 = StringVar()
self.e1 = Entry(root, textvariable=self.str1)
self.str1.trace('w', self.callback_1)
self.e1.pack()
self.str2 = StringVar()
self.e2 = Entry(root, textvariable=self.str2, state='readonly')
self.e2.pack()
self.str3 = StringVar()
self.e3 = Entry(root, textvariable=self.str3, state='readonly')
self.e3.pack()
bt = Button(root, text = 'ещё', command = self.callback_2)
bt.pack()
def callback_1(self, name='', index='', mode=''):
tmp = self.str1.get()
if tmp:
self.str2.set(int(tmp) * 6)
print self.str2.get()
def callback_2(self, name='', index='', mode=''):
tmp = self.str1.get()
if tmp:
self.str3.set(int(tmp) * 6)
print self.str3.get()
root = Tk()
t = ttt()
root.mainloop()
il y a 2 variantes : en appuyant sur le bouton et en entrant dans l'entrée. maintenant vous pouvez choisir n'importe quelle variante
J'ai trouvé que l'utilisation de la Validation TK intégrée correspondait mieux à mon niveau de compétence débutant en python. La validation d'un élément Entry n'est pas bien documentée dans tkinter lui-même, vous devez utiliser une méthode register() pour définir un rappel, et en toujours retournant True à partir du rappel de validation enregistré, vous pouvez recevoir une notification.
def filter_callback(self,nouvelle_valeur):
print(nouvelle_valeur)
# doit retourner vrai car nous voulons que les événements de validation continuent à arriver
return(True)
def __init__(self,root)
self.edit_filter = ttk.Entry(root)
# %d = Type d'action (1=insertion, 0=suppression, -1 pour les autres)
# %i = index du caractère de la chaîne à insérer/supprimer, ou -1
# %P = valeur de l'entrée si la modification est autorisée
# %s = valeur de l'entrée avant l'édition
# %S = la chaîne de texte insérée ou supprimée, le cas échéant
# %v = le type de validation actuellement défini
# %V = le type de validation qui a déclenché le rappel
# (clé, focusin, focusout, forcé)
# %W = le nom tk du widget
vcmd = (self.edit_filter.register(self.filter_callback), "%P")
# notifier uniquement les pressions de touche
self.edit_filter.config(validate = "key", validatecommand = vcmd)
(code illustratif seulement)
Exemple de réponse ici Validation interactive du contenu du widget Entry dans tkinter, et quelques docs sur les événements ici https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/entry-validation.html. Ce n'est pas moins de code que l'utilisation de trace, mais peut être plus facile à suivre pour certains débutants et à construire.
Ceci est mon interprétation basée sur la réponse de @Avi ba. Je l'ai simplifié en ajoutant un setter et un getter pour la variable de texte. J'ai également évité d'utiliser StrinVar
.
class CustomEntry(ttk.Entry):
def __init__(self, parent, valueChangeCallback=lambda x: print(x), **kwargs):
super().__init__(parent, **kwargs)
# lier la fonction de rappel lorsque la valeur du texte est changée
self.bind("", lambda e: valueChangeCallback(self.text))
@property
def text(self) -> str:
return self.get()
@text.setter
def text(self, value) -> None:
self.delete(0, 'end')
self.insert(0, value)
- Réponses précédentes
- Plus de réponses