Meeran Rizvi wrote: > On Monday, January 30, 2017 at 12:02:40 PM UTC+5:30, Meeran Rizvi wrote: >> Hello Guys, >> Here i am creating a GUI which will act as a search engine that will find >> the results from the browser and save the results as a xls file. When i >> typed something in my search box and click the (GO)button.It should >> display search in progress.when the file is saved it should display done. >> How to do that? My button gets hung for a seconds.We should give any >> timeout for that? >> >> Here is my script >> <python> >> from Tkinter import * >> import mechanize >> def clear_search(event): >> search.delete(0,END) >> obj = Tk() >> Label = Label(obj,text="Top Findings:",font="-weight bold") >> search = Entry(obj,width=100) >> search.insert(0, "Enter the value to search") >> search.bind("<Button-1>", clear_search) >> def fun(): >> new = search.get() >> url = "http://duckduckgo.com/html" >> br = mechanize.Browser() >> br.set_handle_robots(False) >> br.open(url) >> br.select_form(name="x") >> br["q"] = str(new) >> res = br.submit() >> content = res.read() >> with open("result1.xls", "w") as f: >> f.write(content) >> fun() >> Go = Button(obj,text="GO",width=5,command=fun) >> Label.pack() >> search.pack() >> Go.pack() >> mainloop() >> </python> > > Hi Peter, > can u explain about these functions > def start_search():
This creates a new thread; target and args specify that in that thread fun will be invoked with the current contents of the search Entry. > thread = threading.Thread( > target=fun, > args=(search.get(),) > ) > thread.setDaemon(True) > thread.start() This tells Tkinter to run the check_state function 100 milliseconds later. > root.after(100, check_state) As the -- aptly named ;) -- start_search() only starts the search without having to wait for the result it will only block the GUI for a moment that should normally be too short for the user to note. You can think of the resulting script as two mini-programs that -- at least conceptually -- run indepently. If they access each other's data you can get an inconsistent state. The Queue class is written with precautions to avoid such problems. check_state() and Tkinter run in the main thread and only receive data from the thread executing fun() through the queue. > def check_state(): > while True: Look into the queue if there is a message from fun(). If there is return it, otherwise instead of waiting for the next message to arrive raise an exception immediately. Remember, if we stay here too long the GUI will lag. > try: > message = queue.get_nowait() > except Queue.Empty: Case (1) No pending messages, break out of the loop. > break Case (2) We have a message. Update the text of the state_info Label accordingly, > state_info["text"] = message then check if it's the last message we expect. > if message == "done": Yes it's the last message; leave check_state() without rescheduling it. > return We got here from the break statement. There are currently no messages, but there may be later, so we ask Tkinter to run check_state again in 100 milliseconds. > root.after(100, check_state) PS: You can verify that you understood this by answering the question: what happens if the user hits the go-button while the second thread is still running. Hint: as written the script does not handle this correctly. -- https://mail.python.org/mailman/listinfo/python-list