如何将Tkinter聊天窗口与Chatbot文件的I/O进行关联?
实现Tkinter GUI与聊天机器人的交互流程
核心实现步骤
- 解耦聊天逻辑与控制台交互:移除
chatbot.py中用于控制台交互的while循环和print语句,保留核心的响应生成逻辑(greeting、response函数)及初始化代码。 - GUI调用聊天机器人逻辑:在
chatbotGUI.py中导入chatbot模块,通过调用其函数处理用户输入并获取回复。 - 修改发送函数:更新
send函数,在插入用户输入后,调用聊天机器人的逻辑生成回复,再将回复插入聊天窗口。 - 添加初始问候:GUI启动时自动显示机器人的初始欢迎语。
修改后的代码
1. chatbot.py(保留核心逻辑,移除控制台循环)
#Meet Reach: your friend #import necessary libraries import io import random import string # to process standard python strings import warnings import numpy as np from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity import warnings warnings.filterwarnings('ignore') import nltk from nltk.stem import WordNetLemmatizer nltk.download('popular', quiet=True) # for downloading packages # uncomment the following only the first time #nltk.download('punkt') # first-time use only #nltk.download('wordnet') # first-time use only #Reading in the corpus with open('chatbot.txt','r', encoding='utf8', errors ='ignore') as fin: raw = fin.read().lower() #TOkenisation sent_tokens = nltk.sent_tokenize(raw)# converts to list of sentences word_tokens = nltk.word_tokenize(raw)# converts to list of words # Preprocessing lemmer = WordNetLemmatizer() def LemTokens(tokens): return [lemmer.lemmatize(token) for token in tokens] remove_punct_dict = dict((ord(punct), None) for punct in string.punctuation) def LemNormalize(text): return LemTokens(nltk.word_tokenize(text.lower().translate(remove_punct_dict))) # Keyword Matching GREETING_INPUTS = ("hello", "hi", "greetings", "sup", "what's up","hey", "whats up", "hi reach", "hello reach") GREETING_RESPONSES = ["Hi", "Hey", "Hi there", "Hello"] def greeting(sentence): """If user's input is a greeting, return a greeting response""" for word in sentence.split(): if word.lower() in GREETING_INPUTS: return random.choice(GREETING_RESPONSES) # Generating response def response(user_response): reach_response='' user_response = user_response.lower() sent_tokens.append(user_response) TfidfVec = TfidfVectorizer(tokenizer=LemNormalize, stop_words='english') tfidf = TfidfVec.fit_transform(sent_tokens) vals = cosine_similarity(tfidf[-1], tfidf) idx=vals.argsort()[0][-2] flat = vals.flatten() flat.sort() req_tfidf = flat[-2] if (user_response=="what is military reach?" or user_response=="what is military reach"): reach_response = "Military REACH is an organization that works to bridge the gap between military family research and practice." reach_response = reach_response + "\nOur goal is to make research more accessible for military families." reach_response = reach_response + "\n\nIs there anything else that I can help you with?" return reach_response elif (user_response=="how many documents does military reach have?" or user_response=="how many documents does military reach have"): reach_response = "Military REACH has a database of over 6,000 documents containing research summaries, reports, newsletters, and more!" reach_response = reach_response + "\n\nIs there anything else that I can help you with?" return reach_response elif(req_tfidf==0): reach_response=reach_response+"I'm not quite sure. Let me look and get back to you!" return reach_response else: reach_response = reach_response+sent_tokens[idx] sent_tokens.remove(user_response) return reach_response def get_initial_greeting(): return "Hello, my name is Reach. I will answer your questions about Military REACH. If you want to exit, type Bye!"
2. chatbotGUI.py(集成聊天机器人逻辑)
#Description: This is a chat bot GUI #Import the library from tkinter import * import chatbot root = Tk() root.title("Military REACH Chat Bot") root.geometry("600x800") root.resizable(width=FALSE, height=FALSE) main_menu = Menu(root) # Create the submenu file_menu = Menu(root) # Add commands to submenu file_menu.add_command(label="New..") file_menu.add_command(label="Save As..") file_menu.add_command(label="Exit", command=root.quit) main_menu.add_cascade(label="File", menu=file_menu) #Add the rest of the menu options to the main menu main_menu.add_command(label="Edit") main_menu.add_command(label="Quit", command=root.quit) root.config(menu=main_menu) messageWindow = Entry(root, bd=0, bg="white",width="30", font=("Arial", 16), foreground="black") messageWindow.place(x=128, y=710, height=88, width=450) chatWindow = Text(root, bd=1, bg="white", width="550", height="100", font=("Arial", 16), foreground="black") chatWindow.place(x=6,y=6, height=700, width=570) # 设置文本框不可编辑,仅用于展示 chatWindow.config(state=DISABLED) scrollbar = Scrollbar(root, command=chatWindow.yview, cursor="arrow") scrollbar.place(x=575,y=6, height=700) def insert_message(sender, message): """统一插入消息到聊天窗口的函数""" chatWindow.config(state=NORMAL) chatWindow.insert(END, f"{sender}: {message}\n\n") chatWindow.config(state=DISABLED) # 自动滚动到底部 chatWindow.see(END) def send(event=None): user_input = messageWindow.get().strip() if not user_input: return # 插入用户输入 insert_message("You", user_input) messageWindow.delete(0, END) # 处理退出逻辑 if user_input.lower() == 'bye': insert_message("REACH", "Bye! Take care.") root.after(1000, root.quit) return # 获取机器人回复 bot_reply = "" if user_input.lower() in ['thanks', 'thank you']: bot_reply = "You are welcome. Do you need anything else?" else: greet_reply = chatbot.greeting(user_input) if greet_reply: bot_reply = greet_reply else: bot_reply = chatbot.response(user_input) # 插入机器人回复 insert_message("REACH", bot_reply) # 显示初始问候语 insert_message("REACH", chatbot.get_initial_greeting()) Button= Button(root, text="Send", width="12", height=3, bd=0, bg="green", activebackground="green",foreground='#000000',font=("Arial", 12), command=send) Button.place(x=6, y=710, height=88) root.bind('<Return>', send) root.mainloop()
关键说明
chatbot.py中新增了get_initial_greeting函数,用于返回初始欢迎语,同时在response函数中提前处理了输入的小写转换,避免重复操作。chatbotGUI.py中新增了insert_message函数,统一处理消息插入逻辑,同时设置聊天窗口为不可编辑状态,防止用户修改历史消息。- 完善了退出逻辑:用户输入
bye时,机器人回复后自动退出GUI;处理感谢类输入的专属回复。
内容的提问来源于stack exchange,提问作者Thomas Murphy
相关产品推荐
相关产品推荐

