You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
1.8 KiB

4 years ago
  1. from __future__ import print_function
  2. import os
  3. import sys
  4. import Queue
  5. import plac_core
  6. from Tkinter import Tk
  7. from ScrolledText import ScrolledText
  8. from plac_ext import Monitor, TerminatedProcess
  9. class TkMonitor(Monitor):
  10. """
  11. An interface over a dictionary {taskno: scrolledtext widget}, with
  12. methods add_listener, del_listener, notify_listener and start/stop.
  13. """
  14. def __init__(self, name, queue=None):
  15. Monitor.__init__(self, name, queue)
  16. self.widgets = {}
  17. @plac_core.annotations(taskno=('task number', 'positional', None, int))
  18. def add_listener(self, taskno):
  19. "There is a ScrolledText for each task"
  20. st = ScrolledText(self.root, height=5)
  21. st.insert('end', 'Output of task %d\n' % taskno)
  22. st.pack()
  23. self.widgets[taskno] = st
  24. @plac_core.annotations(taskno=('task number', 'positional', None, int))
  25. def del_listener(self, taskno):
  26. del self.widgets[taskno]
  27. @plac_core.annotations(taskno=('task number', 'positional', None, int))
  28. def notify_listener(self, taskno, msg):
  29. w = self.widgets[taskno]
  30. w.insert('end', msg + '\n')
  31. w.update()
  32. def start(self):
  33. 'Start the mainloop'
  34. self.root = Tk()
  35. self.root.title(self.name)
  36. self.root.wm_protocol("WM_DELETE_WINDOW", self.stop)
  37. self.root.after(0, self.read_queue)
  38. try:
  39. self.root.mainloop()
  40. except KeyboardInterrupt:
  41. print('Process %d killed by CTRL-C' % os.getpid(), file=sys.stderr)
  42. except TerminatedProcess:
  43. pass
  44. def stop(self):
  45. self.root.quit()
  46. def read_queue(self):
  47. try:
  48. cmd_args = self.queue.get_nowait()
  49. except Queue.Empty:
  50. pass
  51. else:
  52. getattr(self, cmd_args[0])(*cmd_args[1:])
  53. self.root.after(100, self.read_queue)