def destroy(self): self.crawler.quit() Notebook.destroy(self)
class GUI(tk.Tk): """ Start graphical interface for client. Args: client_queue_cmd: queue to send commands client_queue_log: queue to get logging info client_queue_telem: queue to get telemetry data beam_gap_queue: queue to retrieve beam gap data (any queue will do, this is handled via the gui, through the telemetry queue) @depricated server_ip: server IP address for rtp stream access """ def __init__(self, client_queue_cmd, client_queue_log, client_queue_telem, beam_gap_queue, destroyEvent, server_ip, **kwargs): tk.Tk.__init__(self, **kwargs) self.client_queue_cmd = client_queue_cmd self.client_queue_log = client_queue_log self.client_queue_telem = client_queue_telem self.beam_gap_queue = beam_gap_queue self.server_ip = server_ip self.destroyEvent = destroyEvent def init_ui(self): #make resizable self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.notebook = Notebook(self) # define mainapp instance -- also manages above telemetry thread self.mainApplication = MainApplication(self, self.client_queue_cmd, self.client_queue_log, self.client_queue_telem, self.beam_gap_queue, self.destroyEvent, self.server_ip) self.notebook.add(self.mainApplication, text="Main") # define telemetry widgets self.monitor = Monitor(self, VisualConstants.MARS_PRIMARY(1)) self.notebook.add(self.monitor, text='Monitor') self.notebook.grid(column=0, row=0, sticky='nsew') # menu -outside of notebook self.menu_ = TopMenu(self, '../gui/operations.json', self.client_queue_cmd, 'Commands') ### Add custom commands here self.menu_.add_menu_item('Reconnect to Cameras', self.mainApplication.start_streams, "View") self.menu_.add_menu_item('Left', self.mainApplication.focus_left, 'View/Camera Focus') self.menu_.add_menu_item('Center', self.mainApplication.focus_center, 'View/Camera Focus') self.menu_.add_menu_item('Right', self.mainApplication.focus_right, 'View/Camera Focus') self.menu_.add_menu_item('IBeam Display', self.beamGapGraph, 'View/Windows') self.menu_.add_menu_item('Toggle FOD Enabled', self.mainApplication.toggle_fod, 'View/Object Detection') self.menu_.add_menu_item('Set Ideal Images', self.mainApplication.define_ideal_images, 'View/Object Detection') ### self.menu_.finalize_menu_items() self.config(menu=self.menu_) # start all operations here so we don't cause a hissyfit between tkinter and threads self.mainApplication.start_streams() #define telemetryThread self.tthread = TelemetryThread( [self.mainApplication.telemetry_w, self.monitor], self.client_queue_telem, self.beam_gap_queue) self.tthread.start() # title and icon self.wm_title('Hyperloop Imaging Team') #this is garbage, i hate tkinter #self.img = ImageTk.PhotoImage(file='rit_imaging_team.xbm') #self.tk.call('wm', 'iconphoto', self._w, self.img) #self.iconbitmap('@rit_imaging_team.xbm') #call destroyCallback on clicking X self.protocol('WM_DELETE_WINDOW', self.destroyCallback) #assign dimensions and locatin on screen width = 900 height = 500 x = (self.winfo_screenwidth() // 2) - (width // 2) y = (self.winfo_screenheight() // 2) - (height // 2) self.geometry('{}x{}+{}+{}'.format(width, height, x, y)) self.update() def killMars(self): ''' Sends the kill command to Mars ''' logger.debug('GUI Killing Mars...') self.client_queue_cmd.put('exit') def displayMarsDisconnected(self): tkMessageBox.showerror( 'Lost connection to Mars', 'The client has lossed connection to mars, closing application.') self.destroyClient() def destroyClient(self): logger.debug('GUI Killing Main App...') self.menu_.destroy() self.mainApplication.close_() logger.debug('GUI Killing Monitor app...') self.monitor.destroy() self.notebook.destroy() logger.debug('GUI Killing Self...') self.killTelemThread() logger.debug('GUI Dead') self.quit() self.destroy() def killTelemThread(self): """ Customized quit function to allow for safe closure of processes. """ logger.debug('GUI Killing Telemetry...') self.tthread.stop() if self.tthread.is_alive(): self.tthread.join() def destroyCallback(self): ''' Function called when the window handle Destory is clicked (the x) Opens up a small prompt asking if you wanna kill mars ''' logger.debug('GUI entering destroy callback...') result = tkMessageBox.askyesno( 'Leaving GUI, Should Mars be Disabled?', 'Leaving GUI, should Mars be Disabled?') if result: self.killMars() self.destroyClient() def beamGapGraph(self): ''' Function that launches the Beam Gap Widget that displays the current beam distances in readalbe form. ''' if getattr(self, 'top', False) == False: self.top = BeamGapWidget(self, self.beam_gap_queue) self.top.title("VALMAR Beam Gap") else: if self.top['state'] != 'normal': self.top = BeamGapWidget(self, self.beam_gap_queue) self.top.title("VALMAR Beam Gap") def start(self): ''' Starts the root window ''' self.init_ui() try: self.mainloop() except KeyboardInterrupt: self.destroyClient()
class GUI(tk.Tk): """ Start graphical interface for client. Args: client_queue_cmd: queue to send commands client_queue_log: queue to get logging info client_queue_telem: queue to get telemetry data beam_gap_queue: queue to retrieve beam gap data (any queue will do, this is handled via the gui, through the telemetry queue) @depricated server_ip: server IP address for rtp stream access """ def __init__(self, client_queue_cmd, client_queue_log, client_queue_telem, beam_gap_queue, destroyEvent, server_ip, **kwargs): tk.Tk.__init__(self, **kwargs) self.client_queue_cmd = client_queue_cmd self.client_queue_log = client_queue_log self.client_queue_telem = client_queue_telem self.beam_gap_queue = beam_gap_queue self.server_ip = server_ip self.destroyEvent = destroyEvent def init_ui(self): #make resizable self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.notebook = Notebook(self) # define mainapp instance -- also manages above telemetry thread self.mainApplication = MainApplication(self, self.client_queue_cmd, self.client_queue_log, self.client_queue_telem, self.beam_gap_queue, self.destroyEvent, self.server_ip) self.notebook.add(self.mainApplication, text = "Main") # define telemetry widgets self.monitor = Monitor(self, VisualConstants.MARS_PRIMARY(1)) self.notebook.add(self.monitor, text = 'Monitor') self.notebook.grid(column = 0, row = 0, sticky = 'nsew') # menu -outside of notebook self.menu_ = TopMenu(self, '../gui/operations.json', self.client_queue_cmd, 'Commands') ### Add custom commands here self.menu_.add_menu_item('Reconnect to Cameras', self.mainApplication.start_streams, "View") self.menu_.add_menu_item('Left', self.mainApplication.focus_left, 'View/Camera Focus') self.menu_.add_menu_item('Center', self.mainApplication.focus_center, 'View/Camera Focus') self.menu_.add_menu_item('Right', self.mainApplication.focus_right, 'View/Camera Focus') self.menu_.add_menu_item('IBeam Display', self.beamGapGraph, 'View/Windows') self.menu_.add_menu_item('Toggle FOD Enabled', self.mainApplication.toggle_fod, 'View/Object Detection') self.menu_.add_menu_item('Set Ideal Images', self.mainApplication.define_ideal_images, 'View/Object Detection') ### self.menu_.finalize_menu_items() self.config(menu=self.menu_) # start all operations here so we don't cause a hissyfit between tkinter and threads self.mainApplication.start_streams() #define telemetryThread self.tthread = TelemetryThread([self.mainApplication.telemetry_w, self.monitor], self.client_queue_telem, self.beam_gap_queue) self.tthread.start() # title and icon self.wm_title('Hyperloop Imaging Team') #this is garbage, i hate tkinter #self.img = ImageTk.PhotoImage(file='rit_imaging_team.xbm') #self.tk.call('wm', 'iconphoto', self._w, self.img) #self.iconbitmap('@rit_imaging_team.xbm') #call destroyCallback on clicking X self.protocol('WM_DELETE_WINDOW', self.destroyCallback) #assign dimensions and locatin on screen width = 900 height = 500 x = (self.winfo_screenwidth() // 2) - (width // 2) y = (self.winfo_screenheight() // 2) - (height // 2) self.geometry('{}x{}+{}+{}'.format(width, height, x, y)) self.update() def killMars(self): ''' Sends the kill command to Mars ''' logger.debug('GUI Killing Mars...') self.client_queue_cmd.put('exit') def displayMarsDisconnected(self): tkMessageBox.showerror('Lost connection to Mars', 'The client has lossed connection to mars, closing application.') self.destroyClient() def destroyClient(self): logger.debug('GUI Killing Main App...') self.menu_.destroy() self.mainApplication.close_() logger.debug('GUI Killing Monitor app...') self.monitor.destroy() self.notebook.destroy() logger.debug('GUI Killing Self...') self.killTelemThread() logger.debug('GUI Dead') self.quit() self.destroy() def killTelemThread(self): """ Customized quit function to allow for safe closure of processes. """ logger.debug('GUI Killing Telemetry...') self.tthread.stop() if self.tthread.is_alive(): self.tthread.join() def destroyCallback(self): ''' Function called when the window handle Destory is clicked (the x) Opens up a small prompt asking if you wanna kill mars ''' logger.debug('GUI entering destroy callback...') result = tkMessageBox.askyesno('Leaving GUI, Should Mars be Disabled?', 'Leaving GUI, should Mars be Disabled?') if result: self.killMars() self.destroyClient() def beamGapGraph(self): ''' Function that launches the Beam Gap Widget that displays the current beam distances in readalbe form. ''' if getattr(self, 'top', False) == False: self.top = BeamGapWidget(self, self.beam_gap_queue) self.top.title("VALMAR Beam Gap") else: if self.top['state'] != 'normal': self.top = BeamGapWidget(self, self.beam_gap_queue) self.top.title("VALMAR Beam Gap") def start(self): ''' Starts the root window ''' self.init_ui() try: self.mainloop() except KeyboardInterrupt: self.destroyClient()