This is the most common boilerplate for python-tk guis that I wind up writing. Posted here for ease of copy-paste because typing this out again was irritating me
from Tkinter import *
import threading, Queue, sys, os
from optparse import OptionParser
from ConfigParser import SafeConfigParser
__version__ = "0.0.1"
class GUI(object):
def __init__(self, root, queue, shutdown, config):
self.root = root
self.config = config
# Widget creation goes here
def process_events(self):
pass
class ThreadedClient(object):
def __init__(self, root, conf):
self.root = root
self.config = SafeConfigParser()
self.config.read(conf)
self.config_file = os.path.abspath(conf)
self.queue = Queue.Queue()
self.gui = GUI(self.root, self.queue, self.shutdown, self.config)
self.running = True
self.work_thread = threading.Thread(target=self.secure_thread)
self.work_thread.setDaemon(True)
self.work_thread.start()
self.periodic_call()
def periodic_call(self):
self.root.after(200, self.periodic_call)
self.gui.process_events()
if not self.running:
sys.exit(0)
def secure_thread(self):
while self.running:
try:
msg = self.queue.get(0)
except Queue.Empty:
pass
else:
# App work goes here to kepe the gui responsive
pass
sys.exit(0)
def shutdown(self):
self.running = False
if __name__ == "__main__":
parser = OptionParser(usage="%prog [-c]", version=__version__)
parser.add_option("-c", "--config", metavar="FILE",
help="Read config from FILE", default="")
(options, args) = parser.parse_args()
root = Tk()
if args:
app = ThreadedClient(root, options.config, args[0])
else:
app = ThreadedClient(root, options.config)
root.mainloop()