-1

I have a code snippet. Entry widget creates itself with text, then waits seconds then destroys itself.

    entry_var_temporary = tk.StringVar()
    entry_var_temporary.set(varsoundTitle_usernameHeroContainer)
    entry_shtname_temp=tk.Entry(canvas2,width=30,textvariable=entry_var_temporary)
    entry_shtname_temp.pack()
    entry_shtname_temp.focus_set()
    root.update()
    time.sleep(10)
    entry_shtname_temp.destroy()
    root.update()

I have put 10 seconds to wait, and let user to modify the text, if it wants so. But as I see, time.sleep does not let the entry widget to be modified. How can I get around this problem? With wait.window() I realized I can edit text inside widget, but my problem is, it is not compulsory. So, if user doesn't put any text on it, it then after 10 sec needs to be destroyed

xlmaster
  • 659
  • 7
  • 23
  • 1
    You've posted far too much code. If you're asking how to have an entry widget only available for a few seconds, it shouldn't take more than a dozen or two lines of code to illustrate that. – Bryan Oakley Feb 05 '23 at 20:55
  • The answe below is not waiting even seconds after creating entry widget. I am using 30 000 – xlmaster Feb 05 '23 at 20:58
  • It's not waiting because you didn't tell it to wait. Neither `update` nor `after` will cause the code to pause. – Bryan Oakley Feb 05 '23 at 21:05

2 Answers2

1

Use the after method with the destroy method as the callback.

The main reason to use root.after vs time.sleep is the time.sleep stops the thread causing the code to completely stop compared to root.after which is thread-safe because it is implemented in terms of call.

Your widget will destroy itself automatically after a set amount of time.

for example:

import tkinter as tk


root = tk.Tk()

entry_var_temporary = tk.StringVar()
entry = tk.Entry(root,  textvariable=entry_var_temporary)
entry.pack()
root.after(10000, entry.destroy)  # 10000 milliseconds
root.mainloop()
Alexander
  • 16,091
  • 5
  • 13
  • 29
  • 1
    are you sure with `root.destroy` or it should be `entry.destroy`? – xlmaster Feb 05 '23 at 20:33
  • 1
    Whatever you are trying to destroy is what should be calling the destroy method. – Alexander Feb 05 '23 at 20:34
  • I tried again, it did not fix the core issue. Being able to edit data in entry widget. When I click inside entry widget screen freezes, I meean tkinter window – xlmaster Feb 05 '23 at 20:36
  • 1
    @xlmaster did you remove the call to sleep? – Alexander Feb 05 '23 at 20:37
  • Yes, I guess in your code there were not `root.update` – xlmaster Feb 05 '23 at 20:38
  • Sorry, but I need to edit the entry widget. Your code is not giving me that possibility – xlmaster Feb 05 '23 at 20:40
  • @xlmaster Did you try running the code in my example? If you do will see that there is no issue with using the entry widget. – Alexander Feb 05 '23 at 20:41
  • main difference is that i put root.updat()` line after pack() and above `after`. Your code acts strangely, it does not stop running. Maybe I need to put also time.sleep() after `after()`? – xlmaster Feb 05 '23 at 20:44
  • That shouldn't make a difference, and it probably isn't necessary. This would be easier to debug if you posted your full code or a [mre] @xlmaster – Alexander Feb 05 '23 at 20:46
  • 2
    @xlmaster: as a general rule of thumb you should _never_ call `time.sleep` in the same thread as the GUI. It literally puts the entire program to sleep, including the ability for tkinter to redraw the window or react to events such as key and button presses. – Bryan Oakley Feb 05 '23 at 20:47
  • Code runs only after it lets me to edit then destroys itslef – xlmaster Feb 05 '23 at 20:52
  • You see line print(Alelujah) so it show me the widget and prints that word exctly same even though I have put root,update above and below after methods. After code finsihes it let me edit the widget and I put 30000 milliseconds. Guess does not wait – xlmaster Feb 05 '23 at 20:56
  • Impossible with your code, I have even changed `root.after(30000,) ` to `entry.after()` it does not stop even a blink of eye moment, it continues running after. After the code has finished it then lets me to edit the widget – xlmaster Feb 05 '23 at 21:01
  • 1
    @xlmaster: using `after` won't pause the code. The code will continue to run. You must also call `wait_window` if you expect the code to wait until the widget is destroyed. – Bryan Oakley Feb 05 '23 at 21:04
  • 1
    @xlmaster in general you should put any long running code in a separate thread otherwise you will always have issues with frozen gui – Alexander Feb 05 '23 at 21:05
1

This seems to be an extension of a previous question you asked. You only need to add one more line of code to that example in order to automatically delete the entry widget after 10 seconds.

In the following example, notice how I use after to destroy the window in 10 seconds. This call must be done before waiting for the window. This is the example I gave in your previous question, with just that one new statement added:

entry_var = tk.StringVar()
new_sheetname_entryBox=tk.Entry(canvas2,width=30, textvariable=entry_var)
new_sheetname_entryBox.pack()
new_sheetname_entryBox.bind("<Return>", lambda event: new_sheetname_entryBox.destroy())
new_sheetname_entryBox.focus_set()

# wait for the entry widget to be deleted, but automatically
# delete it after 10 seconds if the user doesn't respond.
root.after(10000, new_sheetname_entryBox.destroy)
new_sheetname_entryBox.wait_window()
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • I looked at it, I realized `wait_window()` method gives me possibility to edit widget. But I did not know how to bypass `bind` I did not want it to exist. Now the puzzle sums up after `after()` method is added upon the picture. Thanks! – xlmaster Feb 05 '23 at 21:05
  • Just Great!! thanks a lot! I guess I was also able to digest previous code snippets due to your explanation. Thanks @Bryan – xlmaster Feb 05 '23 at 21:09