2017-07-29 5 views
1

Alors ... je veux transformer ma console chatbot en interface utilisateur graphique et chaque fois que je le fais, il semble ne jamais fonctionner ... ill coller un code original (qui fonctionne dans la console) puis je vais coller le même code, mais ajouté quelques codes tkinter pour le transformer en gui au lieu de l'application console (juste clarifier à nouveau, mon code gui ne fonctionne vraiment pas). quelle était mon erreur dans le code gui et comment le faire fonctionner.J'ai du mal à utiliser tkinter en python pour créer un simple gui pour mon simple chatbot

import random 
#THIS IS THE CONSOLE APP CODE 
greetings = ['hola', 'hello', 'hi', 'Hi', 'hey!','hey'] 
random_greeting = random.choice(greetings) 

question = ['How are you?','How are you doing?'] 
responses = ['Okay',"I'm fine"] 
random_response = random.choice(responses) 


while True: 
    userInput = input(">>> ") 
    if userInput in greetings: 
     print(random_greeting) 
    elif userInput in question: 
     print(random_response) 
    else: 
     print("I did not understand what you said") 

est bien ici le code potentiel IUG que j'ai essayé

import random 
import tkinter 
#GUI CODE 
t = tkinter.Tk() 
userInput = tkinter.Entry(t) 
userInput.pack() 
def cb(): 
    greetings = ['hola', 'hello', 'hi', 'Hi', 'hey!','hey'] 
    random_greeting = random.choice(greetings) 

    question = ['How are you?','How are you doing?'] 
    responses = ['Okay',"I'm fine"] 
    random_response = random.choice(responses) 


    while True: 
     if 'hello' in userInput.get(): 
      lab = tkinter.Label(t,text =random_greeting) 
      lab.pack() 
     elif 'how are you' in userInput.get(): 
      labb = tkinter.Label(t,text =random_response) 
      labb.pack() 
     else: 
      labc = tkinter.Label(t,text ="I did not understand what you said") 
      labc.pack() 
button = tkinter.Button(t, text="Enter",command= cb) 
button.pack() 

tkinter.mainloop() 

(le but de ce code chatbot est vraiment pour que je puisse comprendre l'interface graphique plus) Merci!

+1

vous n'avez pas besoin d'une boucle while depuis la presse de l'utilisateur sur le bouton pour déclencher la fonction, aussi le premier test a été meilleure: 'si UserInput dans les salutations:', garder ce modèle ressemble à 'if userInput.get() dans les salutations:' – PRMoureu

+0

Et vous ne devriez pas créer de nouveaux widgets Label tout le temps. Juste mettre à jour le texte dans l'étiquette en utilisant sa méthode '.config'. –

Répondre

1

Il y a beaucoup de place pour l'amélioration de ce code, mais cela devrait vous permettre d'aller dans la bonne direction.

Il est courant dans le code Tkinter bien écrit de faire import tkinter as tk. Cela nous permet d'écrire tk au lieu de tkinter, ce qui économise le typage et facilite le changement du code pour Python 2 si nous avons besoin de le faire: il suffit de changer l'instruction import en import Tkinter as tk. Et c'est beaucoup mieux que de faire from tkinter import *, parce qu'il nous permet de voir quels noms nous avons importés de Tkinter, et il ne vide pas plus d'une centaine de noms dans notre espace de noms.

Comme PRMoureu mentionné dans les commentaires, nous ne voulons pas de boucle while dans la fonction de rappel: nous avons juste besoin de répondre à la chaîne qui est dans le widget Entrée lorsque l'utilisateur appuie sur le bouton.

Nous créons un seul widget Label pour contenir le texte de réponse du bot, et nous pouvons le mettre à jour avec la méthode Label s .config`.

import random 
import tkinter as tk 

root = tk.Tk() 
user_input = tk.Entry(root) 
user_input.pack() 

greetings = ['hola', 'hello', 'hi', 'Hi', 'hey!', 'hey'] 
question = ['How are you?', 'How are you doing?'] 
responses = ['Okay', "I'm fine"] 
huh = "I did not understand what you said" 

def cb(): 
    user_text = user_input.get() 
    if user_text in greetings: 
     bot_text = random.choice(greetings) 
    elif user_text in question: 
     bot_text = random.choice(responses) 
    else: 
     bot_text = huh 
    output.config(text=bot_text) 

button = tk.Button(root, text="Enter", command=cb) 
button.pack() 

output = tk.Label(root, text='') 
output.pack() 

tk.mainloop() 

Il faut un peu de temps pour vous habituer à la programmation GUI, parce que le flux de contrôle est pas ce que vous êtes habitué à la programmation de la console. Avec le code qui s'exécute dans la console, le code fait ce qu'il veut faire, quand il veut le faire, et l'utilisateur répond. Dans le code de l'interface graphique, nous mettons tout en place, puis attendons les événements générés par les actions de l'utilisateur, puis notre code répond à ces actions. Ceci est appelé event-driven programming. Bien que cela puisse être un peu désorientant au début, avec de la pratique, vous en prendrez bientôt conscience. ;)


Nous n'avons pas vraiment besoin de ce bouton. Au lieu de cela, nous pouvons lier notre callback au widget Entry pour qu'il soit appelé lorsque la touche Enter est enfoncée dans le widget Entry. Nous devons modifier la signature du rappel car il recevra maintenant un objet Event lorsqu'il sera appelé. Mais nous n'avons pas besoin de modifier quoi que ce soit dans le corps de la fonction de rappel car nous n'utilisons pas réellement les données dans l'objet Event.

est ici la nouvelle version:

import random 
import tkinter as tk 

root = tk.Tk() 
user_input = tk.Entry(root) 
user_input.pack() 

greetings = ['hola', 'hello', 'hi', 'Hi', 'hey!', 'hey'] 
question = ['How are you?', 'How are you doing?'] 
responses = ['Okay', "I'm fine"] 
huh = "I did not understand what you said" 

def cb(event): 
    user_text = user_input.get() 
    if user_text in greetings: 
     bot_text = random.choice(greetings) 
    elif user_text in question: 
     bot_text = random.choice(responses) 
    else: 
     bot_text = huh 
    output.config(text=bot_text) 

user_input.bind("<Return>", cb) 
output = tk.Label(root, text='') 
output.pack() 

tk.mainloop()