mainWindow.py 4.9 KB

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