0

In Tkinter I made function setstatus: it appendst the input string to a list of status messages and displays the list of messages in a listbox:

root = Tk()
root.geometry("487x680")
Statusbox = Listbox(statusframe, width=75, height=5, selectmode=SINGLE)
Statusbox.grid(row=0, column=0)
root.statusmessages = [""]*10
def setstatus(statmstr):
    root.statusmessages[1:] = root.statusmessages[0:-1]
    root.statusmessages[0] = statmstr
    Statusbox.delete(0, END)  # delete listbox content
    i = 0
    for item in root.statusmessages:
        i += 1
        Statusbox.insert(END, item)

setstatus("Wait....")
do_plot()  # creates a plot from matplotlib
setstatus("Plotting done.")
root.mainloop()

When running it in debug mode it works fine, all status messages appear in the listbox. Othwerwise, when running it normally, it only logs the first message ("Wait....") in the status message listbox, the 2nd message does not appear. What is the reason of it, how to solve it in Tkinter? Thanks!

SwitchOFF
  • 11
  • 2
  • Please provide [mre], also show how You have defined `setstatus()` and what do You mean by debug mode? – Matiiss Apr 27 '21 at 10:47
  • I added the function code as well for more information. On debug mode I meant if you insert break point for example at the last line and run the code, step through the last line (perform setstatus function), then it shows the "Plotting done". Running without break points it does not show – SwitchOFF Apr 27 '21 at 12:25
  • have You tried printing out what some parts of the function produce? – Matiiss Apr 27 '21 at 12:30
  • I use Pycharm, and in debug mode I could check the root.statusmessages list of strings, it fills up correctly (in debug mode), that's why I don't print something from the function. However, I inserted an additional print statement (e.g. print("Done")) after setstatus("Plotting done") to check if at least print performed or not. It does not print anything. – SwitchOFF Apr 27 '21 at 12:39
  • that is rather confusing, however You could try using `print` for debugging and put it in the `setstatus()` function (several ones to print step by step what happens), also does `do_plot()` ever finish? – Matiiss Apr 27 '21 at 12:41
  • I guess some kind of wait of pause required for Tkinter to catch up (like in Matlab pause(0.001)) – SwitchOFF Apr 27 '21 at 12:45
  • yes , do_plot() finishes, a plot pops up (I just don't want to insert the whole long code of it) – SwitchOFF Apr 27 '21 at 12:47
  • does `do_plot()` use `mainloop()`? because what I think is that it exits `do_plot()` only after closing the window, which would mean that it reaches the last `setstatus()` at the point when it cannot display anything anymore because the window is closed, also at that point it should print anything after that – Matiiss Apr 27 '21 at 12:49
  • Nope, mainloop() is called after the whole thing, at the end of the Tkinter gui code (I edited the question). mainloop() is not in functions, neither in do_plot(), nor in setstatus(). – SwitchOFF Apr 27 '21 at 13:48
  • I honestly have no idea of why it wouldn't work, I can only suggest putting print statements in `setstatus()` function and see what they output – Matiiss Apr 27 '21 at 13:50
  • I found solution here: https://stackoverflow.com/questions/28269157/plotting-in-a-non-blocking-way-with-matplotlib The matplotlib plt.show() blocks execution in my plot function somehow. I inserted plt.ion() before creating the plot figure. Then Tkinter executes my status message display listbox after plotting done. Thanks for Your help though! – SwitchOFF Apr 27 '21 at 14:21

1 Answers1

1

The solution is here: Plotting in a non-blocking way with Matplotlib The matplotlib plt.show() blocks execution in my plot function somehow. I inserted plt.ion() before creating the plot figure. Then Tkinter executes my status message display listbox after plotting done.

SwitchOFF
  • 11
  • 2