#!/usr/bin/python ''' handle display related work upon Tkinter ''' import Tkinter import tkMessageBox import sys import ri_cmd var_dict={} def init(base_w): ''' base_w - base widget instance ''' global root_window root_window = Tkinter.Tk() # grid management for root_window root_window.columnconfigure(0, weight=1) root_window.rowconfigure(0, weight=1) root_window.geometry("%sx%s+0+0" %(root_window.winfo_screenwidth(),root_window.winfo_screenheight())) global base_widget base_widget = create_widget_sub(base_w, root_window) def quit(): ''' exit root window ''' root_window.quit() def create_widget(w): ''' w - widget instance ''' create_widget_sub(w, base_widget) # set step name if 'name' in dir(w): # set step name which will be shown on base widget column 1 row 0 var_dict['main.step_name'].set(w.name) class MyImage: ''' MyImage - a dummy class to hold Image variable ''' count = 0 def modify_attributes(attr_dict): ''' modify values in attr_dict to suit Tk usage ''' for a in attr_dict.keys(): if a == 'image': # I think there is a bug in Tkinter on Image processing # I have to bypass it in the following way: image_var = 'a' + str(MyImage.count) setattr(MyImage, image_var, Tkinter.PhotoImage(file=attr_dict[a])) MyImage.count += 1 attr_dict[a] = getattr(MyImage, image_var) elif a == 'command': attr_dict[a] = getattr(sys.modules["ri_cmd"], attr_dict[a]) elif a == "textvariable" or a == "listvariable": attr_dict[a] = var_dict[attr_dict[a]] def create_widget_sub(w, p_win): ''' w - widget instance p_win - Tk parent window ''' # name type and value for v_n, v_t, v_v in w.variables: if not v_n in var_dict.keys(): # if not yet in dict, create it var_dict[v_n] = getattr(Tkinter, v_t)(value=v_v) # process action init if 'action' in dir(w) and 'init' in w.action.dict: getattr(sys.modules['ri_cmd'], w.action.dict['init'])() # change attr, if needed to suit tk tk_attr = dict(w.attr) modify_attributes(tk_attr) tk_func = getattr(Tkinter, w.tp) w_win = tk_func(p_win, tk_attr) # display sub widgets for sub_w in w.widgets: create_widget_sub(sub_w, w_win) # grid management if 'grid_management' in dir(w): for cf in w.grid_management.cf_list: cf_func = getattr(w_win, cf[0]) cf_func( cf[1], weight=cf[2]) # grid location if 'grid_location' in dir(w): w_win.grid(w.grid_location.dict) # save tk widget instance into w (widget instance) setattr(w, 'tk_widget', w_win) return w_win # When creating widget, I have to create each sub widget. # while destroying a widget, only destroy one. Tk functions will # destroy all descendant. # so init is a little different from quit. def process_action_quit(w): ''' process action quit ''' if 'action' in dir(w) and 'quit' in w.action.dict: getattr(sys.modules['ri_cmd'], w.action.dict['quit'])() if 'widgets' in dir(w): for sub_w in w.widgets: process_action_quit(sub_w) def destroy_widget(w): ''' w - Widget instance ''' # process action quit process_action_quit(w) w.tk_widget.destroy() def create_message_box(w): ''' display MessageBox w - widget instance''' disp = getattr(tkMessageBox, "show%s" %(w.tp)) disp(w.title, w.message)