0

I currently have a problem where I can't get tkinter to display text in one of its .Text modules because it happens in a function that ends in terminating the whole tkinter window. The idea is to have some final output with operation results appearing in the window for 5 seconds, and then have it shut down. The issue is, tkinter seems to be rigged to only ever let the ".insert(xy)" commands through when the whole function has worked itself out, which in this case means it can't do it. Simplified example code for window:

tk_buttonStart = tkinter.Button(
    master, height=2, width=20, text="Start", command=lambda: tk_Start())
tk_buttonEnd = tkinter.Button(
    master, height=2, width=20, text="End", command=lambda: tk_end())
tk_textOutput = tkinter.Text(master, height=25, width=54, bg="light yellow", font=('calibre', 8))

With tk_end being:

def tk_end():
    displayThread = threading.Thread(target=menu_outStrsDisplay, daemon=True, args=(outStrs))
    displayThread.start()
    time.sleep(5)
    master.destroy()
    ws.close()

...And menu_outStrDisplay simplified to:

def menu_outStrsDisplay(addList):
    # --some processing of addList into an outStr here--
    tk_textOutput.delete('1.0', tkinter.END)
    tk_textOutput.insert(tkinter.END, menu_outStr)

Things I tried:

  • The direct approach of manupulating the tk_textOutput inside tk_end, but it never displays before window shutdown
  • Having tk_end call another function "tk_on_close" (usually reserved for the X button - basically the last two lines of tk_end above), but since that is called inside tk_end, it still doesn't count as conclusion, hence the text doesn't display
  • Having tk_on_close started in a separate thread, which results in the text display finally appearing, but also the program never terminating. It seems a threaded offspring function of tkinter cannot end operations of the main thread. (or did I do that wrong?)
  • Finally what you see above, having the Display function be run in a thread. This function works perfectly throughout all the other proceedings of the program, but for some reason it still can't display or manipulate the tkinter text object in threaded mode, so nothing happens before termination again.
2
  • 1
    tk_buttonEnd = tkinter.Button( master, height=2, width=20, text="End", command=lambda: threading.Thread(target=tk_end).start()) You have to thread the function because it freezes the main thread Commented May 18, 2021 at 5:30
  • Thank you, who knew this was possible. However, even though I now get the values displayed, the program still never terminates, which is I suppose due to the websocket there (ws) not properly closing if tk_end is threaded. Commented May 18, 2021 at 5:47

1 Answer 1

1

First you don't need to use thread to run menu_outStrsDisplay() if it is not a time-consuming task.

Second you should not called time.sleep(5). Use .after(5000, ...) to call a function (is it tk_on_close()?) after 5 seconds which calls master.destroy() and ws.close():

def tk_on_close():
    master.destroy()
    ws.close()

def menu_outStrsDisplay(addList):
    # --some processing of addList into an outStr here--
    tk_textOutput.delete("1.0", tkinter.END)
    tk_textOutput.insert(tkinter.END, menu_outStr)

def tk_end():
    menu_outStrsDisplay(outStrs) # don't use thread to run the function
    master.after(5000, tk_on_close) # call tk_on_close() 5 seconds later
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much, I massaged the .after functionality in and it was the right answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.