mainWindow.py 4.0 KB

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