Files
new_install/interface/ri_tk.py
fling 3093360d0c modified: ri_cmd.py
modified:   ri_oper.py
	modified:   ri_tk.py
	modified:   ri_tk_cmd.py
	modified:   ri_widget.py
    add network check ip and hostname update
2010-12-09 12:23:48 +08:00

363 lines
12 KiB
Python

#!/usr/bin/python
''' handle display related work upon Tkinter '''
import Tkinter
import tkMessageBox
import sys
import ri_cmd
import ri_widget
import os.path
var_dict={}
# language should be all lower case letters
language='english'
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()))
root_window.title('Linx')
# bind WM_DELETE_WINDOW
root_window.protocol("WM_DELETE_WINDOW", root_window.quit)
global base_widget
base_widget = create_widget_sub(base_w, root_window)
def quit():
''' exit root window '''
root_window.quit()
def set_step_info(s):
''' set some information in base widget '''
# set step name which will be shown on base widget column 1 row 0
title = translate_text(s)
var_dict['main.step_name'].set(title)
def set_help_info(s):
''' set help information in base widget'''
help = translate_text(s)
w = ri_widget.Widget.dict['main.help'].tk_widget
w.configure(state='normal')
w.delete(1.0,Tkinter.END)
w.insert(1.0,help)
w.configure(state='disable')
def create_widget(w):
''' w - widget instance '''
create_widget_sub(w, base_widget)
# set step name
if 'name' in dir(w):
set_step_info(w.name)
set_help_info('#'+w.name+'.help')
class MyImage:
''' MyImage - a dummy class to hold Image variable '''
count = 0
def translate_text(txt):
''' multi-language support, translate t if needed '''
key = txt.lower()
if key in ri_widget.Text.dict.keys() and (txt[0] == '#' or language != 'english'):
return getattr(ri_widget.Text.dict[key], language)
else:
return txt
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)
drt = os.path.join(os.path.dirname(__file__), '../data')
setattr(MyImage, image_var, Tkinter.PhotoImage(file=os.path.join(drt, 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" or a == 'variable':
attr_dict[a] = var_dict[attr_dict[a]]
elif a == "text":
attr_dict[a] = translate_text(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)
# 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)
# save tk widget instance into w (widget instance)
setattr(w, 'tk_widget', w_win)
# display sub widgets
for sub_w in w.widgets:
create_widget_sub(sub_w, w_win)
# process action init
if 'action' in dir(w) and 'init' in w.action.dict:
getattr(sys.modules['ri_cmd'], w.action.dict['init'])()
# handle scroll bar for sub_widgets
if 'action' in dir(w):
# ing for scrolling, ed for scrolled
for ing, ed in w.action.scrolls:
ing_win = w.dict[ing].tk_widget
ed_win = w.dict[ed].tk_widget
if ing_win['orient'] == 'vertical':
ed_cmd_name = 'yscrollcommand'
ing_cmd = getattr(ed_win, 'yview')
else:
ed_cmd_name = 'xscrollcommand'
ing_cmd = getattr(ed_win, 'xview')
ing_win.configure(command=ing_cmd)
ed_win[ed_cmd_name]=ing_win.set
# 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)
# handle bindings
for bd in w.bindings:
w_win.bind(bd[0], getattr(ri_cmd, bd[1]))
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(w)
w.tk_widget.destroy()
def create_message_box(w):
''' display MessageBox
w - MessageBox instance'''
disp = getattr(tkMessageBox, w.tp)
code = disp(translate_text(w.title), translate_text(w.message))
return code
def create_top_window(w):
''' display TopWindow
w - TopWindow instance '''
tk_attr = dict(w.attr)
modify_attributes(tk_attr)
w_win = Tkinter.Toplevel(root_window, tk_attr)
for sub_w in w.widgets:
create_widget_sub(sub_w, w_win)
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])
# save tk widget instance into w (TopWindow instance)
setattr(w, 'tk_widget', w_win)
# 'bind' it to root window
w_win.transient(root_window)
# grab all events into it
while True:
try:
w_win.grab_set()
except Tkinter.TclError:
pass
else:
break
w_win.wait_window()
return w_win
def destroy_top_window(w):
''' w - Toplevel instance '''
w.tk_widget.destroy()
class SoftwarePackageWindow():
''' Toplevel window for a group of software packages
class member
---------------------------
dict - class static member
instance member
---------------------------
group - data layer group instance
win - Tk widget
selection - StringVar variable for 'select_all'
opt_vars - a list to hold variables containing status for optional packages
opt_chks - a list to hold Checkbuttons for optional packages
'''
dict = {}
def __init__(self, g):
self.group = g
self.opt_vars = []
self.opt_chks = []
SoftwarePackageWindow.dict[g.name] = self
def select_all(self):
''' callback function for check button select_all '''
if self.selection.get() == 'all':
for ck in self.opt_chks:
ck.configure(state='disable')
else:
for ck in self.opt_chks:
ck.configure(state='normal')
def ok(self):
''' callback function for button OK '''
self.group.selection = self.selection.get()
for i in range(len(self.group.optional)):
# install field, yes or no
self.group.optional[i][1] = self.opt_vars[i].get()
# clear variables and check buttons
self.opt_vars = []
self.opt_chks = []
self.win.destroy()
def cancel(self):
''' callback function for button cancel '''
# clear variables and check buttons
self.opt_vars = []
self.opt_chks = []
self.win.destroy()
def show(self):
win = Tkinter.Toplevel(root_window)
self.win = win
win.geometry("%sx%s+%s+%s" %(int(root_window.winfo_screenwidth()*0.8),\
int(root_window.winfo_screenheight()*0.8),\
int(root_window.winfo_screenwidth()*0.1),\
int(root_window.winfo_screenheight()*0.1)))
win.columnconfigure(0, weight=1)
win.rowconfigure(1, weight=1)
win.rowconfigure(4, weight=1)
text_mdt = translate_text('Mandatory')
Tkinter.Label(win, text=text_mdt).grid(column=0, row=0)
cnv1 = Tkinter.Canvas(win)
hs1 = Tkinter.Scrollbar(win, orient='horizontal')
hs1.configure(command=cnv1.xview)
vs1 = Tkinter.Scrollbar(win, orient='vertical')
vs1.configure(command=cnv1.yview)
cnv1.grid(column=0, row=1, sticky='NWES')
vs1.grid(column=1, row=1, sticky='NSW')
hs1.grid(column=0, row=2, sticky='NWE')
cnv1.configure(yscrollcommand=vs1.set, xscrollcommand=hs1.set)
fr1 = Tkinter.Frame(cnv1)
cnv1.create_window((0,0), window=fr1, anchor='nw')
#column set to 5
fr1.columnconfigure(0, weight=1)
fr1.columnconfigure(1, weight=1)
fr1.columnconfigure(2, weight=1)
fr1.columnconfigure(3, weight=1)
fr1.columnconfigure(4, weight=1)
for i in range(len(self.group.mandatory)):
Tkinter.Label(fr1, text=self.group.mandatory[i]).grid(column=i%5, row=i/5, sticky='NWES')
text_opt = translate_text('Optional')
Tkinter.Label(win, text=text_opt).grid(column=0, row=3)
self.selection = Tkinter.StringVar(value=self.group.selection)
text_sal = translate_text('Select all')
chk_sa = Tkinter.Checkbutton(win, text=text_sal, command=self.select_all, variable=self.selection, onvalue='all', offvalue='manual')
chk_sa.grid(column=1, row=3)
if self.group.selection == 'all':
chk_sa.select()
else:
chk_sa.deselect()
cnv2 = Tkinter.Canvas(win)
hs2 = Tkinter.Scrollbar(win, orient='horizontal')
hs2.configure(command=cnv2.xview)
vs2 = Tkinter.Scrollbar(win, orient='vertical')
vs2.configure(command=cnv2.yview)
cnv2.grid(column=0, row=4, sticky='NWES')
vs2.grid(column=1, row=4, sticky='NSW')
hs2.grid(column=0, row=5, sticky='NWE')
cnv2.configure(yscrollcommand=vs2.set, xscrollcommand=hs2.set)
fr2 = Tkinter.Frame(cnv2)
cnv2.create_window((0,0), window=fr2, anchor='nw')
#column set to 5
fr2.columnconfigure(0, weight=1)
fr2.columnconfigure(1, weight=1)
fr2.columnconfigure(2, weight=1)
fr2.columnconfigure(3, weight=1)
fr2.columnconfigure(4, weight=1)
for i in range(len(self.group.optional)):
name, y_n = self.group.optional[i]
v = Tkinter.StringVar(value='no')
self.opt_vars.append(v)
chk = Tkinter.Checkbutton(fr2, text=name, onvalue='yes', offvalue='no', variable=self.opt_vars[i])
self.opt_chks.append(chk)
chk.grid(column=i%5, row=i/5, sticky='NWS')
if y_n == 'yes':
chk.select()
else:
chk.deselect()
if self.group.selection == 'all':
chk.configure(state='disable')
Tkinter.Button(win, text='OK', command=self.ok).grid(column=0, row=6, pady=2)
Tkinter.Button(win, text='Cancel', command=self.cancel).grid(column=1, row=6, pady=2)
# bind WM_DELETE_WINDOW
win.protocol("WM_DELETE_WINDOW", self.cancel)
win.after_idle(lambda : cnv1.configure(scrollregion=(0,0, fr1.winfo_width(), fr1.winfo_height())))
win.after_idle(lambda : cnv2.configure(scrollregion=(0,0, fr2.winfo_width(), fr2.winfo_height())))
win.transient(root_window)
# grab all events into it
while True:
try:
win.grab_set()
except Tkinter.TclError:
pass
else:
break
win.wait_window()