How can I change it to non-modal ? If button is clicked then cursor doesn't change. If I change it to non-modal then it should be ok.
def start_new_proc():
# text.config(cursor="clock")
root.config(cursor="clock")
text.config(state="normal")
command = "ping 8.8.8.8 -c 1"
proc = Popen(command, shell=True, stdout=PIPE)
for line in iter(proc.stdout.readline, ''):
line = line.decode('utf-8')
if line == '':
break
text.insert("end", line)
proc.wait()
# text.config(cursor="")
root.config(cursor="")
text.config(state="disable")
root = tk.Tk()
text = tk.Text(root, state="disabled")
text.pack()
button = tk.Button(root, text="Run", command=start_new_proc)
button.pack()
root.mainloop()
You can achieve this using threading.
By putting the command execution in a thread, it doesn't hold up the tkinter thread. The function
ping_funcis what the thread runs. It does what the program did before, but the output is different. Because tkinter isn't thread safe, you can't use tkinter objects in other threads. Therefore we need to pass a variable instead which can then be polled by the tkinter thread. This is what theoutputlist is for. The output fromping_funcis appended tooutput. To check the contents ofoutputand insert it into the Text widget, we need a functioncheck_output. This calls itself every 100ms to check if the contents of output have changed. If they have it inserts the new line into the Text widget. There is alsocheck_completewhich checks every 100ms if the thread has ended and changes the cursor and enables the button if it has.