mainWindow.py 5.0 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. class MainWindow(tk.Frame):
  9. def __init__(self, root, ac_sensor, ac_queue, ac_cal_state, log_handler):
  10. self.root = root
  11. self.popup = None
  12. self.log_window = None
  13. self.ac_cal_state = ac_cal_state
  14. self.ac_sensor = ac_sensor
  15. self.ac_queue = ac_queue
  16. self.log_handler = log_handler
  17. self.log_handler.add_item("start Main Window")
  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="Acustic 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=2, foreground="red")
  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_queue.qsize() > 0:
  52. name, data = self.ac_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. self.log_handler.add_item("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)
  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() - 1000) / 2
  108. y = (self.log_root.winfo_screenheight() - 400) / 2
  109. self.log_root.geometry(f'1000x400+{int(x)}+{int(y)}')
  110. # deactivate mainWindow
  111. self.log_root.grab_set()
  112. self.log_window = LogScreen(self.log_root,self.log_handler)
  113. self.log_window.pack(side="top", fill="both", expand=True)