class MainApplication: ''' Main class that initiate all (gui + server + logger) ''' def __init__(self, root, log_level, ip, port ): self.root = root self.log_level = log_level self.ip = ip self.port = port self.root.columnconfigure(0, weight=1) self.root.rowconfigure(0, weight=1) self.root.geometry('1024x680') # 2 rows: firts with settings, second with registrar data self.main_frame = tk.Frame(self.root) # Commands row doesn't expands self.main_frame.rowconfigure(0, weight=0) # Logs row will grow self.main_frame.rowconfigure(1, weight=1) # Main fram can enlarge self.main_frame.columnconfigure(0, weight=1) self.main_frame.columnconfigure(1, weight=1) self.main_frame.columnconfigure(2, weight=1) self.main_frame.columnconfigure(3, weight=1) self.main_frame.columnconfigure(4, weight=1) self.main_frame.grid(row=0, column=0, sticky=tk.NSEW) self.main_frame.configure(bg=frame_bgr_stop) #self.port_text.insert('end',port) # Run/Stop button self.control_button = tk.Button(self.main_frame, text="Run Server", font=btn_font, bg=btn_clr, command=self.run_server) self.control_button.grid(row=0, column=0, ipady=10) self.L1 = tk.Label(self.main_frame, text="Port number", bg=frame_bgr_stop, font=('Century Gotic', 12, 'bold')) self.L1.grid(row=0, column=1, ipady=10) self.E1 = tk.Entry(self.main_frame, width=10, font=btn_font) self.E1.grid(row=0, column=2, ipady=10) self.E1.insert('end', '1234') # Clear button self.clear_button = tk.Button(self.main_frame, text="Clear Log", font=btn_font, bg=btn_clr, command=self.clear_log) self.clear_button.grid(row=0, column=3, ipady=10) # Stop log button self.control_log_button = tk.Button(self.main_frame, text="Pause Log", font=btn_font, bg=btn_clr, command=self.stop_log) self.control_log_button.grid(row=0, column=4, ipady=10) # Logs Widget self.log_widget = ScrolledText(self.main_frame) self.log_widget.grid(row=1, column=0, columnspan=5, sticky=tk.NSEW) # Not editable self.log_widget.config(state='disabled') # Queue where the logging handler will write self.log_queue = queue.Queue() # Stup the logger l = logging.getLogger('logger') l.setLevel(self.log_level) formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') # Use the QueueLogger as Handler hl = QueueLogger(queue=self.log_queue) hl.setFormatter(formatter) l.addHandler(hl) self.logger = logging.getLogger('logger') # Setup the update_widget callback reading logs from the queue self.start_log() def stop_log(self): self.logger.info("Pausing the logger") if self.logger_alarm is not None: self.log_widget.after_cancel(self.logger_alarm) self.control_log_button.configure(text="Start Log", command=self.start_log) self.logger_alarm = None def start_log(self): self.logger.info("Starting the logger") self.update_widget(self.log_widget, self.log_queue) self.control_log_button.configure(text="Pause Log", command=self.stop_log) def update_widget(self, widget, queue): widget.config(state='normal') # Read from the Queue and add to the log widger while not queue.empty(): line = queue.get() widget.insert(tk.END, line) widget.see(tk.END) # Scroll to the bottom widget.update_idletasks() widget.config(state='disabled') self.logger_alarm = widget.after(10, self.update_widget, widget, queue) def clear_log(self): self.log_widget.config(state='normal') self.log_widget.delete(0.0, tk.END) self.log_widget.config(state='disabled') # run_server - open connection when the button is pressed def run_server(self): self.port = int(self.E1.get()) self.logger.info("Starting Server on ip %s and port %d",self.ip, self.port) try: self.server = LoggedTCPServer((self.ip, self.port), MyTCPHandler, self.logger) self.server_thread = threading.Thread(name='server', target=self.server.serve_forever) self.server_thread.daemon = True self.server_thread.start() self.control_button.configure(text="Stop Server", command=self.stop_server) self.main_frame.configure(bg=frame_bgr_run) self.L1.configure(bg=frame_bgr_run) except Exception: self.logger.error("Cannot start the server: %s",str(self.ip)) raise Exception # stop_server - close connection when the button is pressed def stop_server(self): self.logger.info("Stopping server") self.server.shutdown() self.server.socket.close() self.logger.debug("Server stopped") self.control_button.configure(text="Run Server", command=self.run_server) self.main_frame.configure(bg=frame_bgr_stop) self.L1.configure(bg=frame_bgr_stop)