web-dev-qa-db-fra.com

Comment définir le texte/valeur/contenu d'un widget `Entry` en utilisant un bouton dans tkinter

J'essaie de définir le texte d'un widget Entry à l'aide d'un bouton d'une interface graphique utilisant le module tkinter.

Cette interface graphique m'aide à classer des milliers de mots en cinq catégories. Chacune des catégories a un bouton. J'espérais que l'utilisation d'un bouton m'accélérerait de manière significative et je voudrais vérifier les mots à chaque fois sinon je voudrais simplement utiliser le bouton et laisser l'interface graphique traiter le mot actuel et apporter le mot suivant.

Les boutons de commande pour une raison quelconque ne se comportent pas comme je le souhaite. Ceci est un exemple:

win = Tk()

v = StringVar()
def setText(Word):
    v.set(Word)

a = Button(win, text="plant", command=setText("plant")
a.pack()
b = Button(win, text="animal", command=setText("animal"))
b.pack()
c = Entry(win, textvariable=v)
c.pack()
win.mainloop()

Jusqu'ici, quand je suis capable de compiler, le clic ne fait rien.

13
unlockme

Vous voudrez peut-être utiliser la méthode insert.

Ce script insère un texte dans Entry. Le texte inséré peut être modifié dans le paramètre command du bouton.

from tkinter import *

def set_text(text):
    e.delete(0,END)
    e.insert(0,text)
    return

win = Tk()

e = Entry(win,width=10)
e.pack()

b1 = Button(win,text="animal",command=lambda:set_text("animal"))
b1.pack()

b2 = Button(win,text="plant",command=lambda:set_text("plant"))
b2.pack()

win.mainloop()
39
Milan Skála

Si vous utilisez une "variable de texte" tk.StringVar(), vous pouvez simplement set() that. 

Pas besoin d'utiliser l'entrée supprimer et insérer. De plus, ces fonctions ne fonctionnent pas lorsque l'entrée est désactivée ou en lecture seule! Cependant, la méthode de variable de texte fonctionne également dans ces conditions.

import Tkinter as tk

...

entryText = tk.StringVar()
entry = tk.Entry( master, textvariable=entryText )
entryText.set( "Hello World" )
7
BuvinJ

Une solution serait d'hériter d'une nouvelle classe, EntryWithSet, et de définir la méthode set qui utilise les méthodes delete et insert des objets Entry class:

try:                        # In order to be able to import tkinter for
    import tkinter as tk    # either in python 2 or in python 3
except ImportError:
    import Tkinter as tk


class EntryWithSet(tk.Entry):
    """
    A subclass to Entry that has a set method for setting its text to
    a given string, much like a Variable class.
    """

    def __init__(self, master, *args, **kwargs):
        tk.Entry.__init__(self, master, *args, **kwargs)


    def set(self, text_string):
        """
        Sets the object's text to text_string.
        """

        self.delete('0', 'end')
        self.insert('0', text_string)


def on_button_click():
    import random, string
    Rand_str = ''.join(random.choice(string.ascii_letters) for _ in range(19))
    entry.set(Rand_str)


if __== '__main__':
    root = tk.Tk()
    entry = EntryWithSet(root)
    entry.pack()
    tk.Button(root, text="Set", command=on_button_click).pack()
    tk.mainloop()
1
Nae

Votre problème est que quand vous faites ceci:

a = Button(win, text="plant", command=setText("plant"))

il essaie d'évaluer ce qu'il faut définir pour la commande. Ainsi, lors de l'instanciation de l'objet Button, il appelle en réalité setText("plant"). C'est faux, car vous ne voulez pas encore appeler la méthode setText. Ensuite, il prend la valeur de retour de cet appel (qui est None) et la définit comme commande du bouton. C'est pourquoi cliquer sur le bouton ne fait rien car il n'y a pas de commande pour cela.

Si vous suivez les instructions de Milan Skála et utilisez plutôt une expression lambda, votre code fonctionnera (si vous corrigez l'indentation et les parenthèses).

Au lieu de command=setText("plant"), qui en fait appelle la fonction, vous pouvez définir command=lambda:setText("plant") qui spécifie quelque chose qui appellera la fonction ultérieurement, lorsque vous souhaitez l'appeler.

Si vous n'aimez pas les lambdas, une autre façon (légèrement plus lourde) serait de définir une paire de fonctions pour faire ce que vous voulez:

def set_to_plant():
    set_text("plant")
def set_to_animal():
    set_text("animal")

et alors vous pouvez utiliser command=set_to_plant et command=set_to_animal - ceux-ci seront évalués en fonction des fonctions correspondantes, mais sont certainement pas identiques à command=set_to_plant(), ce qui bien sûr serait évalué à None à nouveau.

0
user9913277

Vous pouvez choisir entre les deux méthodes suivantes pour définir le texte d'un widget Entry. Pour les exemples, supposons que la bibliothèque importée import tkinter as tk et la fenêtre racine root = tk.Tk().


  • Méthode A: Utiliser delete et insert

    Le widget Entry fournit les méthodes delete et insert qui peuvent être utilisées pour définir le texte avec une nouvelle valeur. Tout d'abord, vous devez supprimer tout ancien texte de Entry avec delete qui nécessite les positions pour commencer et terminer la suppression. Puisque nous voulons supprimer l’ancien texte complet, nous commençons par 0 et se terminons à l’endroit où se trouve actuellement la fin. Nous pouvons accéder à cette valeur via END. Ensuite, la Entry est vide et nous pouvons insérer new_text à la position 0.

    entry = tk.Entry(root)
    new_text = "Example text"
    entry.delete(0, tk.END)
    entry.insert(0, new_text)
    

  • Méthode B: Utiliser StringVar

    Vous devez créer un nouvel objet StringVar appelé entry_text dans l'exemple. De plus, votre widget Entry doit être créé avec l'argument de mot clé textvariable. Ensuite, chaque fois que vous modifiez entry_text avec set, le texte s'affichera automatiquement dans le widget Entry.

    entry_text = tk.StringVar()
    entry = tk.Entry(root, textvariable=entry_text)
    new_text = "Example text"
    entry_text.set(new_text)
    

  • Exemple de travail complet contenant les deux méthodes pour définir le texte via Button:

    Cette fenêtre

     screenshot

    est généré par l'exemple de travail complet suivant:

    import tkinter as tk
    
    def button_1_click():
        # define new text (you can modify this to your needs!)
        new_text = "Button 1 clicked!"
        # delete content from position 0 to end
        entry.delete(0, tk.END)
        # insert new_text at position 0
        entry.insert(0, new_text)
    
    def button_2_click():
        # define new text (you can modify this to your needs!)
        new_text = "Button 2 clicked!"
        # set connected text variable to new_text
        entry_text.set(new_text)
    
    root = tk.Tk()
    
    entry_text = tk.StringVar()
    entry = tk.Entry(root, textvariable=entry_text)
    
    button_1 = tk.Button(root, text="Button 1", command=button_1_click)
    button_2 = tk.Button(root, text="Button 2", command=button_2_click)
    
    entry.pack(side=tk.TOP)
    button_1.pack(side=tk.LEFT)
    button_2.pack(side=tk.LEFT)
    
    root.mainloop()
    
0
finefoot