complete most xml relax ng work.
work on real interface xml
work on python scripts for parsing interface xml
This commit is contained in:
lizhi-rocky
2010-07-08 11:52:50 +08:00
commit d1760bad48
11 changed files with 900 additions and 0 deletions

107
python/mine/install_xml.py Normal file
View File

@@ -0,0 +1,107 @@
#!/usr/bin/python
import sys
from xml.dom import minidom
import Tkinter
def attr_to_dict(attr):
''' convert (widget or grid_location) attributes into a dict '''
dict = {}
for a in attr.values():
if a.name == 'image':
dict[a.name] = Tkinter.PhotoImage(file=a.value)
elif a.name == 'command':
module = sys.modules[__name__]
dict[a.name] = getattr(module, a.value)
else:
dict[a.name] = a.value
return dict
def construct_widget_dict():
''' Go through all widget xml nodes on first level, I mean, those widgets defined
inside other widget will not be checked. If the widget has a name, it will
be recorded in the widget_dict.'''
widgets = [e for e in xmldoc.firstChild.childNodes
if e.nodeType == e.ELEMENT_NODE and e.nodeName == "widget"]
for w in widgets:
if "name" in w.attributes.keys():
widget_dict[w.attributes["name"].value] = w
def widget(w_xml, p_win):
''' create a widget.
w_xml is a xml node describing the widget.
p_win is the parent widget.'''
func = getattr(Tkinter, w_xml.attributes["type"].value)
# convert attributes into dictionary
wa_list = [wa for wa in w_xml.childNodes
if wa.nodeType == wa.ELEMENT_NODE and wa.nodeName =="widget_attribute"]
if wa_list:
# only process the first element, and there should be only one element.
attr_dict = attr_to_dict(wa_list[0].attributes)
w_win = func(p_win, attr_dict)
else:
w_win = func(p_win)
gm_list = [m for m in w_xml.childNodes
if m.nodeType == m.ELEMENT_NODE and m.nodeName == "grid_management"]
gl_list = [l for l in w_xml.childNodes
if l.nodeType == l.ELEMENT_NODE and l.nodeName == "grid_location"]
w_list = [ w for w in w_xml.childNodes
if w.nodeType == w.ELEMENT_NODE and w.nodeName == "widget" ]
for w in w_list:
widget(w, w_win)
for m in gm_list:
for cf in m.childNodes:
if cf.nodeType != m.ELEMENT_NODE or cf.nodeName != "configure":
continue
if "row" in cf.attributes.keys():
cf_func = getattr(w_win, "rowconfigure")
n = cf.attributes["row"].value
elif "column" in cf.attributes.keys():
cf_func = getattr(w_win, "columnconfigure")
n = cf.attributes["column"].value
else:
continue
cf_func(n, weight=cf.attributes["weight"].value)
# only process the first item
break
for l in gl_list:
ld = attr_to_dict(l.attributes)
w_win.grid(ld)
# only process the first item
break
def display():
''' Display a series of widgets '''
root_window = Tkinter.Tk()
# first display the main frame
widget(widget_dict["main"], root_window)
root_window.columnconfigure(0, weight=1)
root_window.rowconfigure(0, weight=1)
root_window.geometry('800x600+0+0')
root_window.mainloop()
# commands for buttons
def quit():
print "quit"
def previous_step():
print "previous step"
def next_step():
print "next step"
xmldoc = minidom.parse("../../xml/interface_t.xml")
widget_dict={}
construct_widget_dict()
sequence_dict={}
construct_sequence_dict()
display()

28
python/mine/ri_cmd.py Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/python
''' handle gui button related commands.'''
import ri_tk
import ri_seq
import ri_widget
def quit():
''' correspond to quit button '''
ri_tk.quit()
def previous():
''' correspond to previous button '''
if 'current_window' in dir(ri_tk):
ri_tk.kill_widget(ri_tk.current_window)
wid_name = ri_seq.previous()
if wid_name is not None:
ri_tk.display_widget(ri_widget.Widget.dict[wid_name])
def next():
''' correspond to next button '''
if 'current_window' in dir(ri_tk):
ri_tk.kill_widget(ri_tk.current_window)
wid_name = ri_seq.next()
if wid_name is not None:
ri_tk.display_widget(ri_widget.Widget.dict[wid_name])

44
python/mine/ri_seq.py Normal file
View File

@@ -0,0 +1,44 @@
#!/usr/bin/python
current_sequence=""
previous_sequences=[]
dict={}
class Sequence:
''' implement sequence in interface xml'''
def __init__(self, xml_node):
self.steps = [ s.attributes["name"].value for s in xml_node.childNodes
if s.nodeType == s.ELEMENT_NODE and s.nodeName == "widget" ]
self.current_step = 0
def construct(xml_root):
''' construct Sequence's static members'''
global current_sequence
current_sequence = xml_root.attributes["sequence"].value
for s in xml_root.childNodes:
if s.nodeType == s.ELEMENT_NODE and s.nodeName == "sequence":
dict[s.attributes["name"].value] = Sequence(s)
def previous():
global current_sequence
cur_seq = dict[current_sequence]
if cur_seq.current_step:
cur_seq.current_step -= 1
return cur_seq.steps[cur_seq.current_step]
# current sequence already in first step
elif previous_sequences:
current_sequence = previous_sequences.pop()
cur_seq = dict[current_sequence]
return cur_seq.steps[cur_seq.current_step]
def next():
global current_sequence
cur_seq = dict[current_sequence]
if cur_seq.current_step < len(cur_seq.steps)-1:
cur_seq.current_step += 1
return cur_seq.steps[cur_seq.current_step]
# current sequence already in last step
elif previous_sequences:
current_sequence = previous_sequences.pop()
cur_seq = dict[current_sequence]
return cur_seq.steps[cur_seq.current_step]

54
python/mine/ri_tk.py Normal file
View File

@@ -0,0 +1,54 @@
#!/usr/bin/python
''' handle display related work upon Tkinter '''
import Tkinter
def initialize(base_w):
''' base widget xml node '''
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 = display_widget_sub(base_w, root_window)
def quit():
''' exit root window '''
root_window.quit()
def display_widget(w):
''' w - widget instance '''
global current_window
current_window = display_widget_sub(w, base_widget)
def display_widget_sub(w, p_win):
'''
w - widget instance
p_win - Tk parent window '''
tk_func = getattr(Tkinter, w.tp)
w_win = tk_func(p_win, w.attr)
# display sub widgets
if 'widgets' in dir(w):
for sub_w in w.widgets:
display_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)
return w_win
def kill_widget(win):
''' win - Tk window instance '''
win.destroy()

78
python/mine/ri_widget.py Normal file
View File

@@ -0,0 +1,78 @@
#!/usr/bin/python
import Tkinter
import sys
class GridManagement:
''' implement grid management '''
def __init__(self, xml_node):
self.cf_list=[]
for cf in xml_node.childNodes:
if cf.nodeType != cf.ELEMENT_NODE or cf.nodeName != "configure":
continue
if "row" in cf.attributes.keys():
cf_func = "rowconfigure"
n = cf.attributes["row"].value
elif "column" in cf.attributes.keys():
cf_func = "columnconfigure"
n = cf.attributes["column"].value
else:
continue
self.cf_list.append((cf_func, n, cf.attributes["weight"].value))
class GridLocation:
''' implement grid_location in interface xml '''
def __init__(self, xml_node):
self.dict={}
for a in xml_node.attributes.values():
self.dict[a.name] = a.value
class Widget:
''' implement widget in interface xml '''
current_widget=""
dict={}
def __init__(self, xml_node):
self.tp = xml_node.attributes["type"].value
self.attr = self.widget_attribute(xml_node)
gm_list = [m for m in xml_node.childNodes
if m.nodeType == m.ELEMENT_NODE and m.nodeName == "grid_management"]
if gm_list:
self.grid_management = GridManagement(gm_list[0])
gl_list = [l for l in xml_node.childNodes
if l.nodeType == l.ELEMENT_NODE and l.nodeName == "grid_location"]
if gl_list:
self.grid_location = GridLocation(gl_list[0])
w_list = [ w for w in xml_node.childNodes
if w.nodeType == w.ELEMENT_NODE and w.nodeName == "widget" ]
if w_list:
self.widgets=[]
for w in w_list:
self.widgets.append(Widget(w))
def widget_attribute(self, xml_node):
attr_list = [ a for a in xml_node.childNodes
if a.nodeType == a.ELEMENT_NODE and a.nodeName == "widget_attribute"]
d = {}
if attr_list:
for a in attr_list[0].attributes.values():
if a.name == 'image':
#d[a.name] = Tkinter.PhotoImage(file=a.value)
pass
elif a.name == 'command':
if not "ri_cmd" in sys.modules.keys():
import ri_cmd
d[a.name] = getattr(sys.modules["ri_cmd"], a.value)
else:
d[a.name] = a.value
return d
def construct(xml_root):
''' construct Widget's static members'''
for w in xml_root.childNodes:
if w.nodeType == w.ELEMENT_NODE and w.nodeName == "widget" and "name" in w.attributes.keys():
Widget.dict[w.attributes["name"].value] = Widget(w)

23
python/mine/test.py Normal file
View File

@@ -0,0 +1,23 @@
#!/usr/bin/python
import ri_widget
import ri_tk
import ri_seq
from xml.dom import minidom
xmldoc = minidom.parse("../../xml/interface_t.xml")
ri_widget.construct(xmldoc.firstChild)
ri_seq.construct(xmldoc.firstChild)
base_widget_name = xmldoc.firstChild.attributes["base_widget"].value
base_widget = ri_widget.Widget.dict[base_widget_name]
ri_tk.initialize(base_widget)
main_sequence_name = xmldoc.firstChild.attributes["sequence"].value
main_sequence = ri_seq.dict[main_sequence_name]
ri_tk.display_widget(ri_widget.Widget.dict[main_sequence.steps[0]])
ri_tk.root_window.mainloop()