mainWindow.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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, conf, ac_sensor, opt_sensor):
  11. self.root = root
  12. self.conf = conf
  13. self.ac_sensor = ac_sensor
  14. self.opt_sensor = opt_sensor
  15. self.log_handler = logHandler.get_log_handler()
  16. self.popup_window = None
  17. self.log_window = None
  18. self.mainWindow= None
  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. self.opt_dro_val_sums = np.ndarray((4), dtype=np.float)
  40. self.opt_dro_val_count = 0
  41. self.opt_dro_x = tk.StringVar()
  42. self.opt_dro_y = tk.StringVar()
  43. self.opt_dro_offset = tk.StringVar()
  44. self.opt_dro_size = tk.StringVar()
  45. self.opt_label = tk.Label(self.controls, text="Optical Sensor", anchor="c", font=("Helvatica", 10, 'bold'))
  46. self.opt_label.pack(side="top", fill="both", expand=False)
  47. tk.Label(self.controls, textvariable=self.opt_dro_x, anchor="nw").pack(side="top", fill="both", expand=False)
  48. tk.Label(self.controls, textvariable=self.opt_dro_y, anchor="nw").pack(side="top", fill="both", expand=False)
  49. tk.Label(self.controls, textvariable=self.opt_dro_offset, anchor="nw").pack(side="top", fill="both", expand=False)
  50. tk.Label(self.controls, textvariable=self.opt_dro_size, anchor="nw").pack(side="top", fill="both", expand=False)
  51. self.quit_button = tk.Button(self.controls, text="Quit", command=self.root.destroy, height=2, foreground="red")
  52. self.quit_button.pack(side="bottom", fill="both")
  53. self.calibrate_button = tk.Button(self.controls, text="Calibrate AC", command=self.calibrate_ac, height=4)
  54. self.calibrate_button.pack(side="bottom", fill="both")
  55. self.clear_button = tk.Button(self.controls, text="Clear graph", command=self.graph.clear, height=4)
  56. self.clear_button.pack(side="bottom", fill="both")
  57. self.logscreen_button = tk.Button(self.controls, text="Log", command=self.open_log, height=4)
  58. self.logscreen_button.pack(side="bottom", fill="both")
  59. self.menu_button = tk.Button(self.controls, text="Menu", command=self.menu, height=4)
  60. self.menu_button.pack(side="bottom", fill="both")
  61. self.menu_back_button = tk.Button(self.controls, text="Back", command=self.back, height=4)
  62. self.menu_back_button.pack_forget()
  63. #"verstecken" der Buttons für Platz für Statusanzeigen Magnetsensor
  64. self.calibrate_button.pack_forget()
  65. self.clear_button.pack_forget()
  66. self.logscreen_button.pack_forget()
  67. def update(self):
  68. if not self.root.winfo_exists():
  69. return
  70. ac_positions = []
  71. # aggregate measurements
  72. while self.ac_sensor.queue.qsize() > 0:
  73. name, data = self.ac_sensor.queue.get()
  74. if name == "data":
  75. ac_positions.append(data[0:2])
  76. self.ac_dro_val_sums += data
  77. self.ac_dro_val_count += 1
  78. opt_positions = []
  79. while self.opt_sensor.queue.qsize() > 0:
  80. name, data = self.opt_sensor.queue.get()
  81. if name == "data":
  82. opt_positions.append(data[0:2])
  83. self.opt_dro_val_sums += data
  84. self.opt_dro_val_count += 1
  85. # graph shows all values as a line
  86. self.graph.update([ac_positions, opt_positions])
  87. # update status color
  88. if self.ac_sensor.dummyActive:
  89. self.ac_label.config(fg="white", bg="red")
  90. elif len(ac_positions) > 0:
  91. self.ac_label.config(fg="white", bg="green")
  92. else:
  93. self.ac_label.config(fg="black", bg="yellow")
  94. if not self.opt_sensor.success:
  95. self.opt_label.config(fg="white", bg="red")
  96. elif len(opt_positions) > 0:
  97. self.opt_label.config(fg="white", bg="green")
  98. else:
  99. self.opt_label.config(fg="black", bg="yellow")
  100. # readouts will only be updated so often
  101. if self.controlsUpdateTime + 0.4 < time.time():
  102. self.controlsUpdateTime = time.time()
  103. # they display the average of all values
  104. if self.ac_dro_val_count > 0:
  105. self.ac_dro_val_sums /= self.ac_dro_val_count
  106. else:
  107. self.ac_dro_val_sums.fill(0)
  108. self.ac_dro_x.set("X: {:.1f} mm".format(self.ac_dro_val_sums[0]))
  109. self.ac_dro_y.set("Y: {:.1f} mm".format(self.ac_dro_val_sums[1]))
  110. self.ac_dro_t1.set("t1: {:.3f} ms".format(self.ac_dro_val_sums[2]/1000))
  111. self.ac_dro_t2.set("t2: {:.3f} ms".format(self.ac_dro_val_sums[3]/1000))
  112. self.ac_dro_val_sums.fill(0)
  113. self.ac_dro_val_count = 0
  114. if self.opt_dro_val_count > 0:
  115. self.opt_dro_val_sums /= self.opt_dro_val_count
  116. else:
  117. self.opt_dro_val_sums.fill(0)
  118. self.opt_dro_x.set("X: {:.1f} mm".format(self.opt_dro_val_sums[0]))
  119. self.opt_dro_y.set("Y: {:.1f} mm".format(self.opt_dro_val_sums[1]))
  120. self.opt_dro_offset.set("offset: {:.1f} %".format(self.opt_dro_val_sums[2]*100))
  121. self.opt_dro_size.set("size: {:.1f} %".format(self.opt_dro_val_sums[3]*100))
  122. self.opt_dro_val_sums.fill(0)
  123. self.opt_dro_val_count = 0
  124. if self.popup_window:
  125. self.popup_window.update()
  126. if self.log_window:
  127. self.log_window.update()
  128. self.root.after(30, self.update)
  129. def calibrate_ac(self):
  130. self.ac_sensor.start_calibration()
  131. if not self.popup_window or not self.pu_root.winfo_exists():
  132. # create new window
  133. self.pu_root = tk.Toplevel(self.root)
  134. self.pu_root.wm_transient(self.root)
  135. self.pu_root.wm_title("Acoustic Sensor Calibration")
  136. # make it centered
  137. x = (self.pu_root.winfo_screenwidth() - 500) / 2
  138. y = (self.pu_root.winfo_screenheight() - 200) / 2
  139. self.pu_root.geometry(f'500x200+{int(x)}+{int(y)}')
  140. # deactivate mainWindow
  141. self.pu_root.grab_set()
  142. self.popup_window = CalibrationPopUp(self.pu_root, self.ac_sensor.calibration_state, self.conf)
  143. self.popup_window.pack(side="top", fill="both", expand=True)
  144. def open_log(self):
  145. #create new window
  146. self.log_root = tk.Toplevel(self.root)
  147. self.log_root.wm_transient(self.root)
  148. self.log_root.wm_title("Logs")
  149. #center
  150. x = (self.log_root.winfo_screenwidth() - 780) / 2
  151. y = (self.log_root.winfo_screenheight() - 400) / 2
  152. self.log_root.geometry(f'780x400+{int(x)}+{int(y)}')
  153. # deactivate mainWindow
  154. self.log_root.grab_set()
  155. self.log_window = LogScreen(self.log_root)
  156. self.log_window.pack(side="top", fill="both", expand=True)
  157. def menu(self):
  158. #Menu
  159. self.calibrate_button.pack(side="bottom", fill="both")
  160. self.clear_button.pack(side="bottom", fill="both")
  161. self.logscreen_button.pack(side="bottom", fill="both")
  162. self.menu_button.pack_forget()
  163. self.menu_back_button.pack(side="bottom", fill="both")
  164. def back(self):
  165. self.calibrate_button.pack_forget()
  166. self.clear_button.pack_forget()
  167. self.logscreen_button.pack_forget()
  168. self.menu_button.pack(side="bottom", fill="both")
  169. self.menu_back_button.pack_forget()