web-dev-qa-db-fra.com

Comment lier la touche Entrée à une fonction dans tkinter?

Je suis un Python débutant auto-apprenant, fonctionnant sur MacOS.

Je crée un programme avec une interface graphique de parseur de texte dans tkinter, où vous tapez une commande dans un widget Entry et appuyez sur un widget Button, qui déclenche ma parse() funct, ect, impression des résultats dans un widget Text, style texte-aventure.

> Contournez le bouton

Je ne peux pas te laisser faire ça, Dave.

J'essaie de trouver un moyen de me débarrasser de la nécessité de transporter la souris vers le Button chaque fois que l'utilisateur émet une commande, mais cela s'est avéré plus difficile que je ne le pensais.

Je suppose que le bon code ressemble à self.bind('<Return>', self.parse())? Mais je ne sais même pas où le mettre. root, __init__, parse() et create_widgets() n'en veulent pas.

Pour être clair, la seule raison pour laquelle quelqu'un doit appuyer sur Entrée dans le prog est de déclencher parse(), il n'a donc pas besoin d'être spécifiquement appliqué au widget Entry spécifiquement. Partout où cela fonctionne, c'est bien.

En réponse à 7stud, le format de base:

from tkinter import *
import tkinter.font, random, re

class Application(Frame):

    def __init__(self, master):
        Frame.__init__(self, master, ...)
        self.grid()
        self.create_widgets()
        self.start()


    def parse(self):
        ...


    def create_widgets(self):

        ...

        self.submit = Button(self, text= "Submit Command.", command= self.parse, ...)
        self.submit.grid(...)


root = Tk()
root.bind('<Return>', self.parse)

app = Application(root)

root.mainloop()
31
Ghosty

Essayez d'exécuter le programme suivant. Vous devez juste être sûr que votre fenêtre a le focus lorsque vous appuyez sur Retour - pour vous en assurer, cliquez d'abord sur le bouton plusieurs fois jusqu'à ce que vous voyiez une sortie, puis sans cliquer ailleurs, appuyez sur Retour.

import tkinter as tk

root = tk.Tk()
root.geometry("300x200")

def func(event):
    print("You hit return.")
root.bind('<Return>', func)

def onclick():
    print("You clicked the button")

button = tk.Button(root, text="click me", command=onclick)
button.pack()

root.mainloop()

Ensuite, vous avez juste un peu de choses Tweak lorsque vous faites à la fois le button click et hitting Return appeler la même fonction - car la fonction de commande doit être une fonction qui ne prend aucun argument, tandis que la fonction de liaison doit être une fonction qui prend un argument (l'objet événement):

import tkinter as tk

root = tk.Tk()
root.geometry("300x200")

def func(event):
    print("You hit return.")

def onclick(event=None):
    print("You clicked the button")

root.bind('<Return>', onclick)

button = tk.Button(root, text="click me", command=onclick)
button.pack()

root.mainloop()

Ou, vous pouvez simplement renoncer à utiliser l'argument de commande du bouton et utiliser à la place bind () pour attacher la fonction onclick au bouton, ce qui signifie que la fonction doit prendre un argument - tout comme avec Return:

import tkinter as tk

root = tk.Tk()
root.geometry("300x200")

def func(event):
    print("You hit return.")

def onclick(event):
    print("You clicked the button")

root.bind('<Return>', onclick)

button = tk.Button(root, text="click me")
button.bind('<Button-1>', onclick)
button.pack()

root.mainloop()

Le voici en classe:

import tkinter as tk

class Application(tk.Frame):
    def __init__(self):
        self.root = tk.Tk()
        self.root.geometry("300x200")

        tk.Frame.__init__(self, self.root)
        self.create_widgets()

    def create_widgets(self):
        self.root.bind('<Return>', self.parse)
        self.grid()

        self.submit = tk.Button(self, text="Submit")
        self.submit.bind('<Button-1>', self.parse)
        self.submit.grid()

    def parse(self, event):
        print("You clicked?")

    def start(self):
        self.root.mainloop()


Application().start()
45
7stud

Une autre alternative consiste à utiliser un lambda:

ent.bind("<Return>", (lambda event: name_of_function()))

Code complet:

from tkinter import *
from tkinter.messagebox import showinfo

def reply(name):
    showinfo(title="Reply", message = "Hello %s!" % name)


top = Tk()
top.title("Echo")
top.iconbitmap("Iconshock-Folder-Gallery.ico")

Label(top, text="Enter your name:").pack(side=TOP)
ent = Entry(top)
ent.bind("<Return>", (lambda event: reply(ent.get())))
ent.pack(side=TOP)
btn = Button(top,text="Submit", command=(lambda: reply(ent.get())))
btn.pack(side=LEFT)

top.mainloop()

Comme vous pouvez le voir, la création d'une fonction lambda avec une variable "événement" inutilisée résout le problème.

7
Seçkin Savaşçı