# Based on this file:
# https://github.com/pallets/werkzeug/blob/master/werkzeug/_reloader.py
import time, os, sys, subprocess
PY2 = sys.version_info[0] == 2
class ReloaderLoop(object):
def restart_with_reloader(self):
"""Spawn a new Python interpreter with the same arguments as this one,
but running the reloader thread.
"""
while 1:
print("starting Tkinter application...")
args = [sys.executable] + sys.argv
new_environ = os.environ.copy()
new_environ['TKINTER_RUN_MAIN'] = 'true'
# a weird bug on windows. sometimes unicode strings end up in the
# environment and subprocess.call does not like this, encode them
# to latin1 and continue.
if os.name == 'nt' and PY2:
for key, value in iteritems(new_environ):
if isinstance(value, text_type):
new_environ[key] = value.encode('iso-8859-1')
exit_code = subprocess.call(args, env=new_environ,
close_fds=False)
if exit_code != 3:
return exit_code
def trigger_reload(self):
self.log_reload()
sys.exit(3)
def log_reload(self):
print("reloading...")
def run_with_reloader(App, *hotkeys):
"""Run the given function in an independent python interpreter."""
import signal
signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))
reloader = ReloaderLoop()
try:
if os.environ.get('TKINTER_RUN_MAIN') == 'true':
app = App()
for hotkey in hotkeys:
app.bind_all(hotkey, lambda event: reloader.trigger_reload())
app.mainloop()
else:
sys.exit(reloader.restart_with_reloader())
except KeyboardInterrupt:
pass
if __name__ == "__main__":
from tkinter import Tk, Label
class App(Tk):
def __init__(self):
Tk.__init__(self)
Label(self, text="Press Control+r to reload...").pack()
run_with_reloader(App, "<Control-R>", "<Control-r>")
Diff to Previous Revision
--- revision 2 2016-10-24 16:35:24
+++ revision 3 2016-10-24 16:43:21
@@ -55,3 +55,14 @@
sys.exit(reloader.restart_with_reloader())
except KeyboardInterrupt:
pass
+
+if __name__ == "__main__":
+ from tkinter import Tk, Label
+
+ class App(Tk):
+ def __init__(self):
+ Tk.__init__(self)
+
+ Label(self, text="Press Control+r to reload...").pack()
+
+ run_with_reloader(App, "<Control-R>", "<Control-r>")