comparison engine/extensions/pychan/widgets/widget.py @ 330:33dd55160a9d

* Added a new method Widget.getNamedChildren * Made the distribute and mapEvents methods (a whole lot) faster. * Added a new (internal) attribute to Widget (has_name) * Added a small decorator for profiling rarely called functions.
author phoku@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 24 Aug 2009 11:45:28 +0000
parents aca5744f017a
children 48c99636453e
comparison
equal deleted inserted replaced
329:aca5744f017a 330:33dd55160a9d
99 # Parent attribute makes sure we only have one parent, 99 # Parent attribute makes sure we only have one parent,
100 # that tests self.__parent - so make sure we have the attr here. 100 # that tests self.__parent - so make sure we have the attr here.
101 self.__parent = None 101 self.__parent = None
102 self.parent = parent 102 self.parent = parent
103 103
104 # This will also set the _event_id and call real_widget.setActionEventId 104 self.has_name = False
105 self.name = name 105 self.name = name
106 106
107 self.position = position 107 self.position = position
108 self.min_size = min_size 108 self.min_size = min_size
109 self.max_size = max_size 109 self.max_size = max_size
277 277
278 children = [] 278 children = []
279 def _childCollector(widget): 279 def _childCollector(widget):
280 if widget.match(**kwargs): 280 if widget.match(**kwargs):
281 children.append(widget) 281 children.append(widget)
282 self.deepApply(_childCollector)
283 return children
284
285 def getNamedChildren(self):
286 """
287 Create a dictionary of child widgets with the keys being
288 their name. This will contain only Widgets which have
289 a name different from "__unnamed__" (which is the default).
290
291 The values are lists of widgets, so not only unique names
292 are handled correctly.
293
294 Usage::
295 children = widget.getNamedChildren()
296 for widget in children.get("info",[])
297 print widget.name , " == info"
298 """
299 children = {}
300 def _childCollector(widget):
301 if widget.has_name:
302 children.setdefault(widget._name,[]).append(widget)
282 self.deepApply(_childCollector) 303 self.deepApply(_childCollector)
283 return children 304 return children
284 305
285 def findChild(self,**kwargs): 306 def findChild(self,**kwargs):
286 """ Find the first contained child widgets by attribute values. 307 """ Find the first contained child widgets by attribute values.
422 "button/mouseEntered" : toggleButtonColorGreen, 443 "button/mouseEntered" : toggleButtonColorGreen,
423 "button/mouseExited" : toggleButtonColorBlue, 444 "button/mouseExited" : toggleButtonColorBlue,
424 }) 445 })
425 446
426 """ 447 """
448 children = self.getNamedChildren()
427 for descr,func in eventMap.items(): 449 for descr,func in eventMap.items():
428 name, event_name, group_name = events.splitEventDescriptor(descr) 450 name, event_name, group_name = events.splitEventDescriptor(descr)
429 #print name, event_name, group_name 451 #print name, event_name, group_name
430 widget = self.findChild(name=name) 452 widgets = children.get(name,[])
431 if widget: 453 if widgets:
432 widget.capture( func, event_name = event_name, group_name = group_name ) 454 for widget in widgets:
455 widget.capture( func, event_name = event_name, group_name = group_name )
433 elif not ignoreMissing: 456 elif not ignoreMissing:
434 raise RuntimeError("No widget with the name: %s" % name) 457 raise RuntimeError("No widget with the name: %s" % name)
435 458
436 def setInitialData(self,data): 459 def setInitialData(self,data):
437 """ 460 """
474 'myTextField' : 'Hello World!', 497 'myTextField' : 'Hello World!',
475 'myListBox' : ["1","2","3"] 498 'myListBox' : ["1","2","3"]
476 }) 499 })
477 500
478 """ 501 """
502 children = self.getNamedChildren()
479 for name,data in initialDataMap.items(): 503 for name,data in initialDataMap.items():
480 widgetList = self.findChildren(name = name) 504 widgetList = children.get(name,[])
481 for widget in widgetList: 505 for widget in widgetList:
482 widget.setInitialData(data) 506 widget.setInitialData(data)
483 507
484 def distributeData(self,dataMap): 508 def distributeData(self,dataMap):
485 """ 509 """
492 'myTextField' : 'Hello World!', 516 'myTextField' : 'Hello World!',
493 'myListBox' : ["1","2","3"] 517 'myListBox' : ["1","2","3"]
494 }) 518 })
495 519
496 """ 520 """
521 children = self.getNamedChildren()
497 for name,data in dataMap.items(): 522 for name,data in dataMap.items():
498 widgetList = self.findChildren(name = name) 523 widgetList = children.get(name,[])
499 if len(widgetList) != 1: 524 if len(widgetList) != 1:
500 if get_manager().debug: 525 if get_manager().debug:
501 self.listNamedWidgets() 526 self.listNamedWidgets()
502 raise RuntimeError("DistributeData can only handle widgets with unique names.") 527 raise RuntimeError("DistributeData can only handle widgets with unique names.")
503 widgetList[0].setData(data) 528 widgetList[0].setData(data)
512 Usage:: 537 Usage::
513 data = guiElement.collectDataAsDict(['myTextField','myListBox']) 538 data = guiElement.collectDataAsDict(['myTextField','myListBox'])
514 print "You entered:",data['myTextField']," and selected ",data['myListBox'] 539 print "You entered:",data['myTextField']," and selected ",data['myListBox']
515 540
516 """ 541 """
542 children = self.getNamedChildren()
517 dataMap = {} 543 dataMap = {}
518 for name in widgetNames: 544 for name in widgetNames:
519 widgetList = self.findChildren(name = name) 545 widgetList = children.get(name,[])
520 if len(widgetList) != 1: 546 if len(widgetList) != 1:
521 if get_manager().debug: 547 if get_manager().debug:
522 self.listNamedWidgets() 548 self.listNamedWidgets()
523 raise RuntimeError("CollectData can only handle widgets with unique names.") 549 raise RuntimeError("CollectData can only handle widgets with unique names.")
524 550
544 print "You entered:",text," and selected item nr",selected 570 print "You entered:",text," and selected item nr",selected
545 # Single elements are handled gracefully, too: 571 # Single elements are handled gracefully, too:
546 test = guiElement.collectData('testElement') 572 test = guiElement.collectData('testElement')
547 573
548 """ 574 """
575 children = self.getNamedChildren()
549 dataList = [] 576 dataList = []
550 for name in widgetNames: 577 for name in widgetNames:
551 widgetList = self.findChildren(name = name) 578 widgetList = children.get(name,[])
552 if len(widgetList) != 1: 579 if len(widgetList) != 1:
553 if get_manager().debug: 580 if get_manager().debug:
554 self.listNamedWidgets() 581 self.listNamedWidgets()
555 raise RuntimeError("CollectData can only handle widgets with unique names.") 582 raise RuntimeError("CollectData can only handle widgets with unique names.")
556 dataList.append( widgetList[0].getData() ) 583 dataList.append( widgetList[0].getData() )
722 print "Widget containment fumble:", self, self.__parent, parent 749 print "Widget containment fumble:", self, self.__parent, parent
723 self.__parent.removeChild(self) 750 self.__parent.removeChild(self)
724 self.__parent = parent 751 self.__parent = parent
725 parent = property(_getParent,_setParent) 752 parent = property(_getParent,_setParent)
726 753
727 def _setName(self,name): self._name = name 754 def _setName(self,name):
755 self._name = name
756 if name != Widget.DEFAULT_NAME:
757 self.has_name = True
728 def _getName(self): 758 def _getName(self):
729 # __str__ relies on self.name 759 # __str__ relies on self.name
730 return getattr(self,'_name','__no_name_yet__') 760 return getattr(self,'_name','__no_name_yet__')
731 name = property(_getName,_setName) 761 name = property(_getName,_setName)
732 762