|
from __future__ import print_function |
|
import os |
|
import sys |
|
if sys.version_info < (3,): |
|
import Queue as queue |
|
else: |
|
import queue |
|
import plac_core |
|
from Tkinter import Tk |
|
from ScrolledText import ScrolledText |
|
from plac_ext import Monitor, TerminatedProcess |
|
|
|
|
|
class TkMonitor(Monitor): |
|
""" |
|
An interface over a dictionary {taskno: scrolledtext widget}, with |
|
methods add_listener, del_listener, notify_listener and start/stop. |
|
""" |
|
def __init__(self, name, queue=None): |
|
Monitor.__init__(self, name, queue) |
|
self.widgets = {} |
|
|
|
@plac_core.annotations(taskno=('task number', 'positional', None, int)) |
|
def add_listener(self, taskno): |
|
"There is a ScrolledText for each task" |
|
st = ScrolledText(self.root, height=5) |
|
st.insert('end', 'Output of task %d\n' % taskno) |
|
st.pack() |
|
self.widgets[taskno] = st |
|
|
|
@plac_core.annotations(taskno=('task number', 'positional', None, int)) |
|
def del_listener(self, taskno): |
|
del self.widgets[taskno] |
|
|
|
@plac_core.annotations(taskno=('task number', 'positional', None, int)) |
|
def notify_listener(self, taskno, msg): |
|
w = self.widgets[taskno] |
|
w.insert('end', msg + '\n') |
|
w.update() |
|
|
|
def start(self): |
|
'Start the mainloop' |
|
self.root = Tk() |
|
self.root.title(self.name) |
|
self.root.wm_protocol("WM_DELETE_WINDOW", self.stop) |
|
self.root.after(0, self.read_queue) |
|
try: |
|
self.root.mainloop() |
|
except KeyboardInterrupt: |
|
print('Process %d killed by CTRL-C' % os.getpid(), file=sys.stderr) |
|
except TerminatedProcess: |
|
pass |
|
|
|
def stop(self): |
|
self.root.quit() |
|
|
|
def read_queue(self): |
|
try: |
|
cmd_args = self.queue.get_nowait() |
|
except queue.Empty: |
|
pass |
|
else: |
|
getattr(self, cmd_args[0])(*cmd_args[1:]) |
|
self.root.after(100, self.read_queue) |
|
|