0

I am making a responce bot in python with tkinter. For that when user inputs something I will give answer. I have not yet completed it. I wanted that the bot should answer after some-time so it looks very nice.

My code:-

import tkinter
from tkinter import Message, messagebox
from tkinter import font
from tkinter.constants import CENTER, LEFT, RIGHT, BOTTOM, TOP
from tkinter import scrolledtext
from typing import Sized
import time

window = tkinter.Tk()
window.geometry("370x500")
window.configure(bg="orange")

#variables
running = True
verdana_12 = ('Verdana', '12')
verdana_10 = ('Verdana', '10')
verdana_9 = ('Verdana', '9')
msg=tkinter.StringVar()

#messages
greetings = ["hi", "hello", "hey", "what's up!"]
questions = [
                   '    1. What is python?', 
                   '    2. Where to ask questions if I get     stuck?', 
                   '    3. How can I get example questions     and quizes related to python?'
                   ]

#items inb gui
info_text = tkinter.Label(window, text="Chat", bg="orange", font=verdana_12)
info_text.pack(padx=20, pady=5)

text_1 = tkinter.Label(window, text="Type your message: ", font=verdana_9, bg="orange")
text_1.place(x=0, y=476)

input_area = tkinter.Entry(window, justify=LEFT, textvariable=msg, font=verdana_12, width=16)
input_area.focus_force()
input_area.place(x=135, y=476)

chat_area = scrolledtext.ScrolledText(window)
chat_area.pack(padx=20, pady=5)
chat_area.config(state = "disabled")

#define message
message = f"You: {input_area.get()}\n"

#functions
#def afterwards():
#    mine_msg = message.lower().strip().split()[1]
#    if 1 == mine_msg:
#        reply("Bot: Python is an interpreted high-level general-purpose programming language. Python's design philosophy emphasizes code readability with its notable use of significant indentation. More info at https://en.wikipedia.org/wiki/Python_(programming_language)")
#    
#    elif 2 == mine_msg:
#        reply("Bot: If you get stuck in python programming, go to stackoverflow.com where you can ask questions related to any programming language!")
#
#    elif 3 == mine_msg:
#        reply("Bot: You can get quizes related to python in w3schools.org and example questions in w3resource.org.")
    
def reply(reply_msg):
    str(reply_msg)
    the_reply = f"{reply_msg}\n" #input_area = where person types.
    chat_area.config(state='normal')
    chat_area.insert(tkinter.INSERT, the_reply)
    chat_area.yview('end')
    chat_area.config(state='disabled')
    input_area.delete(0, 'end')

def check_msg():
    global message
    print('Message =', message.strip())
    try:
        mine_msg = message.lower().strip().split()[1]
        
        if greetings[0] == mine_msg or greetings[1] == mine_msg or greetings[2] == mine_msg or greetings[3] == mine_msg:
            reply("Bot: Hello, here's how I can help you")
            for i in questions:
                reply(i)
            #afterwards()
        
        else:
            reply("Bot: Couldn't understand your message,      please type 'hi', 'hello', 'hey'       or 'what's up!' to get responce.")
    except IndexError:
        pass

def write(): 
    global message
    if len(input_area.get().split()) > 0:
        message = f"You: {input_area.get()}\n" #input_area = where person types.
        chat_area.config(state='normal')
        chat_area.insert(tkinter.INSERT, message)
        chat_area.yview('end')
        chat_area.config(state='disabled')
        input_area.delete(0, 'end')
        check_msg()
    else:
        reply('Please type something.')

def print_it():
    message = f"You: {input_area.get()}"
    print(message)

#button_send
send_button = tkinter.Button(window, text="Send", command=write, font=verdana_10, bg="gray", fg="white", width=26, height=1)
send_button.pack(padx=20, pady=5)

window.mainloop()

It freezes everything for 0.5 instead I want it to freeze only the write() function. Any help please.

Thank you!

  • That's normal. You need to use multithreading for multiple things to happen at a time. Otherwise, there's only one thread of execution, so if that one thread is sleeping, it isn't responding to new inputs. That's not just a Python thing -- it works that way in C/C++/etc too; there are means to avoid the issue (like having an asynchronous dispatch scheduler), but that only happens if someone does that work to implement it – Charles Duffy Jun 16 '21 at 10:56
  • 1
    for tkinter specifically You can try using `.after()` scripts to schedule something so I think it would very well fit Your case – Matiiss Jun 16 '21 at 10:59
  • Don't use `sleep()`. Tkinter has timers for this. See linked duplicate. – Tomalak Jun 16 '21 at 11:00

1 Answers1

1

One way to achieve this would be to use the .after method from tkinter to delay the message from being replied to for a period of time.

i = "My Message"
window.after(1000,lambda i=i: reply(i))

This would call the reply function with the message "My Message" after 1000ms or 1 second.

scotty3785
  • 6,763
  • 1
  • 25
  • 35