From fc6b2c8cd32cda17aeaeab94c242a2a5f5552f61 Mon Sep 17 00:00:00 2001 From: "M. Jirik" Date: Mon, 30 Mar 2015 13:42:23 +0200 Subject: [PATCH] config editor close #25 --- lisa/config.py | 13 ++--- lisa/configEditor.py | 117 +++++++++++++++++++++++++++++++++++++++++++ lisa/lisaWindow.py | 35 ++++++++++++- 3 files changed, 158 insertions(+), 7 deletions(-) create mode 100644 lisa/configEditor.py diff --git a/lisa/config.py b/lisa/config.py index c7150eb9..a14f569d 100644 --- a/lisa/config.py +++ b/lisa/config.py @@ -14,9 +14,9 @@ import os.path path_to_script = os.path.dirname(os.path.abspath(__file__)) -sys.path.append(os.path.join(path_to_script, "../extern/pyseg_base/src")) -sys.path.append(os.path.join(path_to_script, - "../extern/sed3/")) +# sys.path.append(os.path.join(path_to_script, "../extern/pyseg_base/src")) +# sys.path.append(os.path.join(path_to_script, +# "../extern/sed3/")) #sys.path.append(os.path.join(path_to_script, "../extern/")) #import featurevector @@ -26,7 +26,8 @@ import inspect -import misc +from io3d import misc +# import misc def get_config(filename, default_cfg): @@ -123,5 +124,5 @@ def subdict(bigdict, wanted_keys): return ret -def save_config(cfg, pointer): - pass +def save_config(cfg, filename): + misc.obj_to_file(cfg, filename, filetype='yaml') diff --git a/lisa/configEditor.py b/lisa/configEditor.py new file mode 100644 index 00000000..bfce6b3b --- /dev/null +++ b/lisa/configEditor.py @@ -0,0 +1,117 @@ +""" +DICTIONNARY INTERFACE FOR EDITING VALUES +creates labels/edits/menubutton widgets in a TkFrame to edit dictionary values +use: apply(frame,dict,position) +""" + +import Tkinter as tk + +def cbMenu(controlV,value,btn= None): + controlV.set(str(value)) + if not (btn== None): + btn.config(text= str(value)) + +def updateMB(ctrlV, value): + ctrlV.set(value) + +def doLambda(f,*args): + """Tips: Create lambda within for loop with fixed local variable + without interference across iterations""" + def g(): return f(*args) + return g + + +def apply(root,d,pos, use_list=True): + """Creates interface for dictionnary d in root at given grid position """ + "TODO: repercuter kwargs" + (x,y,w,h)= pos + lbs= [] + saisies= dict() + entries= dict() + for (n,(k,v)) in enumerate(d.iteritems()): + assert (k not in saisies) + l= tk.Label(root,text=str(k)) + l.grid(row=n+x,column=y) + if isinstance(v, list) and use_list: + """value= list => multiple choice => use menubutton""" + #saisies[k]= tk.StringVar(name=str(n),value= str(v[0])) + saisies[k]= tk.StringVar(value= str(v[0])) + ent=tk.Menubutton(root,textvariable=saisies[k],relief="sunken") + ent.m=tk.Menu(ent,tearoff=0) + ent.config(menu=ent.m) + for (kk,possible) in enumerate(v): + possibleSaved= "%s" %possible + ent.m.add_command(label=str(possible), command= doLambda(updateMB,saisies[k],str(d[k][kk]) ) ) + print possible + else: + """value is not a list => classical edit => use Entry""" + #saisies[k]= tk.StringVar(name=str(n),value= str(v)) + saisies[k]= tk.StringVar(value= str(v)) + ent= tk.Entry(textvariable=saisies[k])#,width=30) + ent.grid(row=n+x,column=y+1) + entries[k]= ent + return saisies + +def get(strVarDict): + d= {} + for (k,v) in strVarDict.iteritems(): + #try: v= float(v) + #except: pass + d[k]=v.get() + return d + + + +def main(): + "EXAMPLE" + root = tk.Tk() + #d= {'oui':1, 'non':'non'} + d= {'oui':1,'a':'b', 'non':['?','!non'],'mode':[1.1,2.1,3.1]} + + v= tk.StringVar(value= "Open File Dialog") + + m=tk.Menubutton(root,textvariable=v,relief="raised") + m.grid(row=2,column=1) + mm=tk.Menu(m,tearoff=0) + tk.Button(root, textvariable=v, command=lambda:v.set('oui')).grid(row=1,column=1) + mm.add_command(label="go", command=lambda: cbMenu(v,"non")) + m.config(menu=mm) + + s= apply(root,d,(0,2,0,0)) + print isinstance(d, dict) + root.mainloop() + #print d + print s + for (k,v) in s.iteritems(): + print str(k), '->',str(v.get()) + +def testindependance(): + root = tk.Tk() + d= {'oui':1,'a':'b', 'non':['?','!non'],'mode':[1.1,2.1,3.1]} + s= apply(root,d,(0,2,0,0)) + + dd= {'oui':1,'a':'b', 'non':['?','!non'],'mode':[1.1,2.1,3.1]} + ss= apply(root,dd,(0,5,0,0)) + + print "s =",s + print "ss=",ss + + print isinstance(d, dict) + root.mainloop() + #print d + #print s + for (k,v) in s.iteritems(): + print str(k), '->',str(v.get()) + print "-"*10 + for (k,v) in ss.iteritems(): + print str(k), '->',str(v.get()) + print "="*10 + print get(s) + print get(ss) + + +if __name__ == '__main__': + main() + #testindependance() + + diff --git a/lisa/lisaWindow.py b/lisa/lisaWindow.py index 05a1e19c..8c23407c 100644 --- a/lisa/lisaWindow.py +++ b/lisa/lisaWindow.py @@ -12,6 +12,7 @@ import numpy as np import datetime +import Tkinter as tk from io3d import datareader # import segmentation @@ -102,12 +103,17 @@ def initUI(self): grid.addWidget(lisa_title, 0, 1) grid.addWidget(info, 1, 1) grid.addWidget(lisa_logo, 0, 2, 2, 2) + + btn_config = QPushButton("Configuration", self) + btn_config.clicked.connect(self.btnConfig) + self.uiw['dcmdir'] = btn_config + grid.addWidget(btn_config, 2, 1) # rid.setColumnMinimumWidth(1, logo.width()/2) # rid.setColumnMinimumWidth(2, logo.width()/2) # rid.setColumnMinimumWidth(3, logo.width()/2) # # dicom reader - rstart = 2 + rstart = 3 hr = QFrame() hr.setFrameShape(QFrame.HLine) text_dcm = QLabel('DICOM reader') @@ -643,6 +649,33 @@ def saveOut(self, event=None, filename=None): else: self.statusBar().showMessage('No segmentation data!') + def btnConfig(self, event=None): + import lisa.configEditor as ce + import lisa.config + import lisa.organ_segmentation as los + d = los.lisa_config_init() + root = tk.Tk() + conf = ce.apply(root, d, (0, 2, 0, 0), use_list=False) + root.mainloop() + newconf = {} + for (k, v) in conf.iteritems(): + key = str(k) + value = str(v.get()) + try: + value = eval(value) + except: + pass + newconf[key] = value + + lisa.config.save_config( + newconf, + os.path.join(newconf['output_datapath'], 'organ_segmentation.config') + ) + self.quit(event) + # from PyQt4.QtCore import pyqtRemoveInputHook + # pyqtRemoveInputHook() + # import ipdb; ipdb.set_trace() # noqa BREAKPOINT + def btnSaveOutDcmOverlay(self, event=None, filename=None): if self.oseg.segmentation is not None: self.statusBar().showMessage('Saving segmentation data...')