Package teamwork :: Package widgets :: Package PsychGUI :: Package AgentWindow :: Module ObservationPane
[hide private]
[frames] | no frames]

Source Code for Module teamwork.widgets.PsychGUI.AgentWindow.ObservationPane

  1  from Tkinter import * 
  2  import tkMessageBox 
  3  import Pmw 
  4  from teamwork.math.Keys import ObservationKey 
  5  from teamwork.math.ProbabilityTree import ProbabilityTree 
  6  from teamwork.widgets.images import loadImages 
  7  from teamwork.widgets.TreeBuilder import TreeBuilder 
  8  from teamwork.widgets.ActionDialog import ActionDialog 
  9   
10 -class ObservationFrame(Pmw.ScrolledFrame):
11 """Frame for specifying model of partial observability 12 @ivar images: table of images to use (need to keep this permanently stored) 13 @type images: dict 14 @cvar anyString: label used for a O function LHS that matches against any action 15 @type anyString: str 16 """ 17 anyString = 'any' 18
19 - def __init__(self,parent,entity,**kw):
20 self.images = loadImages({'del': 'icons/binocular--minus.png', 21 'add': 'icons/binocular--plus.png', 22 'new': 'icons/chart--plus.png'}) 23 optiondefs = ( 24 ('balloon',None,Pmw.INITOPT), 25 ('generic',False,Pmw.INITOPT), 26 ('expert', False,None), 27 ('society', {}, None), 28 ) 29 self.entity = entity 30 self.defineoptions(kw, optiondefs) 31 Pmw.ScrolledFrame.__init__(self,parent) 32 self.interior().grid_columnconfigure(0,weight=1) 33 if self['generic']: 34 toolbar = Frame(self.interior(),bd=2,relief='raised') 35 toolbar.grid(row=0,column=0,sticky='new') 36 # Dialog for getting new symbol name 37 self.createcomponent('dialog',(),None,Pmw.PromptDialog,(parent,), 38 title='New observation',entryfield_labelpos='w', 39 label_text='New observation:', 40 defaultbutton = 0,buttons = ('OK', 'Cancel'), 41 command = self.newOmega) 42 self.component('dialog').withdraw() 43 # Button for adding new observations 44 button = Label(toolbar) 45 button.bind('<ButtonRelease-1>',self.component('dialog').activate) 46 if self.images.has_key('add'): 47 button.configure(image=self.images['add'],bd=0) 48 else: 49 button.configure(text='Add') 50 button.pack(side='left',ipadx=5,ipady=3) 51 if self['balloon']: 52 self['balloon'].bind(button,'Add new observation symbol') 53 # Button for deleting observation symbols 54 button = Label(toolbar) 55 button.bind('<ButtonRelease-1>',self.delete) 56 if self.images.has_key('del'): 57 button.configure(image=self.images['del'],bd=0) 58 else: 59 button.configure(text='Delete') 60 button.pack(side='left',ipadx=5,ipady=3) 61 if self['balloon']: 62 self['balloon'].bind(button,'Delete selected observation symbol') 63 # Toggle for complete observability 64 self.perfect = IntVar() 65 button = self.createcomponent('observable',(),None,Checkbutton, 66 (self.interior(),),command=self.observable, 67 variable=self.perfect, 68 text='Perfect observations') 69 button.grid(row=1,column=0,sticky='nw',padx=20,pady=20) 70 # Space for partial observability 71 frame = self.createcomponent('details',(),None,Frame,(self.interior(),)) 72 # Buttons for existing observation symbols 73 widget = self.createcomponent('omega',(),None,Pmw.RadioSelect,(frame,), 74 labelpos='nw',label_text='Observations:', 75 buttontype='checkbutton',frame_bd=1, 76 frame_relief='ridge') 77 widget.pack(side='top',anchor='nw',fill='x',padx=20,pady=20) 78 # Area for defining observation function 79 table = {} 80 for entry in entity.observations: 81 table[str(entry['actions'])] = entry 82 widget = self.createcomponent('editor',(),None,TreeBuilder,(frame,), 83 orient='horizontal',default=True, 84 menus_leaves=self.entity.omega.keys(), 85 society=self['society'],expert=True, 86 new=self.newO,table=table) 87 widget.interior().grid_columnconfigure(1,weight=1) 88 widget.pack(side='top',anchor='nw',fill='both',padx=20,pady=20) 89 # Set up initial view depending on whether there are pre-defined 90 # observations or not 91 self.drawOmega() 92 if self.entity.observable(): 93 button.select() 94 else: 95 button.deselect() 96 self.observable() 97 if not self['generic']: 98 button.configure(state='disabled') 99 self.initialiseoptions(ObservationFrame)
100
101 - def observable(self):
102 """Callback for toggling complete observability 103 """ 104 if self.perfect.get(): 105 self.component('details').grid_forget() 106 else: 107 self.component('details').grid(row=2,column=0,sticky='enws')
108
109 - def newOmega(self,button):
110 """Callback for a new observation 111 """ 112 self.component('dialog').deactivate() 113 if button == 'OK': 114 omega = self.component('dialog_entryfield').getvalue().strip() 115 key = ObservationKey({'type': omega}) 116 if not self.entity.omega.has_key(key): 117 self.entity.omega[key] = True 118 self.drawOmega() 119 self.component('dialog_entryfield').clear()
120
121 - def drawOmega(self):
122 """Updates the display of the current set of possible observations 123 """ 124 Omega = map(str,self.entity.omega.keys()) 125 Omega.sort() 126 widget = self.component('omega') 127 widget.deleteall() 128 for omega in Omega: 129 if omega == str(None) or omega == str(True): 130 widget.add(omega,state='disabled') 131 else: 132 widget.add(omega)
133
134 - def validate(self,omega):
135 """Validates the uniqueness of the current symbol 136 """ 137 if self.entity.omega.has_key(ObservationKey({'type': omega})): 138 return Pmw.PARTIAL 139 elif omega == str(None) or omega == str(True): 140 # Avoid reserved observation keywords 141 return Pmw.PARTIAL 142 else: 143 return Pmw.OK
144
145 - def newO(self,key,option,tree):
146 """Callback for creating a new observation function entry 147 """ 148 self.entity.observations.append({'actions': option,'tree': tree})
149
150 - def delete(self,event=None):
151 """Deletes selected observation symbols 152 """ 153 selection = self.component('omega').getvalue() 154 if 'None' in selection: 155 tkMessageBox.showerror('Illegal removal','You cannot remove the null observation.') 156 elif 'True' in selection: 157 tkMessageBox.showerror('Illegal removal','You cannot remove the true observation.') 158 elif selection: 159 for omega in selection: 160 key = ObservationKey({'type': omega}) 161 del self.entity.omega[key] 162 self.drawOmega() 163 else: 164 tkMessageBox.showerror('No selection','You must first select at least one observation symbol to delete.')
165