mainWindow.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import time
  2. import queue
  3. import tkinter as tk
  4. import numpy as np
  5. from gui.popup import CalibrationPopUp
  6. from gui.graph import Graph
  7. from gui.logScreen import LogScreen
  8. import logHandler
  9. class MainWindow(tk.Frame):
  10. def __init__(self, root, ac_sensor, ac_queue, ac_cal_state, conf):
  11. self.root = root
  12. self.popup = None
  13. self.log_window = None
  14. self.ac_cal_state = ac_cal_state
  15. self.ac_sensor = ac_sensor
  16. self.ac_queue = ac_queue
  17. self.log_handler = logHandler.get_log_handler()
  18. self.conf = conf
  19. tk.Frame.__init__(self, root)
  20. # data plot at left side
  21. self.graph = Graph(self)
  22. self.graph.pack(fill=tk.BOTH, side=tk.LEFT, expand=True)
  23. # frame at right side
  24. self.controls = tk.Frame(self, borderwidth=4)
  25. self.controls.pack(fill=tk.BOTH, side=tk.RIGHT)
  26. self.controlsUpdateTime = 0
  27. self.ac_dro_val_sums = np.ndarray((4), dtype=np.float)
  28. self.ac_dro_val_count = 0
  29. self.ac_dro_x = tk.StringVar()
  30. self.ac_dro_y = tk.StringVar()
  31. self.ac_dro_t1 = tk.StringVar()
  32. self.ac_dro_t2 = tk.StringVar()
  33. self.ac_label = tk.Label(self.controls, text="Acoustic Sensor", anchor="c", font=("Helvatica", 10, 'bold'))
  34. self.ac_label.pack(side="top", fill="both", expand=False)
  35. tk.Label(self.controls, textvariable=self.ac_dro_x, anchor="nw").pack(side="top", fill="both", expand=False)
  36. tk.Label(self.controls, textvariable=self.ac_dro_y, anchor="nw").pack(side="top", fill="both", expand=False)
  37. tk.Label(self.controls, textvariable=self.ac_dro_t1, anchor="nw").pack(side="top", fill="both", expand=False)
  38. tk.Label(self.controls, textvariable=self.ac_dro_t2, anchor="nw").pack(side="top", fill="both", expand=False)
  39. quit_button = tk.Button(self.controls, text="Quit", command=self.root.destroy, height=2, foreground="red")
  40. quit_button.pack(side="bottom", fill="both")
  41. calibrate_button = tk.Button(self.controls, text="Calibrate", command=self.calibrate, height=4)
  42. calibrate_button.pack(side="bottom", fill="both")
  43. clear_button = tk.Button(self.controls, text="Clear graph", command=self.graph.clear, height=4)
  44. clear_button.pack(side="bottom", fill="both")
  45. logscreen_button = tk.Button(self.controls, text="Log", command=self.open_log, height=4)
  46. logscreen_button.pack(side="bottom", fill="both")
  47. def update(self):
  48. if not self.root.winfo_exists():
  49. return
  50. ac_positions = []
  51. # aggregate measurements
  52. while self.ac_queue.qsize() > 0:
  53. name, data = self.ac_queue.get()
  54. if name == "data":
  55. ac_positions.append(data[0:2])
  56. self.ac_dro_val_sums += data
  57. self.ac_dro_val_count += 1
  58. # graph shows all values as a line
  59. self.graph.update([ac_positions])
  60. # update status color
  61. if self.ac_sensor.dummyActive:
  62. self.ac_label.config(fg="white", bg="red")
  63. elif len(ac_positions) > 0:
  64. self.ac_label.config(fg="white", bg="green")
  65. else:
  66. self.ac_label.config(fg="black", bg="yellow")
  67. # readouts will only be updated so often
  68. if self.controlsUpdateTime + 0.4 < time.time():
  69. self.controlsUpdateTime = time.time()
  70. # they display the average of all values
  71. if self.ac_dro_val_count > 0:
  72. self.ac_dro_val_sums /= self.ac_dro_val_count
  73. else:
  74. self.ac_dro_val_sums.fill(0)
  75. self.ac_dro_x.set("X: {:.1f} mm".format(self.ac_dro_val_sums[0]))
  76. self.ac_dro_y.set("Y: {:.1f} mm".format(self.ac_dro_val_sums[1]))
  77. self.ac_dro_t1.set("t1: {:.3f} ms".format(self.ac_dro_val_sums[2]/1000))
  78. self.ac_dro_t2.set("t2: {:.3f} ms".format(self.ac_dro_val_sums[3]/1000))
  79. self.ac_dro_val_sums.fill(0)
  80. self.ac_dro_val_count = 0
  81. if self.popup:
  82. self.popup.update()
  83. if self.log_window:
  84. self.log_window.update()
  85. self.root.after(30, self.update)
  86. def calibrate(self):
  87. self.ac_sensor.start_calibration()
  88. if not self.popup or not self.pu_root.winfo_exists():
  89. # create new window
  90. self.pu_root = tk.Toplevel(self.root)
  91. self.pu_root.wm_transient(self.root)
  92. self.pu_root.wm_title("Calibration")
  93. # make it centered
  94. x = (self.pu_root.winfo_screenwidth() - 500) / 2
  95. y = (self.pu_root.winfo_screenheight() - 200) / 2
  96. self.pu_root.geometry(f'500x200+{int(x)}+{int(y)}')
  97. # deactivate mainWindow
  98. self.pu_root.grab_set()
  99. self.popup = CalibrationPopUp(self.pu_root, self.ac_cal_state, self.conf)
  100. self.popup.pack(side="top", fill="both", expand=True)
  101. def open_log(self):
  102. #create new window
  103. self.log_root = tk.Toplevel(self.root)
  104. self.log_root.wm_transient(self.root)
  105. self.log_root.wm_title("Logs")
  106. #center
  107. x = (self.log_root.winfo_screenwidth() - 780) / 2
  108. y = (self.log_root.winfo_screenheight() - 400) / 2
  109. self.log_root.geometry(f'780x400+{int(x)}+{int(y)}')
  110. # deactivate mainWindow
  111. self.log_root.grab_set()
  112. self.log_window = LogScreen(self.log_root)
  113. self.log_window.pack(side="top", fill="both", expand=True)