I was wondering if there was a way to run the tkinter mainloop on a separate thread (not the mainthread) so that the terminal is "free".
Let's say we have a simple GUI:
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid()
self.createWidgets()
def printHello(self):
print("Hello")
def createWidgets(self):
self.quitButton = tk.Button(self, text='Quit',
command=self.quit)
self.quitButton.grid(row=1,column=0)
self.printButton = tk.Button(self, text='Print',command=lambda: self.printHello())
self.printButton.grid(row=1,column=1)
app = Application()
app.master.title('Sample application')
app.mainloop()
Observed behavior: if I run this file using the terminal in PyCharm (let's say) using: python application.py
, the terminal is then "frozen"/"occupied" by the tkinter mainloop and I am not able to type anything in the terminal.
Desired behavior: if I run the gui file with python application.py
, the terminal is "free" such that it is able to take in additional commands.
I'm aware that python application.py &
is supposed to free up the terminal but that hasn't worked for me. I'm not very experienced with threading or GUI processes but is there a way to run the tkinter mainloop in a different process / thread so that the terminal will be "free"?
You can use the threading module to run the GUI in a background thread while using the terminal in the main thread.
Try this code. It will start the GUI then allow input from the terminal.
import tkinter as tk
import threading
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid()
self.createWidgets()
def printHello(self):
print("Hello")
def createWidgets(self):
self.quitButton = tk.Button(self, text='Quit',
command=self.quit) # exits background (gui) thread
self.quitButton.grid(row=1,column=0)
self.printButton = tk.Button(self, text='Print',command=lambda: self.printHello())
self.printButton.grid(row=1,column=1)
def runtk(): # runs in background thread
app = Application()
app.master.title('Sample application')
app.mainloop()
thd = threading.Thread(target=runtk) # gui thread
thd.daemon = True # background thread will exit if main thread exits
thd.start() # start tk loop
while True: # run in main thread
x = input("Enter a value or Q to quit: ")
if x.lower() == 'q':
exit()
print('You entered', x)