#!/usr/bin/python # -*- coding: utf-8 -*- # """ Nome: TkInterface.py Autor: Alessandro dos Santos Ferreira ( santosferreira.alessandro@gmail.com ) Descricão: Classe que implementa os modulos de interface utilizando a biblioteca TkInter. """ import sys if sys.version_info[0] < 3: import Tkinter as Tk else: import tkinter as Tk import tkMessageBox from Interface import Interface, InterfaceException as IException from tk import * class TkInterface(Interface): MAX_CLASSES = 20 utils = TkUtils.Utils title = None __root = None __menus = None __image = None __grid = None __logger = None def __init__(self, title): self.title = title self.__root = Tk.Tk() self.__root.wm_title(self.title) self.__root.geometry('%dx%d+%d+%d' % (800, 600, 0, 0)) self.__menus = [] def set_subtitle(self, subtitle): self.__root.wm_title(self.title + ' - ' + subtitle) def add_menu(self, label): self.__menus.append( TkMenu.Menu(self.__root, label) ) def add_command(self, label, action, shortcut = None): self.__menus[-1].add_command( label = label, action = lambda *_: self.__apply( action ), shortcut = shortcut ) def add_separator(self): self.__menus[-1].add_separator( ) def add_check_button(self, label, action, shortcut = None): self.__menus[-1].add_check_button(label = label, action = lambda *_: self.__apply( action ), shortcut = shortcut) def render_menu(self): menubar = Tk.Menu(self.__root) for menu in self.__menus: menu.render(menubar) self.__root.config(menu=menubar) def add_image(self, image, title = None, onclick = None): if self.__image is not None: self.__image.close() self.__image = TkCanvas.Image(self.__root, image, lambda event, *_: self.__apply( onclick, event )) if title is not None: self.set_subtitle(title) def refresh_image(self, image, title = None): if self.__image is not None: self.__image.refresh(image) if title is not None: self.set_subtitle(title) def close_image(self): if self.__image is not None: if tkMessageBox.askokcancel("Quit", "Do you want to close the image?"): self.__image.close() self.__image = None return True return False def open_log(self): self.__logger = TkLogger.Logger(self.__root) def write_log(self, fmt, *args): if self.__logger: self.__logger.write_logger(fmt, *args) def append_log(self, fmt, *args): if self.__logger: self.__logger.append_logger(fmt, *args) def clear_log(self): if self.__logger: self.__logger.clear_logger() def toogle_log(self): if self.__logger: self.close_log() else: self.open_log() def close_log(self): if self.__logger: self.__logger.destroy_logger() self.__logger = None def add_panel(self, left = True): self.__grid = TkCustomFrame.CustomGrid(self.__root, 175) side = Tk.LEFT if left == True else Tk.RIGHT self.__grid.pack(side=side, fill=Tk.Y, expand=False) def add_panel_classes(self, classes = None, selected = 0): if self.__grid is None: self.__grid = TkCustomFrame.CustomGrid(self.__root) self.clear_panel_classes() classes = classes if classes is not None else [] self.__grid.add_cell_label("", 0, 0, 1, 4) self.__grid.add_cell_label("Classes ", 0, 1, 12, 4) self.__grid.add_cell_label("", 0, 3, 2, 4) length = len(classes) for i in range(1, length+1): self.__grid.add_cell_radio_button(classes[i-1]["name"].value[:12], i, i, 1, 12, selected=True if i == selected+1 else False, command=classes[i-1]["callback"].value, command_args=classes[i-1]["args"].value ) self.__grid.add_cell_button_color("", i, 2, 2, bg=classes[i-1]["color"].value, command=classes[i-1]["callback_color"].value, command_args=classes[i-1]["args"].value ) self.__grid.pack(side=Tk.LEFT, fill=Tk.Y, expand=False) def refresh_panel_classes(self, classes = None, selected = 0): self.clear_panel_classes() self.add_panel_classes(classes, selected) def clear_panel_classes(self): for i in range(1, self.MAX_CLASSES+1): self.__grid.add_cell_label("", i, 1, 15) self.__grid.add_cell_label("", i, 2, 2) def close_panel(self): if self.__grid is not None: self.__grid.pack_forget(); self.__grid.destroy(); def popup(self): pass def log_and_popup(self, message): pass def dialogue_config(self, title, configs, callback): self.__conf_dialog = TkCustomDialog.ConfigDialog(self.__root, title, configs, command_ok = lambda *_: self.__apply( callback )) def get_config_and_destroy(self): if self.__conf_dialog is None: return None try: self.__conf_dialog.update_and_validate_configs() configs = self.__conf_dialog.get_configs() self.__conf_dialog.destroy() self.__conf_dialog = None return configs except: self.__conf_dialog.destroy() raise IException("Illegal values, please try again") def show_error(self, fmt, *args): tkMessageBox.showerror("Error", fmt % args) def show_info(self, fmt, *args): tkMessageBox.showinfo("Info", fmt % args) def show_warning(self, fmt, *args): tkMessageBox.showwarning("Warning", fmt % args) def show(self): self.__root.protocol("WM_DELETE_WINDOW", self.quit) self.__root.mainloop() def quit(self): if tkMessageBox.askokcancel("Quit", "Do you want to quit?"): self.__root.quit() self.__root.destroy() def debug(self, event): print("DEBUG") def __apply(self, f, *args): try: f(*args) except IException as exc: self.__log_exception( str(exc), True ) except: self.__log_exception( IException.format_exception() ) def __log_exception(self, message, warning = False): if warning == True: self.show_warning( message ) elif IException.DEBUG == True: self.append_log( message ) else: self.show_error( message )