Revisão | d98687d2a0d8b814f09fd87f103188ec8d2faaeb (tree) |
---|---|
Hora | 2010-05-07 18:21:16 |
Autor | Hidehisa SHIOMI <pylaf@user...> |
Commiter | Hidehisa SHIOMI |
動的ポートリンカにて子コンポーネントのポートも選択できるようにした。
PortListbox.getports()メソッドをPortCollectorクラスに分割した。
@@ -5,3 +5,4 @@ | ||
5 | 5 | from widgets import * |
6 | 6 | from plotters import * |
7 | 7 | from easy import * |
8 | +from instant import * |
@@ -3,8 +3,9 @@ | ||
3 | 3 | from numpy import array |
4 | 4 | from framework import Component, Port, Frame, iscontain |
5 | 5 | from framework import DoubleVar, IntVar, StringVar, BooleanVar |
6 | -from widgets import GridPane, Menu, Entry, TriggerButton | |
6 | +from widgets import GridPane, Menu | |
7 | 7 | from inspect import getmembers, stack, getargvalues |
8 | +from instant import Linker, ClassListbox, findtoplevel | |
8 | 9 | import Tkinter |
9 | 10 | |
10 | 11 | class EasyComponent(Component): |
@@ -24,11 +25,15 @@ | ||
24 | 25 | setattr(frm,'console',o) |
25 | 26 | return frm |
26 | 27 | def menu(self,master,cnf={},**kw): |
27 | - if self._menu == None: | |
28 | - return None | |
29 | - else: | |
30 | - menu = EasyMenu(master,list=self._menu,cnf=cnf,**kw) | |
31 | - return menu | |
28 | + menu = [['PyLAF', ['Launch...',self.launch],['Link to...',self.link]]] | |
29 | + try: | |
30 | + for item in self._menu: menu.append(item) | |
31 | + except TypeError: pass | |
32 | + return EasyMenu(master,list=menu,cnf=cnf,**kw) | |
33 | + def link(self): | |
34 | + Linker(self) | |
35 | + def launch(self): | |
36 | + ClassListbox(Tkinter.Toplevel(findtoplevel(self))).pack() | |
32 | 37 | |
33 | 38 | class EasyPort(Port): |
34 | 39 | def _inckey(self,caller,key=None): |
@@ -70,9 +75,6 @@ | ||
70 | 75 | else: |
71 | 76 | tkvar = StringVar(self) |
72 | 77 | master.entry(self.label,tkvar) |
73 | - #row = master.grid_size()[1] | |
74 | - #Tkinter.Label(master,text=self.label).grid(row=row,column=0) | |
75 | - #Entry(master,textvariable=tkvar).grid(row=row,column=1) | |
76 | 78 | |
77 | 79 | class TrigPort(EasyPort): |
78 | 80 | def __init__(self,variable,label='',key=None): |
@@ -81,9 +83,6 @@ | ||
81 | 83 | self.label = label |
82 | 84 | def grid(self,master): |
83 | 85 | master.trig(self.label,BooleanVar(self)) |
84 | - #tkvar = BooleanVar(self) | |
85 | - #row = master.grid_size()[1] | |
86 | - #TriggerButton(master,text=self.label,variable=tkvar).grid(row=row,column=0,columnspan=2,sticky=Tkinter.W+Tkinter.E) | |
87 | 86 | |
88 | 87 | class EasyGrid(GridPane): |
89 | 88 | def __init__(self,master,component,cnf={},**kw): |
@@ -0,0 +1,159 @@ | ||
1 | +# coding: utf-8 | |
2 | +''' | |
3 | +インスタントPyLAFの試験実装 | |
4 | +''' | |
5 | +import Tkinter, inspect, os, imp | |
6 | +from framework import iscontain, popcnf, App, Component, Port | |
7 | +from plotters import BasePlot | |
8 | + | |
9 | +def findroot(widget): | |
10 | + try: | |
11 | + widget.master.master | |
12 | + except AttributeError: | |
13 | + return widget | |
14 | + return findroot(widget.master) | |
15 | + | |
16 | +def findtoplevel(widget): | |
17 | + cls = widget.master.__class__ | |
18 | + if not (cls == Tkinter.Toplevel or cls == Tkinter.Tk): | |
19 | + return findtoplevel(widget.master) | |
20 | + return widget.master | |
21 | + | |
22 | +class AvailableApps(dict): | |
23 | + def __init__(self,root): | |
24 | + dict.__init__(self) | |
25 | + self.check(root) | |
26 | + def check(self,widget): | |
27 | + for name in widget.children: self.check(widget.children[name]) | |
28 | + if iscontain(widget,App): | |
29 | + t, c = widget.master.title(), widget.component | |
30 | + self['%s:%s' % (t,c.__class__.__name__)] = c | |
31 | + | |
32 | +class AvailableComponent(dict): | |
33 | + def __init__(self,cwd): | |
34 | + dict.__init__(self) | |
35 | + # | |
36 | + pylaf = imp.load_module('PyLAF',*imp.find_module('PyLAF')) | |
37 | + mods = {} | |
38 | + for key,module in inspect.getmembers(pylaf,lambda x:inspect.ismodule(x)): mods[key] = module | |
39 | + plt = inspect.getmembers(mods['plotters'],lambda x:inspect.isclass(x) and inspect.getmro(x).__contains__(BasePlot)) | |
40 | + for key,cls in plt: self[key] = cls | |
41 | + # | |
42 | + for fname in os.listdir(cwd): | |
43 | + if fname.endswith('.py'): | |
44 | + mname = fname.replace('.py','') | |
45 | + try: | |
46 | + m = imp.load_module(mname,*imp.find_module(mname,[cwd])) | |
47 | + cs = inspect.getmembers(m,lambda x:inspect.isclass(x) and inspect.getmro(x).__contains__(Component)) | |
48 | + for key,cls in cs: self[key] = cls | |
49 | + except SyntaxError: pass | |
50 | + except ImportError: pass | |
51 | + except AttributeError: pass | |
52 | + for key in ['BasePlot','EasyComponent','Component']: | |
53 | + try: | |
54 | + del self[key] | |
55 | + except KeyError: pass | |
56 | + | |
57 | +class PortListbox(Tkinter.Listbox): | |
58 | + def __init__(self,master,**key): | |
59 | + frame = Tkinter.Frame(master) | |
60 | + self.apps = apps = popcnf('apps',key) | |
61 | + self.appvar = appvar = Tkinter.StringVar(); appvar.set(apps.keys()[0]); appvar.trace('w',self.set) | |
62 | + self.portvar = Tkinter.StringVar() | |
63 | + Tkinter.OptionMenu(frame,appvar,*apps.keys()).pack() | |
64 | + self.makeScrolledListbox(Tkinter.Frame(frame),**key); self.master.pack() | |
65 | + self.bind('<ButtonRelease-1>',self.buffer) | |
66 | + Tkinter.Entry(frame,textvariable=self.portvar).pack() | |
67 | + self.set() | |
68 | + for m in (Tkinter.Pack.__dict__.keys() + Tkinter.Grid.__dict__.keys() + Tkinter.Place.__dict__.keys()): | |
69 | + m[0] == '_' or m == 'config' or m == 'configure' or setattr(self, m, getattr(frame, m)) | |
70 | + def makeScrolledListbox(self,master,**key): | |
71 | + yscroll = Tkinter.Scrollbar(master,orient=Tkinter.VERTICAL) | |
72 | + yscroll.pack(side=Tkinter.RIGHT,fill=Tkinter.BOTH) | |
73 | + Tkinter.Listbox.__init__(self,master,yscrollcommand=yscroll.set,selectmode=Tkinter.SINGLE,**key) | |
74 | + self.pack(side=Tkinter.LEFT, fill=Tkinter.BOTH, expand=1) | |
75 | + yscroll.config(command=self.yview) | |
76 | + def buffer(self,*args): | |
77 | + selection = Tkinter.Listbox.get(self,0,Tkinter.END)[int(self.curselection()[0])] | |
78 | + self.portvar.set(selection) | |
79 | + def get(self): | |
80 | + return self.pdic[self.portvar.get()] | |
81 | + def set(self,*args): | |
82 | + #self.pdic = pdic = self.getports(self.apps[self.appvar.get()]) | |
83 | + self.pdic = pdic = PortCollector(self.apps[self.appvar.get()]) | |
84 | + self.delete(0,Tkinter.END) | |
85 | + self.insert(Tkinter.END,*[key for key in pdic]) | |
86 | + #def getports(self,component): | |
87 | + #res, m = {}, inspect.getmembers(component,lambda x:iscontain(x,Port)) | |
88 | + #for key,obj in m: res[key] = obj | |
89 | + #return res | |
90 | + def clear(self): | |
91 | + self.portvar.set('') | |
92 | + | |
93 | +class PortCollector(dict): | |
94 | + def __init__(self,component): | |
95 | + dict.__init__(self) | |
96 | + self.collect(component) | |
97 | + def collect(self,component,prefix='.'): | |
98 | + m = inspect.getmembers(component,lambda x:iscontain(x,Port)) | |
99 | + for key,obj in m: self[prefix+key] = obj | |
100 | + m = inspect.getmembers(component,lambda x:iscontain(x,Component)) | |
101 | + for key,obj in m: | |
102 | + if not key == 'master': self.collect(obj,prefix+'%s.' % key) | |
103 | + #print inspect.getmembers(obj,lambda x:iscontain(x,Component)) | |
104 | + | |
105 | +class ClassListbox(Tkinter.Listbox): | |
106 | + '''立ち上げ可能コンポーネントクラスの一覧、App(Equipment)でローンチ | |
107 | + ''' | |
108 | + def __init__(self,master,**key): | |
109 | + frame = Tkinter.Frame(master) | |
110 | + self.title = Tkinter.Entry(frame); self.title.pack() | |
111 | + self.cmps = AvailableComponent(os.getcwd()) | |
112 | + self.makeScrolledListbox(Tkinter.Frame(frame),**key); self.master.pack() | |
113 | + Tkinter.Button(frame,text='Launch',command=self.launch).pack() | |
114 | + self.insert(Tkinter.END,*[key for key in self.cmps]) | |
115 | + self.bind('<Double-1>',self.launch) | |
116 | + for m in (Tkinter.Pack.__dict__.keys() + Tkinter.Grid.__dict__.keys() + Tkinter.Place.__dict__.keys()): | |
117 | + m[0] == '_' or m == 'config' or m == 'configure' or setattr(self, m, getattr(frame, m)) | |
118 | + def makeScrolledListbox(self,master,**key): | |
119 | + yscroll = Tkinter.Scrollbar(master,orient=Tkinter.VERTICAL) | |
120 | + yscroll.pack(side=Tkinter.RIGHT,fill=Tkinter.BOTH) | |
121 | + Tkinter.Listbox.__init__(self,master,yscrollcommand=yscroll.set,selectmode=Tkinter.SINGLE,**key) | |
122 | + self.pack(side=Tkinter.LEFT, fill=Tkinter.BOTH, expand=1) | |
123 | + yscroll.config(command=self.yview) | |
124 | + def launch(self,*args): | |
125 | + try: | |
126 | + selection = self.get(0,Tkinter.END)[int(self.curselection()[0])] | |
127 | + except IndexError: return | |
128 | + o = App(Tkinter.Toplevel(findroot(self)),self.cmps[selection]) | |
129 | + title = self.title.get() | |
130 | + if title == '': title = self.cmps[selection].__name__ | |
131 | + o.master.title(title) | |
132 | + o.pack() | |
133 | + findtoplevel(self).destroy() | |
134 | + | |
135 | +class Linker(Tkinter.Toplevel): | |
136 | + '''起動したクラスのポートメンバの一覧、ローンチされているイクイップメントの一覧(コンボメニュー)、 | |
137 | + イクイップメントを選択するとそのポートメンバの一覧を表示 | |
138 | + ポートを選択してリンクボタンを押す | |
139 | + ''' | |
140 | + def __init__(self, master=None, cnf={}, **kw): | |
141 | + root = findroot(master) | |
142 | + Tkinter.Toplevel.__init__(self,findtoplevel(master),cnf,**kw) | |
143 | + apps = AvailableApps(root) | |
144 | + self.src = src = PortListbox(self,apps=apps); src.pack(side=Tkinter.LEFT) | |
145 | + title = apps.keys()[0] | |
146 | + for key,obj in apps.items(): | |
147 | + if master == obj: title = key | |
148 | + src.appvar.set(title) | |
149 | + Tkinter.Button(self,text='oo',command=self.link).pack(side=Tkinter.LEFT) | |
150 | + self.tgt = tgt = PortListbox(self,apps=apps); tgt.pack(side=Tkinter.LEFT) | |
151 | + def link(self): | |
152 | + try: | |
153 | + src = self.src.get() | |
154 | + tgt = self.tgt.get() | |
155 | + src.link(tgt) | |
156 | + except KeyError: pass | |
157 | + self.src.clear() | |
158 | + self.tgt.clear() | |
159 | + | |
\ No newline at end of file |
@@ -1,7 +1,7 @@ | ||
1 | 1 | # coding: utf-8 |
2 | 2 | |
3 | 3 | import StringIO, Image, ImageTk, matplotlib, tkFileDialog |
4 | -matplotlib.use('Agg') | |
4 | +matplotlib.use('Agg',warn=False) | |
5 | 5 | from matplotlib import pyplot |
6 | 6 | from scipy import array, arange, real, imag, sin, pi, fft, log10, fftpack |
7 | 7 | from Tkinter import Label, BOTTOM, Toplevel, mainloop, _cnfmerge |