I have read multiple similar questions & answers, but somehow still have not understood how to apply them to my particular use case. The best I found was using Tkinter with Thread
:
from Tkinter import *
import threading
class App(threading.Thread):
def __init__(self, tk_root):
self.root = tk_root
threading.Thread.__init__(self)
self.start()
def run(self):
loop_active = True
while loop_active:
user_input = raw_input("Give me your command! Just type "exit" to close: ")
if user_input == "exit":
loop_active = False
self.root.quit()
self.root.update()
else:
label = Label(self.root, text=user_input)
label.pack()
ROOT = Tk()
APP = App(ROOT)
LABEL = Label(ROOT, text="Hello, world!")
LABEL.pack()
ROOT.mainloop()
But here the parallel task is the raw_input
, which is already part of the App
itself. But what if I want to have instead two instances of App
each in its thread running in parallel? Or App
+ open3d
visualization? How would I modify this code to have responsive Tkinter GUI in one thread, without explicitly relying on some function input?
Another solution I found utilized Toplevel
. Is that indeed the correct approach for this problem? Would it not complain that Tkinter does not like working with threads, as multiple other answers to similar questions pointed out? Example:
from tkinter import *
import threading
import time
class Show_Azure_Message(Toplevel):
def __init__(self,master,message):
Toplevel.__init__(self,master) #master have to be Toplevel, Tk or subclass of Tk/Toplevel
self.title('')
self.attributes('WM_DELETE_WINDOW',self.callback)
self.resizable(False,False)
Label(self,text=message,font='-size 25').pack(fill=BOTH,expand=True)
self.geometry('250x50+%i+%i'%((self.winfo_screenwidth()-250)//2,(self.winfo_screenheight()-50)//2))
def callback(self): pass
BasicApp=Tk()
App = Show_Azure_Message(BasicApp,'Hello')
for i in range(0,2):
print(i)
time.sleep(1)
App.destroy()